diff options
Diffstat (limited to 'Python/pythonrun.c')
| -rw-r--r-- | Python/pythonrun.c | 1250 | 
1 files changed, 391 insertions, 859 deletions
| diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 8e97d7f..afb4c51 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -11,10 +11,13 @@  #include "parsetok.h"  #include "errcode.h"  #include "code.h" +#include "compile.h"  #include "symtable.h" +#include "pyarena.h"  #include "ast.h" +#include "eval.h"  #include "marshal.h" -#include "osdefs.h" +#include "abstract.h"  #ifdef HAVE_SIGNAL_H  #include <signal.h> @@ -32,7 +35,6 @@  #ifdef MS_WINDOWS  #undef BYTE  #include "windows.h" -#define PATH_MAX MAXPATHLEN  #endif  #ifndef Py_REF_DEBUG @@ -47,29 +49,24 @@  extern "C" {  #endif -extern wchar_t *Py_GetPath(void); +extern char *Py_GetPath(void);  extern grammar _PyParser_Grammar; /* From graminit.c */  /* Forward */  static void initmain(void); -static void initfsencoding(void);  static void initsite(void); -static int initstdio(void); -static void flush_io(void);  static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,                            PyCompilerFlags *, PyArena *);  static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,                                PyCompilerFlags *);  static void err_input(perrdetail *);  static void initsigs(void); -static void call_py_exitfuncs(void);  static void wait_for_thread_shutdown(void); +static void call_sys_exitfunc(void);  static void call_ll_exitfuncs(void);  extern void _PyUnicode_Init(void);  extern void _PyUnicode_Fini(void); -extern int _PyLong_Init(void); -extern void PyLong_Fini(void);  #ifdef WITH_THREAD  extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); @@ -78,17 +75,21 @@ extern void _PyGILState_Fini(void);  int Py_DebugFlag; /* Needed by parser.c */  int Py_VerboseFlag; /* Needed by import.c */ -int Py_QuietFlag; /* Needed by sysmodule.c */  int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */ -int Py_InspectFlag; /* Needed to determine whether to exit at SystemError */ +int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */  int Py_NoSiteFlag; /* Suppress 'import site' */  int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */  int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */  int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */  int Py_FrozenFlag; /* Needed by getpath.c */ +int Py_UnicodeFlag = 0; /* Needed by compile.c */  int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ +/* _XXX Py_QnewFlag should go away in 2.3.  It's true iff -Qnew is passed, +  on the command line, and is used in 2.2 by ceval.c to make all "/" divisions +  true divisions (which they will be in 2.3). */ +int _Py_QnewFlag = 0;  int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ -int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ +int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */  /* PyModule_GetWarningsModule is no longer necessary as of 2.6  since _warnings is builtin.  This API should not be used. */ @@ -131,71 +132,33 @@ add_flag(int flag, const char *envs)      return flag;  } -static char* -get_codec_name(const char *encoding) -{ -    char *name_utf8, *name_str; -    PyObject *codec, *name = NULL; - -    codec = _PyCodec_Lookup(encoding); -    if (!codec) -        goto error; - -    name = PyObject_GetAttrString(codec, "name"); -    Py_CLEAR(codec); -    if (!name) -        goto error; - -    name_utf8 = _PyUnicode_AsString(name); -    if (name == NULL) -        goto error; -    name_str = strdup(name_utf8); -    Py_DECREF(name); -    if (name_str == NULL) { -        PyErr_NoMemory(); -        return NULL; -    } -    return name_str; - -error: -    Py_XDECREF(codec); -    Py_XDECREF(name); -    return NULL; -} - -#if defined(HAVE_LANGINFO_H) && defined(CODESET) -static char* -get_codeset(void) -{ -    char* codeset = nl_langinfo(CODESET); -    if (!codeset || codeset[0] == '\0') { -        PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty"); -        return NULL; -    } -    return get_codec_name(codeset); -} -#endif -  void  Py_InitializeEx(int install_sigs)  {      PyInterpreterState *interp;      PyThreadState *tstate; -    PyObject *bimod, *sysmod, *pstderr; +    PyObject *bimod, *sysmod;      char *p; +    char *icodeset = NULL; /* On Windows, input codeset may theoretically +                              differ from output codeset. */ +    char *codeset = NULL; +    char *errors = NULL; +    int free_codeset = 0; +    int overridden = 0; +    PyObject *sys_stream, *sys_isatty; +#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) +    char *saved_locale, *loc_codeset; +#endif +#ifdef MS_WINDOWS +    char ibuf[128]; +    char buf[128]; +#endif      extern void _Py_ReadyTypes(void);      if (initialized)          return;      initialized = 1; -#if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) -    /* Set up the LC_CTYPE locale, so we can obtain -       the locale's charset without having to switch -       locales. */ -    setlocale(LC_CTYPE, ""); -#endif -      if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0')          Py_DebugFlag = add_flag(Py_DebugFlag, p);      if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') @@ -204,6 +167,12 @@ Py_InitializeEx(int install_sigs)          Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p);      if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0')          Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); +    /* The variable is only tested for existence here; _PyRandom_Init will +       check its value further. */ +    if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') +        Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p); + +    _PyRandom_Init();      interp = PyInterpreterState_New();      if (interp == NULL) @@ -214,23 +183,14 @@ Py_InitializeEx(int install_sigs)          Py_FatalError("Py_Initialize: can't make first thread");      (void) PyThreadState_Swap(tstate); -#ifdef WITH_THREAD -    /* We can't call _PyEval_FiniThreads() in Py_Finalize because -       destroying the GIL might fail when it is being referenced from -       another running thread (see issue #9901). -       Instead we destroy the previously created GIL here, which ensures -       that we can call Py_Initialize / Py_Finalize multiple times. */ -    _PyEval_FiniThreads(); - -    /* Auto-thread-state API */ -    _PyGILState_Init(interp, tstate); -#endif /* WITH_THREAD */ -      _Py_ReadyTypes();      if (!_PyFrame_Init())          Py_FatalError("Py_Initialize: can't init frames"); +    if (!_PyInt_Init()) +        Py_FatalError("Py_Initialize: can't init ints"); +      if (!_PyLong_Init())          Py_FatalError("Py_Initialize: can't init longs"); @@ -246,21 +206,19 @@ Py_InitializeEx(int install_sigs)      if (interp->modules_reloading == NULL)          Py_FatalError("Py_Initialize: can't make modules_reloading dictionary"); +#ifdef Py_USING_UNICODE      /* Init Unicode implementation; relies on the codec registry */      _PyUnicode_Init(); +#endif      bimod = _PyBuiltin_Init();      if (bimod == NULL) -        Py_FatalError("Py_Initialize: can't initialize builtins modules"); -    _PyImport_FixupBuiltin(bimod, "builtins"); +        Py_FatalError("Py_Initialize: can't initialize __builtin__");      interp->builtins = PyModule_GetDict(bimod);      if (interp->builtins == NULL)          Py_FatalError("Py_Initialize: can't initialize builtins dict");      Py_INCREF(interp->builtins); -    /* initialize builtin exceptions */ -    _PyExc_Init(); -      sysmod = _PySys_Init();      if (sysmod == NULL)          Py_FatalError("Py_Initialize: can't initialize sys"); @@ -268,51 +226,149 @@ Py_InitializeEx(int install_sigs)      if (interp->sysdict == NULL)          Py_FatalError("Py_Initialize: can't initialize sys dict");      Py_INCREF(interp->sysdict); -    _PyImport_FixupBuiltin(sysmod, "sys"); +    _PyImport_FixupExtension("sys", "sys");      PySys_SetPath(Py_GetPath());      PyDict_SetItemString(interp->sysdict, "modules",                           interp->modules); -    /* Set up a preliminary stderr printer until we have enough -       infrastructure for the io module in place. */ -    pstderr = PyFile_NewStdPrinter(fileno(stderr)); -    if (pstderr == NULL) -        Py_FatalError("Py_Initialize: can't set preliminary stderr"); -    PySys_SetObject("stderr", pstderr); -    PySys_SetObject("__stderr__", pstderr); -    Py_DECREF(pstderr); -      _PyImport_Init(); -    _PyImportHooks_Init(); - -    /* Initialize _warnings. */ -    _PyWarnings_Init(); +    /* initialize builtin exceptions */ +    _PyExc_Init(); +    _PyImport_FixupExtension("exceptions", "exceptions"); -    _PyTime_Init(); +    /* phase 2 of builtins */ +    _PyImport_FixupExtension("__builtin__", "__builtin__"); -    initfsencoding(); +    _PyImportHooks_Init();      if (install_sigs)          initsigs(); /* Signal handling stuff, including initintr() */ -    initmain(); /* Module __main__ */ -    if (initstdio() < 0) -        Py_FatalError( -            "Py_Initialize: can't initialize sys standard streams"); -      /* Initialize warnings. */ +    _PyWarnings_Init();      if (PySys_HasWarnOptions()) {          PyObject *warnings_module = PyImport_ImportModule("warnings"); -        if (warnings_module == NULL) { -            fprintf(stderr, "'import warnings' failed; traceback:\n"); -            PyErr_Print(); -        } +        if (!warnings_module) +            PyErr_Clear();          Py_XDECREF(warnings_module);      } +    initmain(); /* Module __main__ */ + +    /* auto-thread-state API, if available */ +#ifdef WITH_THREAD +    _PyGILState_Init(interp, tstate); +#endif /* WITH_THREAD */ +      if (!Py_NoSiteFlag)          initsite(); /* Module site */ + +    if ((p = Py_GETENV("PYTHONIOENCODING")) && *p != '\0') { +        p = icodeset = codeset = strdup(p); +        free_codeset = 1; +        errors = strchr(p, ':'); +        if (errors) { +            *errors = '\0'; +            errors++; +        } +        overridden = 1; +    } + +#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) +    /* On Unix, set the file system encoding according to the +       user's preference, if the CODESET names a well-known +       Python codec, and Py_FileSystemDefaultEncoding isn't +       initialized by other means. Also set the encoding of +       stdin and stdout if these are terminals, unless overridden.  */ + +    if (!overridden || !Py_FileSystemDefaultEncoding) { +        saved_locale = strdup(setlocale(LC_CTYPE, NULL)); +        setlocale(LC_CTYPE, ""); +        loc_codeset = nl_langinfo(CODESET); +        if (loc_codeset && *loc_codeset) { +            PyObject *enc = PyCodec_Encoder(loc_codeset); +            if (enc) { +                loc_codeset = strdup(loc_codeset); +                Py_DECREF(enc); +            } else { +                if (PyErr_ExceptionMatches(PyExc_LookupError)) { +                    PyErr_Clear(); +                    loc_codeset = NULL; +                } else { +                    PyErr_Print(); +                    exit(1); +                } +            } +        } else +            loc_codeset = NULL; +        setlocale(LC_CTYPE, saved_locale); +        free(saved_locale); + +        if (!overridden) { +            codeset = icodeset = loc_codeset; +            free_codeset = 1; +        } + +        /* Initialize Py_FileSystemDefaultEncoding from +           locale even if PYTHONIOENCODING is set. */ +        if (!Py_FileSystemDefaultEncoding) { +            Py_FileSystemDefaultEncoding = loc_codeset; +            if (!overridden) +                free_codeset = 0; +        } +    } +#endif + +#ifdef MS_WINDOWS +    if (!overridden) { +        icodeset = ibuf; +        codeset = buf; +        sprintf(ibuf, "cp%d", GetConsoleCP()); +        sprintf(buf, "cp%d", GetConsoleOutputCP()); +    } +#endif + +    if (codeset) { +        sys_stream = PySys_GetObject("stdin"); +        sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); +        if (!sys_isatty) +            PyErr_Clear(); +        if ((overridden || +             (sys_isatty && PyObject_IsTrue(sys_isatty))) && +           PyFile_Check(sys_stream)) { +            if (!PyFile_SetEncodingAndErrors(sys_stream, icodeset, errors)) +                Py_FatalError("Cannot set codeset of stdin"); +        } +        Py_XDECREF(sys_isatty); + +        sys_stream = PySys_GetObject("stdout"); +        sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); +        if (!sys_isatty) +            PyErr_Clear(); +        if ((overridden || +             (sys_isatty && PyObject_IsTrue(sys_isatty))) && +           PyFile_Check(sys_stream)) { +            if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors)) +                Py_FatalError("Cannot set codeset of stdout"); +        } +        Py_XDECREF(sys_isatty); + +        sys_stream = PySys_GetObject("stderr"); +        sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); +        if (!sys_isatty) +            PyErr_Clear(); +        if((overridden || +            (sys_isatty && PyObject_IsTrue(sys_isatty))) && +           PyFile_Check(sys_stream)) { +            if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors)) +                Py_FatalError("Cannot set codeset of stderr"); +        } +        Py_XDECREF(sys_isatty); + +        if (free_codeset) +            free(codeset); +    }  }  void @@ -326,32 +382,6 @@ Py_Initialize(void)  extern void dump_counts(FILE*);  #endif -/* Flush stdout and stderr */ - -static void -flush_std_files(void) -{ -    PyObject *fout = PySys_GetObject("stdout"); -    PyObject *ferr = PySys_GetObject("stderr"); -    PyObject *tmp; - -    if (fout != NULL && fout != Py_None) { -        tmp = PyObject_CallMethod(fout, "flush", ""); -        if (tmp == NULL) -            PyErr_WriteUnraisable(fout); -        else -            Py_DECREF(tmp); -    } - -    if (ferr != NULL && ferr != Py_None) { -        tmp = PyObject_CallMethod(ferr, "flush", ""); -        if (tmp == NULL) -            PyErr_Clear(); -        else -            Py_DECREF(tmp); -    } -} -  /* Undo the effect of Py_Initialize().     Beware: if multiple interpreter and/or thread states exist, these @@ -386,12 +416,9 @@ Py_Finalize(void)       * threads created thru it, so this also protects pending imports in       * the threads created via Threading.       */ -    call_py_exitfuncs(); +    call_sys_exitfunc();      initialized = 0; -    /* Flush stdout+stderr */ -    flush_std_files(); -      /* Get current thread state and interpreter pointer */      tstate = PyThreadState_GET();      interp = tstate->interp; @@ -422,16 +449,10 @@ Py_Finalize(void)      while (PyGC_Collect() > 0)          /* nothing */;  #endif -    /* We run this while most interpreter state is still alive, so that -       debug information can be printed out */ -    _PyGC_Fini();      /* Destroy all modules */      PyImport_Cleanup(); -    /* Flush stdout+stderr (again, in case more was printed) */ -    flush_std_files(); -      /* Collect final garbage.  This disposes of cycles created by       * new-style class definitions, for example.       * XXX This is disabled because it caused too many problems.  If @@ -498,20 +519,16 @@ Py_Finalize(void)      PyTuple_Fini();      PyList_Fini();      PySet_Fini(); -    PyBytes_Fini(); +    PyString_Fini();      PyByteArray_Fini(); -    PyLong_Fini(); +    PyInt_Fini();      PyFloat_Fini();      PyDict_Fini(); +#ifdef Py_USING_UNICODE      /* Cleanup Unicode implementation */      _PyUnicode_Fini(); - -    /* reset file system default encoding */ -    if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { -        free((char*)Py_FileSystemDefaultEncoding); -        Py_FileSystemDefaultEncoding = NULL; -    } +#endif      /* XXX Still allocated:         - various static ad-hoc pointers to interned strings @@ -577,20 +594,15 @@ Py_NewInterpreter(void)      interp->modules = PyDict_New();      interp->modules_reloading = PyDict_New(); -    bimod = _PyImport_FindBuiltin("builtins"); +    bimod = _PyImport_FindExtension("__builtin__", "__builtin__");      if (bimod != NULL) {          interp->builtins = PyModule_GetDict(bimod);          if (interp->builtins == NULL)              goto handle_error;          Py_INCREF(interp->builtins);      } - -    /* initialize builtin exceptions */ -    _PyExc_Init(); - -    sysmod = _PyImport_FindBuiltin("sys"); +    sysmod = _PyImport_FindExtension("sys", "sys");      if (bimod != NULL && sysmod != NULL) { -        PyObject *pstderr;          interp->sysdict = PyModule_GetDict(sysmod);          if (interp->sysdict == NULL)              goto handle_error; @@ -598,19 +610,7 @@ Py_NewInterpreter(void)          PySys_SetPath(Py_GetPath());          PyDict_SetItemString(interp->sysdict, "modules",                               interp->modules); -        /* Set up a preliminary stderr printer until we have enough -           infrastructure for the io module in place. */ -        pstderr = PyFile_NewStdPrinter(fileno(stderr)); -        if (pstderr == NULL) -            Py_FatalError("Py_Initialize: can't set preliminary stderr"); -        PySys_SetObject("stderr", pstderr); -        PySys_SetObject("__stderr__", pstderr); -        Py_DECREF(pstderr); -          _PyImportHooks_Init(); -        if (initstdio() < 0) -            Py_FatalError( -            "Py_Initialize: can't initialize sys standard streams");          initmain();          if (!Py_NoSiteFlag)              initsite(); @@ -661,43 +661,35 @@ Py_EndInterpreter(PyThreadState *tstate)      PyInterpreterState_Delete(interp);  } -static wchar_t *progname = L"python"; +static char *progname = "python";  void -Py_SetProgramName(wchar_t *pn) +Py_SetProgramName(char *pn)  {      if (pn && *pn)          progname = pn;  } -wchar_t * +char *  Py_GetProgramName(void)  {      return progname;  } -static wchar_t *default_home = NULL; -static wchar_t env_home[PATH_MAX+1]; +static char *default_home = NULL;  void -Py_SetPythonHome(wchar_t *home) +Py_SetPythonHome(char *home)  {      default_home = home;  } -wchar_t * +char *  Py_GetPythonHome(void)  { -    wchar_t *home = default_home; -    if (home == NULL && !Py_IgnoreEnvironmentFlag) { -        char* chome = Py_GETENV("PYTHONHOME"); -        if (chome) { -            size_t r = mbstowcs(env_home, chome, PATH_MAX+1); -            if (r != (size_t)-1 && r <= PATH_MAX) -                home = env_home; -        } - -    } +    char *home = default_home; +    if (home == NULL && !Py_IgnoreEnvironmentFlag) +        home = Py_GETENV("PYTHONHOME");      return home;  } @@ -712,45 +704,11 @@ initmain(void)          Py_FatalError("can't create __main__ module");      d = PyModule_GetDict(m);      if (PyDict_GetItemString(d, "__builtins__") == NULL) { -        PyObject *bimod = PyImport_ImportModule("builtins"); +        PyObject *bimod = PyImport_ImportModule("__builtin__");          if (bimod == NULL ||              PyDict_SetItemString(d, "__builtins__", bimod) != 0)              Py_FatalError("can't add __builtins__ to __main__"); -        Py_DECREF(bimod); -    } -} - -static void -initfsencoding(void) -{ -    PyObject *codec; -#if defined(HAVE_LANGINFO_H) && defined(CODESET) -    char *codeset = NULL; - -    if (Py_FileSystemDefaultEncoding == NULL) { -        /* On Unix, set the file system encoding according to the -           user's preference, if the CODESET names a well-known -           Python codec, and Py_FileSystemDefaultEncoding isn't -           initialized by other means. */ -        codeset = get_codeset(); -        if (codeset == NULL) -            Py_FatalError("Py_Initialize: Unable to get the locale encoding"); - -        Py_FileSystemDefaultEncoding = codeset; -        Py_HasFileSystemDefaultEncoding = 0; -        return; -    } -#endif - -    /* the encoding is mbcs, utf-8 or ascii */ -    codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); -    if (!codec) { -        /* Such error can only occurs in critical situations: no more -         * memory, import a module of the standard library failed, -         * etc. */ -        Py_FatalError("Py_Initialize: unable to load the file system codec"); -    } else { -        Py_DECREF(codec); +        Py_XDECREF(bimod);      }  } @@ -771,239 +729,6 @@ initsite(void)      }  } -static PyObject* -create_stdio(PyObject* io, -    int fd, int write_mode, char* name, -    char* encoding, char* errors) -{ -    PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; -    const char* mode; -    const char* newline; -    PyObject *line_buffering; -    int buffering, isatty; - -    /* stdin is always opened in buffered mode, first because it shouldn't -       make a difference in common use cases, second because TextIOWrapper -       depends on the presence of a read1() method which only exists on -       buffered streams. -    */ -    if (Py_UnbufferedStdioFlag && write_mode) -        buffering = 0; -    else -        buffering = -1; -    if (write_mode) -        mode = "wb"; -    else -        mode = "rb"; -    buf = PyObject_CallMethod(io, "open", "isiOOOi", -                              fd, mode, buffering, -                              Py_None, Py_None, Py_None, 0); -    if (buf == NULL) -        goto error; - -    if (buffering) { -        raw = PyObject_GetAttrString(buf, "raw"); -        if (raw == NULL) -            goto error; -    } -    else { -        raw = buf; -        Py_INCREF(raw); -    } - -    text = PyUnicode_FromString(name); -    if (text == NULL || PyObject_SetAttrString(raw, "name", text) < 0) -        goto error; -    res = PyObject_CallMethod(raw, "isatty", ""); -    if (res == NULL) -        goto error; -    isatty = PyObject_IsTrue(res); -    Py_DECREF(res); -    if (isatty == -1) -        goto error; -    if (isatty || Py_UnbufferedStdioFlag) -        line_buffering = Py_True; -    else -        line_buffering = Py_False; - -    Py_CLEAR(raw); -    Py_CLEAR(text); - -    newline = "\n"; -#ifdef MS_WINDOWS -    if (!write_mode) { -        /* translate \r\n to \n for sys.stdin on Windows */ -        newline = NULL; -    } -#endif - -    stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO", -                                 buf, encoding, errors, -                                 newline, line_buffering); -    Py_CLEAR(buf); -    if (stream == NULL) -        goto error; - -    if (write_mode) -        mode = "w"; -    else -        mode = "r"; -    text = PyUnicode_FromString(mode); -    if (!text || PyObject_SetAttrString(stream, "mode", text) < 0) -        goto error; -    Py_CLEAR(text); -    return stream; - -error: -    Py_XDECREF(buf); -    Py_XDECREF(stream); -    Py_XDECREF(text); -    Py_XDECREF(raw); -    return NULL; -} - -/* Initialize sys.stdin, stdout, stderr and builtins.open */ -static int -initstdio(void) -{ -    PyObject *iomod = NULL, *wrapper; -    PyObject *bimod = NULL; -    PyObject *m; -    PyObject *std = NULL; -    int status = 0, fd; -    PyObject * encoding_attr; -    char *encoding = NULL, *errors; - -    /* Hack to avoid a nasty recursion issue when Python is invoked -       in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ -    if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { -        goto error; -    } -    Py_DECREF(m); - -    if (!(m = PyImport_ImportModule("encodings.latin_1"))) { -        goto error; -    } -    Py_DECREF(m); - -    if (!(bimod = PyImport_ImportModule("builtins"))) { -        goto error; -    } - -    if (!(iomod = PyImport_ImportModule("io"))) { -        goto error; -    } -    if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { -        goto error; -    } - -    /* Set builtins.open */ -    if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { -        Py_DECREF(wrapper); -        goto error; -    } -    Py_DECREF(wrapper); - -    encoding = Py_GETENV("PYTHONIOENCODING"); -    errors = NULL; -    if (encoding) { -        encoding = strdup(encoding); -        errors = strchr(encoding, ':'); -        if (errors) { -            *errors = '\0'; -            errors++; -        } -    } - -    /* Set sys.stdin */ -    fd = fileno(stdin); -    /* Under some conditions stdin, stdout and stderr may not be connected -     * and fileno() may point to an invalid file descriptor. For example -     * GUI apps don't have valid standard streams by default. -     */ -    if (fd < 0) { -#ifdef MS_WINDOWS -        std = Py_None; -        Py_INCREF(std); -#else -        goto error; -#endif -    } -    else { -        std = create_stdio(iomod, fd, 0, "<stdin>", encoding, errors); -        if (std == NULL) -            goto error; -    } /* if (fd < 0) */ -    PySys_SetObject("__stdin__", std); -    PySys_SetObject("stdin", std); -    Py_DECREF(std); - -    /* Set sys.stdout */ -    fd = fileno(stdout); -    if (fd < 0) { -#ifdef MS_WINDOWS -        std = Py_None; -        Py_INCREF(std); -#else -        goto error; -#endif -    } -    else { -        std = create_stdio(iomod, fd, 1, "<stdout>", encoding, errors); -        if (std == NULL) -            goto error; -    } /* if (fd < 0) */ -    PySys_SetObject("__stdout__", std); -    PySys_SetObject("stdout", std); -    Py_DECREF(std); - -#if 1 /* Disable this if you have trouble debugging bootstrap stuff */ -    /* Set sys.stderr, replaces the preliminary stderr */ -    fd = fileno(stderr); -    if (fd < 0) { -#ifdef MS_WINDOWS -        std = Py_None; -        Py_INCREF(std); -#else -        goto error; -#endif -    } -    else { -        std = create_stdio(iomod, fd, 1, "<stderr>", encoding, "backslashreplace"); -        if (std == NULL) -            goto error; -    } /* if (fd < 0) */ - -    /* Same as hack above, pre-import stderr's codec to avoid recursion -       when import.c tries to write to stderr in verbose mode. */ -    encoding_attr = PyObject_GetAttrString(std, "encoding"); -    if (encoding_attr != NULL) { -        const char * encoding; -        encoding = _PyUnicode_AsString(encoding_attr); -        if (encoding != NULL) { -            _PyCodec_Lookup(encoding); -        } -        Py_DECREF(encoding_attr); -    } -    PyErr_Clear();  /* Not a fatal error if codec isn't available */ - -    PySys_SetObject("__stderr__", std); -    PySys_SetObject("stderr", std); -    Py_DECREF(std); -#endif - -    if (0) { -  error: -        status = -1; -    } - -    if (encoding) -        free(encoding); -    Py_XDECREF(bimod); -    Py_XDECREF(iomod); -    return status; -} -  /* Parse input from a file and execute it */  int @@ -1035,12 +760,12 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag      }      v = PySys_GetObject("ps1");      if (v == NULL) { -        PySys_SetObject("ps1", v = PyUnicode_FromString(">>> ")); +        PySys_SetObject("ps1", v = PyString_FromString(">>> "));          Py_XDECREF(v);      }      v = PySys_GetObject("ps2");      if (v == NULL) { -        PySys_SetObject("ps2", v = PyUnicode_FromString("... ")); +        PySys_SetObject("ps2", v = PyString_FromString("... "));          Py_XDECREF(v);      }      for (;;) { @@ -1055,90 +780,60 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag      }  } -/* compute parser flags based on compiler flags */ -static int PARSER_FLAGS(PyCompilerFlags *flags) -{ -    int parser_flags = 0; -    if (!flags) -        return 0; -    if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT) -        parser_flags |= PyPARSE_DONT_IMPLY_DEDENT; -    if (flags->cf_flags & PyCF_IGNORE_COOKIE) -        parser_flags |= PyPARSE_IGNORE_COOKIE; -    if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL) -        parser_flags |= PyPARSE_BARRY_AS_BDFL; -    return parser_flags; -} -  #if 0 +/* compute parser flags based on compiler flags */ +#define PARSER_FLAGS(flags) \ +    ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \ +                  PyPARSE_DONT_IMPLY_DEDENT : 0)) : 0) +#endif +#if 1  /* Keep an example of flags with future keyword support. */  #define PARSER_FLAGS(flags) \      ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \                    PyPARSE_DONT_IMPLY_DEDENT : 0) \ -                | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \ -                   PyPARSE_WITH_IS_KEYWORD : 0)) : 0) +                | (((flags)->cf_flags & CO_FUTURE_PRINT_FUNCTION) ? \ +                   PyPARSE_PRINT_IS_FUNCTION : 0) \ +                | (((flags)->cf_flags & CO_FUTURE_UNICODE_LITERALS) ? \ +                   PyPARSE_UNICODE_LITERALS : 0) \ +                ) : 0)  #endif  int  PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)  { -    PyObject *m, *d, *v, *w, *oenc = NULL; +    PyObject *m, *d, *v, *w;      mod_ty mod;      PyArena *arena; -    char *ps1 = "", *ps2 = "", *enc = NULL; +    char *ps1 = "", *ps2 = "";      int errcode = 0; -    if (fp == stdin) { -        /* Fetch encoding from sys.stdin */ -        v = PySys_GetObject("stdin"); -        if (v == NULL || v == Py_None) -            return -1; -        oenc = PyObject_GetAttrString(v, "encoding"); -        if (!oenc) -            return -1; -        enc = _PyUnicode_AsString(oenc); -        if (enc == NULL) -            return -1; -    }      v = PySys_GetObject("ps1");      if (v != NULL) {          v = PyObject_Str(v);          if (v == NULL)              PyErr_Clear(); -        else if (PyUnicode_Check(v)) { -            ps1 = _PyUnicode_AsString(v); -            if (ps1 == NULL) { -                PyErr_Clear(); -                ps1 = ""; -            } -        } +        else if (PyString_Check(v)) +            ps1 = PyString_AsString(v);      }      w = PySys_GetObject("ps2");      if (w != NULL) {          w = PyObject_Str(w);          if (w == NULL)              PyErr_Clear(); -        else if (PyUnicode_Check(w)) { -            ps2 = _PyUnicode_AsString(w); -            if (ps2 == NULL) { -                PyErr_Clear(); -                ps2 = ""; -            } -        } +        else if (PyString_Check(w)) +            ps2 = PyString_AsString(w);      }      arena = PyArena_New();      if (arena == NULL) {          Py_XDECREF(v);          Py_XDECREF(w); -        Py_XDECREF(oenc);          return -1;      } -    mod = PyParser_ASTFromFile(fp, filename, enc, +    mod = PyParser_ASTFromFile(fp, filename,                                 Py_single_input, ps1, ps2,                                 flags, &errcode, arena);      Py_XDECREF(v);      Py_XDECREF(w); -    Py_XDECREF(oenc);      if (mod == NULL) {          PyArena_Free(arena);          if (errcode == E_EOF) { @@ -1156,12 +851,13 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags      d = PyModule_GetDict(m);      v = run_mod(mod, filename, d, d, flags, arena);      PyArena_Free(arena); -    flush_io();      if (v == NULL) {          PyErr_Print();          return -1;      }      Py_DECREF(v); +    if (Py_FlushLine()) +        PyErr_Clear();      return 0;  } @@ -1211,24 +907,20 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,  {      PyObject *m, *d, *v;      const char *ext; -    int set_file_name = 0, ret; -    size_t len; +    int set_file_name = 0, ret, len;      m = PyImport_AddModule("__main__");      if (m == NULL)          return -1;      d = PyModule_GetDict(m);      if (PyDict_GetItemString(d, "__file__") == NULL) { -        PyObject *f; -        f = PyUnicode_DecodeFSDefault(filename); +        PyObject *f = PyString_FromString(filename);          if (f == NULL)              return -1;          if (PyDict_SetItemString(d, "__file__", f) < 0) {              Py_DECREF(f);              return -1;          } -        if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) -            return -1;          set_file_name = 1;          Py_DECREF(f);      } @@ -1251,13 +943,14 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,          v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d,                                closeit, flags);      } -    flush_io();      if (v == NULL) {          PyErr_Print();          ret = -1;          goto done;      }      Py_DECREF(v); +    if (Py_FlushLine()) +        PyErr_Clear();      ret = 0;    done:      if (set_file_name && PyDict_DelItemString(d, "__file__")) @@ -1279,6 +972,8 @@ PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)          return -1;      }      Py_DECREF(v); +    if (Py_FlushLine()) +        PyErr_Clear();      return 0;  } @@ -1294,56 +989,67 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,          return PyArg_ParseTuple(err, "O(ziiz)", message, filename,                                  lineno, offset, text); -    /* new style errors.  `err' is an instance */ +    *message = NULL; -    if (! (v = PyObject_GetAttrString(err, "msg"))) +    /* new style errors.  `err' is an instance */ +    *message = PyObject_GetAttrString(err, "msg"); +    if (!*message)          goto finally; -    *message = v; -    if (!(v = PyObject_GetAttrString(err, "filename"))) +    v = PyObject_GetAttrString(err, "filename"); +    if (!v)          goto finally; -    if (v == Py_None) +    if (v == Py_None) { +        Py_DECREF(v);          *filename = NULL; -    else if (! (*filename = _PyUnicode_AsString(v))) -        goto finally; +    } +    else { +        *filename = PyString_AsString(v); +        Py_DECREF(v); +        if (!*filename) +            goto finally; +    } -    Py_DECREF(v); -    if (!(v = PyObject_GetAttrString(err, "lineno"))) +    v = PyObject_GetAttrString(err, "lineno"); +    if (!v)          goto finally; -    hold = PyLong_AsLong(v); +    hold = PyInt_AsLong(v);      Py_DECREF(v); -    v = NULL;      if (hold < 0 && PyErr_Occurred())          goto finally;      *lineno = (int)hold; -    if (!(v = PyObject_GetAttrString(err, "offset"))) +    v = PyObject_GetAttrString(err, "offset"); +    if (!v)          goto finally;      if (v == Py_None) {          *offset = -1;          Py_DECREF(v); -        v = NULL;      } else { -        hold = PyLong_AsLong(v); +        hold = PyInt_AsLong(v);          Py_DECREF(v); -        v = NULL;          if (hold < 0 && PyErr_Occurred())              goto finally;          *offset = (int)hold;      } -    if (!(v = PyObject_GetAttrString(err, "text"))) +    v = PyObject_GetAttrString(err, "text"); +    if (!v)          goto finally; -    if (v == Py_None) +    if (v == Py_None) { +        Py_DECREF(v);          *text = NULL; -    else if (!PyUnicode_Check(v) || -             !(*text = _PyUnicode_AsString(v))) -        goto finally; -    Py_DECREF(v); +    } +    else { +        *text = PyString_AsString(v); +        Py_DECREF(v); +        if (!*text) +            goto finally; +    }      return 1;  finally: -    Py_XDECREF(v); +    Py_XDECREF(*message);      return 0;  } @@ -1379,8 +1085,11 @@ print_error_text(PyObject *f, int offset, const char *text)      if (offset == -1)          return;      PyFile_WriteString("    ", f); -    while (--offset > 0) +    offset--; +    while (offset > 0) {          PyFile_WriteString(" ", f); +        offset--; +    }      PyFile_WriteString("^\n", f);  } @@ -1396,6 +1105,8 @@ handle_system_exit(void)          return;      PyErr_Fetch(&exception, &value, &tb); +    if (Py_FlushLine()) +        PyErr_Clear();      fflush(stdout);      if (value == NULL || value == Py_None)          goto done; @@ -1411,8 +1122,8 @@ handle_system_exit(void)          /* If we failed to dig out the 'code' attribute,             just let the else clause below print the error. */      } -    if (PyLong_Check(value)) -        exitcode = (int)PyLong_AsLong(value); +    if (PyInt_Check(value)) +        exitcode = (int)PyInt_AsLong(value);      else {          PyObject *sys_stderr = PySys_GetObject("stderr");          if (sys_stderr != NULL && sys_stderr != Py_None) { @@ -1448,11 +1159,6 @@ PyErr_PrintEx(int set_sys_last_vars)      if (exception == NULL)          return;      PyErr_NormalizeException(&exception, &v, &tb); -    if (tb == NULL) { -        tb = Py_None; -        Py_INCREF(tb); -    } -    PyException_SetTraceback(v, tb);      if (exception == NULL)          return;      /* Now we know v != NULL too */ @@ -1462,8 +1168,9 @@ PyErr_PrintEx(int set_sys_last_vars)          PySys_SetObject("last_traceback", tb);      }      hook = PySys_GetObject("excepthook"); -    if (hook) { -        PyObject *args = PyTuple_Pack(3, exception, v, tb); +    if (hook && hook != Py_None) { +        PyObject *args = PyTuple_Pack(3, +            exception, v, tb ? tb : Py_None);          PyObject *result = PyEval_CallObject(hook, args);          if (result == NULL) {              PyObject *exception2, *v2, *tb2; @@ -1483,6 +1190,8 @@ PyErr_PrintEx(int set_sys_last_vars)                  v2 = Py_None;                  Py_INCREF(v2);              } +            if (Py_FlushLine()) +                PyErr_Clear();              fflush(stdout);              PySys_WriteStderr("Error in sys.excepthook:\n");              PyErr_Display(exception2, v2, tb2); @@ -1503,108 +1212,100 @@ PyErr_PrintEx(int set_sys_last_vars)      Py_XDECREF(tb);  } -static void -print_exception(PyObject *f, PyObject *value) +void +PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)  {      int err = 0; -    PyObject *type, *tb; - -    if (!PyExceptionInstance_Check(value)) { -        PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); -        PyFile_WriteString(Py_TYPE(value)->tp_name, f); -        PyFile_WriteString(" found\n", f); -        return; -    } - +    PyObject *f = PySys_GetObject("stderr");      Py_INCREF(value); -    fflush(stdout); -    type = (PyObject *) Py_TYPE(value); -    tb = PyException_GetTraceback(value); -    if (tb && tb != Py_None) -        err = PyTraceBack_Print(tb, f); -    if (err == 0 && -        PyObject_HasAttrString(value, "print_file_and_line")) -    { -        PyObject *message; -        const char *filename, *text; -        int lineno, offset; -        if (!parse_syntax_error(value, &message, &filename, -                                &lineno, &offset, &text)) +    if (f == NULL || f == Py_None) +        fprintf(stderr, "lost sys.stderr\n"); +    else { +        if (Py_FlushLine())              PyErr_Clear(); -        else { -            char buf[10]; -            PyFile_WriteString("  File \"", f); -            if (filename == NULL) -                PyFile_WriteString("<string>", f); -            else -                PyFile_WriteString(filename, f); -            PyFile_WriteString("\", line ", f); -            PyOS_snprintf(buf, sizeof(buf), "%d", lineno); -            PyFile_WriteString(buf, f); -            PyFile_WriteString("\n", f); -            if (text != NULL) -                print_error_text(f, offset, text); -            Py_DECREF(value); -            value = message; -            /* Can't be bothered to check all those -               PyFile_WriteString() calls */ -            if (PyErr_Occurred()) -                err = -1; +        fflush(stdout); +        if (tb && tb != Py_None) +            err = PyTraceBack_Print(tb, f); +        if (err == 0 && +            PyObject_HasAttrString(value, "print_file_and_line")) +        { +            PyObject *message; +            const char *filename, *text; +            int lineno, offset; +            if (!parse_syntax_error(value, &message, &filename, +                                    &lineno, &offset, &text)) +                PyErr_Clear(); +            else { +                char buf[10]; +                PyFile_WriteString("  File \"", f); +                if (filename == NULL) +                    PyFile_WriteString("<string>", f); +                else +                    PyFile_WriteString(filename, f); +                PyFile_WriteString("\", line ", f); +                PyOS_snprintf(buf, sizeof(buf), "%d", lineno); +                PyFile_WriteString(buf, f); +                PyFile_WriteString("\n", f); +                if (text != NULL) +                    print_error_text(f, offset, text); +                Py_DECREF(value); +                value = message; +                /* Can't be bothered to check all those +                   PyFile_WriteString() calls */ +                if (PyErr_Occurred()) +                    err = -1; +            }          } -    } -    if (err) { -        /* Don't do anything else */ -    } -    else { -        PyObject* moduleName; -        char* className; -        assert(PyExceptionClass_Check(type)); -        className = PyExceptionClass_Name(type); -        if (className != NULL) { -            char *dot = strrchr(className, '.'); -            if (dot != NULL) -                className = dot+1; +        if (err) { +            /* Don't do anything else */          } +        else if (PyExceptionClass_Check(exception)) { +            PyObject* moduleName; +            char* className = PyExceptionClass_Name(exception); +            if (className != NULL) { +                char *dot = strrchr(className, '.'); +                if (dot != NULL) +                    className = dot+1; +            } -        moduleName = PyObject_GetAttrString(type, "__module__"); -        if (moduleName == NULL || !PyUnicode_Check(moduleName)) -        { -            Py_DECREF(moduleName); -            err = PyFile_WriteString("<unknown>", f); -        } -        else { -            char* modstr = _PyUnicode_AsString(moduleName); -            if (modstr && strcmp(modstr, "builtins")) -            { -                err = PyFile_WriteString(modstr, f); -                err += PyFile_WriteString(".", f); +            moduleName = PyObject_GetAttrString(exception, "__module__"); +            if (moduleName == NULL) +                err = PyFile_WriteString("<unknown>", f); +            else { +                char* modstr = PyString_AsString(moduleName); +                if (modstr && strcmp(modstr, "exceptions")) +                { +                    err = PyFile_WriteString(modstr, f); +                    err += PyFile_WriteString(".", f); +                } +                Py_DECREF(moduleName);              } -            Py_DECREF(moduleName); -        } -        if (err == 0) { -            if (className == NULL) +            if (err == 0) { +                if (className == NULL)                        err = PyFile_WriteString("<unknown>", f); -            else +                else                        err = PyFile_WriteString(className, f); +            }          } +        else +            err = PyFile_WriteObject(exception, f, Py_PRINT_RAW); +        if (err == 0 && (value != Py_None)) { +            PyObject *s = PyObject_Str(value); +            /* only print colon if the str() of the +               object is not the empty string +            */ +            if (s == NULL) +                err = -1; +            else if (!PyString_Check(s) || +                     PyString_GET_SIZE(s) != 0) +                err = PyFile_WriteString(": ", f); +            if (err == 0) +              err = PyFile_WriteObject(s, f, Py_PRINT_RAW); +            Py_XDECREF(s); +        } +        /* try to write a newline in any case */ +        err += PyFile_WriteString("\n", f);      } -    if (err == 0 && (value != Py_None)) { -        PyObject *s = PyObject_Str(value); -        /* only print colon if the str() of the -           object is not the empty string -        */ -        if (s == NULL) -            err = -1; -        else if (!PyUnicode_Check(s) || -            PyUnicode_GetSize(s) != 0) -            err = PyFile_WriteString(": ", f); -        if (err == 0) -          err = PyFile_WriteObject(s, f, Py_PRINT_RAW); -        Py_XDECREF(s); -    } -    /* try to write a newline in any case */ -    err += PyFile_WriteString("\n", f); -    Py_XDECREF(tb);      Py_DECREF(value);      /* If an error happened here, don't show it.         XXX This is wrong, but too many callers rely on this behavior. */ @@ -1612,82 +1313,6 @@ print_exception(PyObject *f, PyObject *value)          PyErr_Clear();  } -static const char *cause_message = -    "\nThe above exception was the direct cause " -    "of the following exception:\n\n"; - -static const char *context_message = -    "\nDuring handling of the above exception, " -    "another exception occurred:\n\n"; - -static void -print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen) -{ -    int err = 0, res; -    PyObject *cause, *context; - -    if (seen != NULL) { -        /* Exception chaining */ -        if (PySet_Add(seen, value) == -1) -            PyErr_Clear(); -        else if (PyExceptionInstance_Check(value)) { -            cause = PyException_GetCause(value); -            context = PyException_GetContext(value); -            if (cause) { -                res = PySet_Contains(seen, cause); -                if (res == -1) -                    PyErr_Clear(); -                if (res == 0) { -                    print_exception_recursive( -                        f, cause, seen); -                    err |= PyFile_WriteString( -                        cause_message, f); -                } -            } -            else if (context) { -                res = PySet_Contains(seen, context); -                if (res == -1) -                    PyErr_Clear(); -                if (res == 0) { -                    print_exception_recursive( -                        f, context, seen); -                    err |= PyFile_WriteString( -                        context_message, f); -                } -            } -            Py_XDECREF(context); -            Py_XDECREF(cause); -        } -    } -    print_exception(f, value); -    if (err != 0) -        PyErr_Clear(); -} - -void -PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) -{ -    PyObject *seen; -    PyObject *f = PySys_GetObject("stderr"); -    if (f == Py_None) { -        /* pass */ -    } -    else if (f == NULL) { -        _PyObject_Dump(value); -        fprintf(stderr, "lost sys.stderr\n"); -    } -    else { -        /* We choose to ignore seen being possibly NULL, and report -           at least the main exception (it could be a MemoryError). -        */ -        seen = PySet_New(NULL); -        if (seen == NULL) -            PyErr_Clear(); -        print_exception_recursive(f, value, seen); -        Py_XDECREF(seen); -    } -} -  PyObject *  PyRun_StringFlags(const char *str, int start, PyObject *globals,                    PyObject *locals, PyCompilerFlags *flags) @@ -1715,7 +1340,7 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,      if (arena == NULL)          return NULL; -    mod = PyParser_ASTFromFile(fp, filename, NULL, start, 0, 0, +    mod = PyParser_ASTFromFile(fp, filename, start, 0, 0,                                 flags, NULL, arena);      if (closeit)          fclose(fp); @@ -1728,35 +1353,6 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,      return ret;  } -static void -flush_io(void) -{ -    PyObject *f, *r; -    PyObject *type, *value, *traceback; - -    /* Save the current exception */ -    PyErr_Fetch(&type, &value, &traceback); - -    f = PySys_GetObject("stderr"); -    if (f != NULL) { -        r = PyObject_CallMethod(f, "flush", ""); -        if (r) -            Py_DECREF(r); -        else -            PyErr_Clear(); -    } -    f = PySys_GetObject("stdout"); -    if (f != NULL) { -        r = PyObject_CallMethod(f, "flush", ""); -        if (r) -            Py_DECREF(r); -        else -            PyErr_Clear(); -    } - -    PyErr_Restore(type, value, traceback); -} -  static PyObject *  run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,           PyCompilerFlags *flags, PyArena *arena) @@ -1766,7 +1362,7 @@ run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,      co = PyAST_Compile(mod, filename, flags, arena);      if (co == NULL)          return NULL; -    v = PyEval_EvalCode((PyObject*)co, globals, locals); +    v = PyEval_EvalCode(co, globals, locals);      Py_DECREF(co);      return v;  } @@ -1796,7 +1392,7 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals,          return NULL;      }      co = (PyCodeObject *)v; -    v = PyEval_EvalCode((PyObject*)co, globals, locals); +    v = PyEval_EvalCode(co, globals, locals);      if (v && flags)          flags->cf_flags |= (co->co_flags & PyCF_MASK);      Py_DECREF(co); @@ -1804,8 +1400,8 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals,  }  PyObject * -Py_CompileStringExFlags(const char *str, const char *filename, int start, -                        PyCompilerFlags *flags, int optimize) +Py_CompileStringFlags(const char *str, const char *filename, int start, +                      PyCompilerFlags *flags)  {      PyCodeObject *co;      mod_ty mod; @@ -1823,19 +1419,11 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start,          PyArena_Free(arena);          return result;      } -    co = PyAST_CompileEx(mod, filename, flags, optimize, arena); +    co = PyAST_Compile(mod, filename, flags, arena);      PyArena_Free(arena);      return (PyObject *)co;  } -/* For use in Py_LIMITED_API */ -#undef Py_CompileString -PyObject * -PyCompileString(const char *str, const char *filename, int start) -{ -    return Py_CompileStringFlags(str, filename, start, NULL); -} -  struct symtable *  Py_SymtableString(const char *str, const char *filename, int start)  { @@ -1847,6 +1435,7 @@ Py_SymtableString(const char *str, const char *filename, int start)          return NULL;      flags.cf_flags = 0; +      mod = PyParser_ASTFromString(str, filename, start, &flags, arena);      if (mod == NULL) {          PyArena_Free(arena); @@ -1887,8 +1476,7 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,  }  mod_ty -PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc, -                     int start, char *ps1, +PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1,                       char *ps2, PyCompilerFlags *flags, int *errcode,                       PyArena *arena)  { @@ -1897,8 +1485,7 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,      perrdetail err;      int iflags = PARSER_FLAGS(flags); -    node *n = PyParser_ParseFileFlagsEx(fp, filename, enc, -                                      &_PyParser_Grammar, +    node *n = PyParser_ParseFileFlagsEx(fp, filename, &_PyParser_Grammar,                              start, ps1, ps2, &err, &iflags);      if (flags == NULL) {          localflags.cf_flags = 0; @@ -1924,8 +1511,7 @@ node *  PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)  {      perrdetail err; -    node *n = PyParser_ParseFileFlags(fp, filename, NULL, -                                      &_PyParser_Grammar, +    node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar,                                        start, NULL, NULL, &err, flags);      if (n == NULL)          err_input(&err); @@ -1978,11 +1564,9 @@ PyParser_SetError(perrdetail *err)  static void  err_input(perrdetail *err)  { -    PyObject *v, *w, *errtype, *errtext; -    PyObject *msg_obj = NULL; -    PyObject *filename; +    PyObject *v, *w, *errtype; +    PyObject* u = NULL;      char *msg = NULL; -      errtype = PyExc_SyntaxError;      switch (err->error) {      case E_ERROR: @@ -2037,9 +1621,14 @@ err_input(perrdetail *err)      case E_DECODE: {          PyObject *type, *value, *tb;          PyErr_Fetch(&type, &value, &tb); -        msg = "unknown decode error"; -        if (value != NULL) -            msg_obj = PyObject_Str(value); +        if (value != NULL) { +            u = PyObject_Str(value); +            if (u != NULL) { +                msg = PyString_AsString(u); +            } +        } +        if (msg == NULL) +            msg = "unknown decode error";          Py_XDECREF(type);          Py_XDECREF(value);          Py_XDECREF(tb); @@ -2048,47 +1637,21 @@ err_input(perrdetail *err)      case E_LINECONT:          msg = "unexpected character after line continuation character";          break; - -    case E_IDENTIFIER: -        msg = "invalid character in identifier"; -        break;      default:          fprintf(stderr, "error=%d\n", err->error);          msg = "unknown parsing error";          break;      } -    /* err->text may not be UTF-8 in case of decoding errors. -       Explicitly convert to an object. */ -    if (!err->text) { -        errtext = Py_None; -        Py_INCREF(Py_None); -    } else { -        errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text), -                                       "replace"); -    } -    if (err->filename != NULL) -        filename = PyUnicode_DecodeFSDefault(err->filename); -    else { -        Py_INCREF(Py_None); -        filename = Py_None; -    } -    if (filename != NULL) -        v = Py_BuildValue("(NiiN)", filename, -                          err->lineno, err->offset, errtext); -    else -        v = NULL; -    if (v != NULL) { -        if (msg_obj) -            w = Py_BuildValue("(OO)", msg_obj, v); -        else -            w = Py_BuildValue("(sO)", msg, v); -    } else -        w = NULL; +    v = Py_BuildValue("(ziiz)", err->filename, +                      err->lineno, err->offset, err->text); +    w = NULL; +    if (v != NULL) +        w = Py_BuildValue("(sO)", msg, v); +    Py_XDECREF(u);      Py_XDECREF(v);      PyErr_SetObject(errtype, w);      Py_XDECREF(w);  cleanup: -    Py_XDECREF(msg_obj);      if (err->text != NULL) {          PyObject_FREE(err->text);          err->text = NULL; @@ -2102,9 +1665,7 @@ Py_FatalError(const char *msg)  {      fprintf(stderr, "Fatal Python error: %s\n", msg);      fflush(stderr); /* it helps in Windows debug build */ -    if (PyErr_Occurred()) { -        PyErr_PrintEx(0); -    } +  #ifdef MS_WINDOWS      {          size_t len = strlen(msg); @@ -2134,23 +1695,6 @@ Py_FatalError(const char *msg)  #include "pythread.h"  #endif -static void (*pyexitfunc)(void) = NULL; -/* For the atexit module. */ -void _Py_PyAtExit(void (*func)(void)) -{ -    pyexitfunc = func; -} - -static void -call_py_exitfuncs(void) -{ -    if (pyexitfunc == NULL) -        return; - -    (*pyexitfunc)(); -    PyErr_Clear(); -} -  /* Wait until threading._shutdown completes, provided     the threading module was imported in the first place.     The shutdown routine will wait until all non-daemon @@ -2169,12 +1713,10 @@ wait_for_thread_shutdown(void)          return;      }      result = PyObject_CallMethod(threading, "_shutdown", ""); -    if (result == NULL) { +    if (result == NULL)          PyErr_WriteUnraisable(threading); -    } -    else { +    else          Py_DECREF(result); -    }      Py_DECREF(threading);  #endif  } @@ -2192,6 +1734,29 @@ int Py_AtExit(void (*func)(void))  }  static void +call_sys_exitfunc(void) +{ +    PyObject *exitfunc = PySys_GetObject("exitfunc"); + +    if (exitfunc) { +        PyObject *res; +        Py_INCREF(exitfunc); +        PySys_SetObject("exitfunc", (PyObject *)NULL); +        res = PyEval_CallObject(exitfunc, (PyObject *)NULL); +        if (res == NULL) { +            if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { +                PySys_WriteStderr("Error in sys.exitfunc:\n"); +            } +            PyErr_Print(); +        } +        Py_DECREF(exitfunc); +    } + +    if (Py_FlushLine()) +        PyErr_Clear(); +} + +static void  call_ll_exitfuncs(void)  {      while (nexitfuncs > 0) @@ -2225,27 +1790,6 @@ initsigs(void)  } -/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. - * - * All of the code in this function must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - */ -void -_Py_RestoreSignals(void) -{ -#ifdef SIGPIPE -    PyOS_setsig(SIGPIPE, SIG_DFL); -#endif -#ifdef SIGXFZ -    PyOS_setsig(SIGXFZ, SIG_DFL); -#endif -#ifdef SIGXFSZ -    PyOS_setsig(SIGXFSZ, SIG_DFL); -#endif -} - -  /*   * The file descriptor fd is considered ``interactive'' if either   *   a) isatty(fd) is TRUE, or @@ -2339,11 +1883,6 @@ PyOS_getsig(int sig)  #endif  } -/* - * All of the code in this function must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - */  PyOS_sighandler_t  PyOS_setsig(int sig, PyOS_sighandler_t handler)  { @@ -2461,15 +2000,7 @@ PyRun_SimpleString(const char *s)  PyAPI_FUNC(PyObject *)  Py_CompileString(const char *str, const char *p, int s)  { -    return Py_CompileStringExFlags(str, p, s, NULL, -1); -} - -#undef Py_CompileStringFlags -PyAPI_FUNC(PyObject *) -Py_CompileStringFlags(const char *str, const char *p, int s, -                      PyCompilerFlags *flags) -{ -    return Py_CompileStringExFlags(str, p, s, flags, -1); +    return Py_CompileStringFlags(str, p, s, NULL);  }  #undef PyRun_InteractiveOne @@ -2489,3 +2020,4 @@ PyRun_InteractiveLoop(FILE *f, const char *p)  #ifdef __cplusplus  }  #endif + | 
