diff options
Diffstat (limited to 'Python/pythonrun.c')
| -rw-r--r-- | Python/pythonrun.c | 349 | 
1 files changed, 264 insertions, 85 deletions
| diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 3639fa7..dd32017 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -52,7 +52,7 @@ extern wchar_t *Py_GetPath(void);  extern grammar _PyParser_Grammar; /* From graminit.c */  /* Forward */ -static void initmain(void); +static void initmain(PyInterpreterState *interp);  static int initfsencoding(PyInterpreterState *interp);  static void initsite(void);  static int initstdio(void); @@ -62,14 +62,17 @@ static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,  static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,                                PyCompilerFlags *);  static void err_input(perrdetail *); +static void err_free(perrdetail *);  static void initsigs(void);  static void call_py_exitfuncs(void);  static void wait_for_thread_shutdown(void);  static void call_ll_exitfuncs(void); -extern void _PyUnicode_Init(void); +extern int _PyUnicode_Init(void);  extern void _PyUnicode_Fini(void);  extern int _PyLong_Init(void);  extern void PyLong_Fini(void); +extern int _PyFaulthandler_Init(void); +extern void _PyFaulthandler_Fini(void);  #ifdef WITH_THREAD  extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); @@ -139,12 +142,13 @@ get_codec_name(const char *encoding)  {      char *name_utf8, *name_str;      PyObject *codec, *name = NULL; +    _Py_IDENTIFIER(name);      codec = _PyCodec_Lookup(encoding);      if (!codec)          goto error; -    name = PyObject_GetAttrString(codec, "name"); +    name = _PyObject_GetAttrId(codec, &PyId_name);      Py_CLEAR(codec);      if (!name)          goto error; @@ -166,21 +170,79 @@ error:      return NULL;  } -#if defined(HAVE_LANGINFO_H) && defined(CODESET)  static char* -get_codeset(void) +get_locale_encoding(void)  { +#ifdef MS_WINDOWS +    char codepage[100]; +    PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP()); +    return get_codec_name(codepage); +#elif defined(HAVE_LANGINFO_H) && defined(CODESET)      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); -} +#else +    PyErr_SetNone(PyExc_NotImplementedError); +    return NULL;  #endif +} + +static void +import_init(PyInterpreterState *interp, PyObject *sysmod) +{ +    PyObject *importlib; +    PyObject *impmod; +    PyObject *sys_modules; +    PyObject *value; + +    /* Import _importlib through its frozen version, _frozen_importlib. */ +    if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { +        Py_FatalError("Py_Initialize: can't import _frozen_importlib"); +    } +    else if (Py_VerboseFlag) { +        PySys_FormatStderr("import _frozen_importlib # frozen\n"); +    } +    importlib = PyImport_AddModule("_frozen_importlib"); +    if (importlib == NULL) { +        Py_FatalError("Py_Initialize: couldn't get _frozen_importlib from " +                      "sys.modules"); +    } +    interp->importlib = importlib; +    Py_INCREF(interp->importlib); + +    /* Install _importlib as __import__ */ +    impmod = PyInit_imp(); +    if (impmod == NULL) { +        Py_FatalError("Py_Initialize: can't import imp"); +    } +    else if (Py_VerboseFlag) { +        PySys_FormatStderr("import imp # builtin\n"); +    } +    sys_modules = PyImport_GetModuleDict(); +    if (Py_VerboseFlag) { +        PySys_FormatStderr("import sys # builtin\n"); +    } +    if (PyDict_SetItemString(sys_modules, "_imp", impmod) < 0) { +        Py_FatalError("Py_Initialize: can't save _imp to sys.modules"); +    } + +    value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); +    if (value == NULL) { +        PyErr_Print(); +        Py_FatalError("Py_Initialize: importlib install failed"); +    } +    Py_DECREF(value); +    Py_DECREF(impmod); + +    _PyImportZip_Init(); +} +  void -Py_InitializeEx(int install_sigs) +_Py_InitializeEx_Private(int install_sigs, int install_importlib)  {      PyInterpreterState *interp;      PyThreadState *tstate; @@ -252,12 +314,10 @@ Py_InitializeEx(int install_sigs)      interp->modules = PyDict_New();      if (interp->modules == NULL)          Py_FatalError("Py_Initialize: can't make modules dictionary"); -    interp->modules_reloading = PyDict_New(); -    if (interp->modules_reloading == NULL) -        Py_FatalError("Py_Initialize: can't make modules_reloading dictionary");      /* Init Unicode implementation; relies on the codec registry */ -    _PyUnicode_Init(); +    if (_PyUnicode_Init() < 0) +        Py_FatalError("Py_Initialize: can't initialize unicode");      bimod = _PyBuiltin_Init();      if (bimod == NULL) @@ -269,7 +329,7 @@ Py_InitializeEx(int install_sigs)      Py_INCREF(interp->builtins);      /* initialize builtin exceptions */ -    _PyExc_Init(); +    _PyExc_Init(bimod);      sysmod = _PySys_Init();      if (sysmod == NULL) @@ -299,6 +359,15 @@ Py_InitializeEx(int install_sigs)      /* Initialize _warnings. */      _PyWarnings_Init(); +    if (!install_importlib) +        return; + +    import_init(interp, sysmod); + +    /* initialize the faulthandler module */ +    if (_PyFaulthandler_Init()) +        Py_FatalError("Py_Initialize: can't initialize faulthandler"); +      _PyTime_Init();      if (initfsencoding(interp) < 0) @@ -307,7 +376,7 @@ Py_InitializeEx(int install_sigs)      if (install_sigs)          initsigs(); /* Signal handling stuff, including initintr() */ -    initmain(); /* Module __main__ */ +    initmain(interp); /* Module __main__ */      if (initstdio() < 0)          Py_FatalError(              "Py_Initialize: can't initialize sys standard streams"); @@ -327,6 +396,12 @@ Py_InitializeEx(int install_sigs)  }  void +Py_InitializeEx(int install_sigs) +{ +    _Py_InitializeEx_Private(install_sigs, 1); +} + +void  Py_Initialize(void)  {      Py_InitializeEx(1); @@ -361,9 +436,10 @@ flush_std_files(void)      PyObject *fout = PySys_GetObject("stdout");      PyObject *ferr = PySys_GetObject("stderr");      PyObject *tmp; +    _Py_IDENTIFIER(flush);      if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { -        tmp = PyObject_CallMethod(fout, "flush", ""); +        tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");          if (tmp == NULL)              PyErr_WriteUnraisable(fout);          else @@ -371,7 +447,7 @@ flush_std_files(void)      }      if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { -        tmp = PyObject_CallMethod(ferr, "flush", ""); +        tmp = _PyObject_CallMethodId(ferr, &PyId_flush, "");          if (tmp == NULL)              PyErr_Clear();          else @@ -464,7 +540,7 @@ Py_Finalize(void)      flush_std_files();      /* Collect final garbage.  This disposes of cycles created by -     * new-style class definitions, for example. +     * class definitions, for example.       * XXX This is disabled because it caused too many problems.  If       * XXX a __del__ or weakref callback triggers here, Python code has       * XXX a hard time running, because even the sys module has been @@ -485,6 +561,9 @@ Py_Finalize(void)      /* Destroy the database used by _PyImport_{Fixup,Find}Extension */      _PyImport_Fini(); +    /* unload faulthandler module */ +    _PyFaulthandler_Fini(); +      /* Debugging stuff */  #ifdef COUNT_ALLOCS      dump_counts(stdout); @@ -534,6 +613,7 @@ Py_Finalize(void)      PyLong_Fini();      PyFloat_Fini();      PyDict_Fini(); +    PySlice_Fini();      /* Cleanup Unicode implementation */      _PyUnicode_Fini(); @@ -562,7 +642,7 @@ Py_Finalize(void)  #endif /* Py_TRACE_REFS */  #ifdef PYMALLOC_DEBUG      if (Py_GETENV("PYTHONMALLOCSTATS")) -        _PyObject_DebugMallocStats(); +        _PyObject_DebugMallocStats(stderr);  #endif      call_ll_exitfuncs(); @@ -606,7 +686,6 @@ Py_NewInterpreter(void)      /* XXX The following is lax in error checking */      interp->modules = PyDict_New(); -    interp->modules_reloading = PyDict_New();      bimod = _PyImport_FindBuiltin("builtins");      if (bimod != NULL) { @@ -617,11 +696,12 @@ Py_NewInterpreter(void)      }      /* initialize builtin exceptions */ -    _PyExc_Init(); +    _PyExc_Init(bimod);      sysmod = _PyImport_FindBuiltin("sys");      if (bimod != NULL && sysmod != NULL) {          PyObject *pstderr; +          interp->sysdict = PyModule_GetDict(sysmod);          if (interp->sysdict == NULL)              goto handle_error; @@ -640,13 +720,15 @@ Py_NewInterpreter(void)          _PyImportHooks_Init(); +        import_init(interp, sysmod); +          if (initfsencoding(interp) < 0)              goto handle_error;          if (initstdio() < 0)              Py_FatalError(              "Py_Initialize: can't initialize sys standard streams"); -        initmain(); +        initmain(interp);          if (!Py_NoSiteFlag)              initsite();      } @@ -743,7 +825,7 @@ Py_GetPythonHome(void)  /* Create __main__ module */  static void -initmain(void) +initmain(PyInterpreterState *interp)  {      PyObject *m, *d;      m = PyImport_AddModule("__main__"); @@ -752,35 +834,48 @@ initmain(void)      d = PyModule_GetDict(m);      if (PyDict_GetItemString(d, "__builtins__") == NULL) {          PyObject *bimod = PyImport_ImportModule("builtins"); -        if (bimod == NULL || -            PyDict_SetItemString(d, "__builtins__", bimod) != 0) -            Py_FatalError("can't add __builtins__ to __main__"); +        if (bimod == NULL) { +            Py_FatalError("Failed to retrieve builtins module"); +        } +        if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { +            Py_FatalError("Failed to initialize __main__.__builtins__"); +        }          Py_DECREF(bimod);      } +    /* Main is a little special - imp.is_builtin("__main__") will return +     * False, but BuiltinImporter is still the most appropriate initial +     * setting for its __loader__ attribute. A more suitable value will +     * be set if __main__ gets further initialized later in the startup +     * process. +     */ +    if (PyDict_GetItemString(d, "__loader__") == NULL) { +        PyObject *loader = PyObject_GetAttrString(interp->importlib, +                                                  "BuiltinImporter"); +        if (loader == NULL) { +            Py_FatalError("Failed to retrieve BuiltinImporter"); +        } +        if (PyDict_SetItemString(d, "__loader__", loader) < 0) { +            Py_FatalError("Failed to initialize __main__.__loader__"); +        } +        Py_DECREF(loader); +    }  }  static int  initfsencoding(PyInterpreterState *interp)  {      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) + +    if (Py_FileSystemDefaultEncoding == NULL) +    { +        Py_FileSystemDefaultEncoding = get_locale_encoding(); +        if (Py_FileSystemDefaultEncoding == NULL)              Py_FatalError("Py_Initialize: Unable to get the locale encoding"); -        Py_FileSystemDefaultEncoding = codeset;          Py_HasFileSystemDefaultEncoding = 0;          interp->fscodec_initialized = 1;          return 0;      } -#endif      /* the encoding is mbcs, utf-8 or ascii */      codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); @@ -822,6 +917,11 @@ create_stdio(PyObject* io,      const char* newline;      PyObject *line_buffering;      int buffering, isatty; +    _Py_IDENTIFIER(open); +    _Py_IDENTIFIER(isatty); +    _Py_IDENTIFIER(TextIOWrapper); +    _Py_IDENTIFIER(name); +    _Py_IDENTIFIER(mode);      /* stdin is always opened in buffered mode, first because it shouldn't         make a difference in common use cases, second because TextIOWrapper @@ -836,14 +936,15 @@ create_stdio(PyObject* io,          mode = "wb";      else          mode = "rb"; -    buf = PyObject_CallMethod(io, "open", "isiOOOi", -                              fd, mode, buffering, -                              Py_None, Py_None, Py_None, 0); +    buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi", +                                 fd, mode, buffering, +                                 Py_None, Py_None, Py_None, 0);      if (buf == NULL)          goto error;      if (buffering) { -        raw = PyObject_GetAttrString(buf, "raw"); +        _Py_IDENTIFIER(raw); +        raw = _PyObject_GetAttrId(buf, &PyId_raw);          if (raw == NULL)              goto error;      } @@ -853,9 +954,9 @@ create_stdio(PyObject* io,      }      text = PyUnicode_FromString(name); -    if (text == NULL || PyObject_SetAttrString(raw, "name", text) < 0) +    if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0)          goto error; -    res = PyObject_CallMethod(raw, "isatty", ""); +    res = _PyObject_CallMethodId(raw, &PyId_isatty, "");      if (res == NULL)          goto error;      isatty = PyObject_IsTrue(res); @@ -881,9 +982,9 @@ create_stdio(PyObject* io,      newline = "\n";  #endif -    stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO", -                                 buf, encoding, errors, -                                 newline, line_buffering); +    stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO", +                                    buf, encoding, errors, +                                    newline, line_buffering);      Py_CLEAR(buf);      if (stream == NULL)          goto error; @@ -893,7 +994,7 @@ create_stdio(PyObject* io,      else          mode = "r";      text = PyUnicode_FromString(mode); -    if (!text || PyObject_SetAttrString(stream, "mode", text) < 0) +    if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0)          goto error;      Py_CLEAR(text);      return stream; @@ -1133,13 +1234,14 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags      PyArena *arena;      char *ps1 = "", *ps2 = "", *enc = NULL;      int errcode = 0; +    _Py_IDENTIFIER(encoding);      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"); +        oenc = _PyObject_GetAttrId(v, &PyId_encoding);          if (!oenc)              return -1;          enc = _PyUnicode_AsString(oenc); @@ -1252,6 +1354,37 @@ maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit)  }  int +static set_main_loader(PyObject *d, const char *filename, const char *loader_name) +{ +    PyInterpreterState *interp; +    PyThreadState *tstate; +    PyObject *filename_obj, *loader_type, *loader; +    int result = 0; + +    filename_obj = PyUnicode_DecodeFSDefault(filename); +    if (filename_obj == NULL) +        return -1; +    /* Get current thread state and interpreter pointer */ +    tstate = PyThreadState_GET(); +    interp = tstate->interp; +    loader_type = PyObject_GetAttrString(interp->importlib, loader_name); +    if (loader_type == NULL) { +        Py_DECREF(filename_obj); +        return -1; +    } +    loader = PyObject_CallFunction(loader_type, "sN", "__main__", filename_obj); +    Py_DECREF(loader_type); +    if (loader == NULL) { +        return -1; +    } +    if (PyDict_SetItemString(d, "__loader__", loader) < 0) { +        result = -1; +    } +    Py_DECREF(loader); +    return result; +} + +int  PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,                          PyCompilerFlags *flags)  { @@ -1284,18 +1417,34 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,      len = strlen(filename);      ext = filename + len - (len > 4 ? 4 : 0);      if (maybe_pyc_file(fp, filename, ext, closeit)) { +        FILE *pyc_fp;          /* Try to run a pyc file. First, re-open in binary */          if (closeit)              fclose(fp); -        if ((fp = fopen(filename, "rb")) == NULL) { +        if ((pyc_fp = fopen(filename, "rb")) == NULL) {              fprintf(stderr, "python: Can't reopen .pyc file\n");              goto done;          }          /* Turn on optimization if a .pyo file is given */          if (strcmp(ext, ".pyo") == 0)              Py_OptimizeFlag = 1; -        v = run_pyc_file(fp, filename, d, d, flags); + +        if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) { +            fprintf(stderr, "python: failed to set __main__.__loader__\n"); +            ret = -1; +            fclose(pyc_fp); +            goto done; +        } +        v = run_pyc_file(pyc_fp, filename, d, d, flags); +        fclose(pyc_fp);      } else { +        /* When running from stdin, leave __main__.__loader__ alone */ +        if (strcmp(filename, "<stdin>") != 0 && +            set_main_loader(d, filename, "SourceFileLoader") < 0) { +            fprintf(stderr, "python: failed to set __main__.__loader__\n"); +            ret = -1; +            goto done; +        }          v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d,                                closeit, flags);      } @@ -1336,20 +1485,20 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,  {      long hold;      PyObject *v; - -    /* old style errors */ -    if (PyTuple_Check(err)) -        return PyArg_ParseTuple(err, "O(ziiz)", message, filename, -                                lineno, offset, text); +    _Py_IDENTIFIER(msg); +    _Py_IDENTIFIER(filename); +    _Py_IDENTIFIER(lineno); +    _Py_IDENTIFIER(offset); +    _Py_IDENTIFIER(text);      *message = NULL;      /* new style errors.  `err' is an instance */ -    *message = PyObject_GetAttrString(err, "msg"); +    *message = _PyObject_GetAttrId(err, &PyId_msg);      if (!*message)          goto finally; -    v = PyObject_GetAttrString(err, "filename"); +    v = _PyObject_GetAttrId(err, &PyId_filename);      if (!v)          goto finally;      if (v == Py_None) { @@ -1363,7 +1512,7 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,              goto finally;      } -    v = PyObject_GetAttrString(err, "lineno"); +    v = _PyObject_GetAttrId(err, &PyId_lineno);      if (!v)          goto finally;      hold = PyLong_AsLong(v); @@ -1372,7 +1521,7 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,          goto finally;      *lineno = (int)hold; -    v = PyObject_GetAttrString(err, "offset"); +    v = _PyObject_GetAttrId(err, &PyId_offset);      if (!v)          goto finally;      if (v == Py_None) { @@ -1386,7 +1535,7 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,          *offset = (int)hold;      } -    v = PyObject_GetAttrString(err, "text"); +    v = _PyObject_GetAttrId(err, &PyId_text);      if (!v)          goto finally;      if (v == Py_None) { @@ -1460,7 +1609,8 @@ handle_system_exit(void)          goto done;      if (PyExceptionInstance_Check(value)) {          /* The error code should be in the `code' attribute. */ -        PyObject *code = PyObject_GetAttrString(value, "code"); +        _Py_IDENTIFIER(code); +        PyObject *code = _PyObject_GetAttrId(value, &PyId_code);          if (code) {              Py_DECREF(value);              value = code; @@ -1567,6 +1717,7 @@ print_exception(PyObject *f, PyObject *value)  {      int err = 0;      PyObject *type, *tb; +    _Py_IDENTIFIER(print_file_and_line);      if (!PyExceptionInstance_Check(value)) {          PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); @@ -1582,7 +1733,7 @@ print_exception(PyObject *f, PyObject *value)      if (tb && tb != Py_None)          err = PyTraceBack_Print(tb, f);      if (err == 0 && -        PyObject_HasAttrString(value, "print_file_and_line")) +        _PyObject_HasAttrId(value, &PyId_print_file_and_line))      {          PyObject *message;          const char *filename, *text; @@ -1617,6 +1768,7 @@ print_exception(PyObject *f, PyObject *value)      else {          PyObject* moduleName;          char* className; +        _Py_IDENTIFIER(__module__);          assert(PyExceptionClass_Check(type));          className = PyExceptionClass_Name(type);          if (className != NULL) { @@ -1625,10 +1777,10 @@ print_exception(PyObject *f, PyObject *value)                  className = dot+1;          } -        moduleName = PyObject_GetAttrString(type, "__module__"); +        moduleName = _PyObject_GetAttrId(type, &PyId___module__);          if (moduleName == NULL || !PyUnicode_Check(moduleName))          { -            Py_DECREF(moduleName); +            Py_XDECREF(moduleName);              err = PyFile_WriteString("<unknown>", f);          }          else { @@ -1655,7 +1807,7 @@ print_exception(PyObject *f, PyObject *value)          if (s == NULL)              err = -1;          else if (!PyUnicode_Check(s) || -            PyUnicode_GetSize(s) != 0) +            PyUnicode_GetLength(s) != 0)              err = PyFile_WriteString(": ", f);          if (err == 0)            err = PyFile_WriteObject(s, f, Py_PRINT_RAW); @@ -1703,7 +1855,8 @@ print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen)                          cause_message, f);                  }              } -            else if (context) { +            else if (context && +                !((PyBaseExceptionObject *)value)->suppress_context) {                  res = PySet_Contains(seen, context);                  if (res == -1)                      PyErr_Clear(); @@ -1792,13 +1945,14 @@ flush_io(void)  {      PyObject *f, *r;      PyObject *type, *value, *traceback; +    _Py_IDENTIFIER(flush);      /* Save the current exception */      PyErr_Fetch(&type, &value, &traceback);      f = PySys_GetObject("stderr");      if (f != NULL) { -        r = PyObject_CallMethod(f, "flush", ""); +        r = _PyObject_CallMethodId(f, &PyId_flush, "");          if (r)              Py_DECREF(r);          else @@ -1806,7 +1960,7 @@ flush_io(void)      }      f = PySys_GetObject("stdout");      if (f != NULL) { -        r = PyObject_CallMethod(f, "flush", ""); +        r = _PyObject_CallMethodId(f, &PyId_flush, "");          if (r)              Py_DECREF(r);          else @@ -1845,9 +1999,10 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals,                     "Bad magic number in .pyc file");          return NULL;      } +    /* Skip mtime and size */ +    (void) PyMarshal_ReadLongFromFile(fp);      (void) PyMarshal_ReadLongFromFile(fp);      v = PyMarshal_ReadLastObjectFromFile(fp); -    fclose(fp);      if (v == NULL || !PyCode_Check(v)) {          Py_XDECREF(v);          PyErr_SetString(PyExc_RuntimeError, @@ -1937,12 +2092,13 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,          flags->cf_flags |= iflags & PyCF_MASK;          mod = PyAST_FromNode(n, flags, filename, arena);          PyNode_Free(n); -        return mod;      }      else {          err_input(&err); -        return NULL; +        mod = NULL;      } +    err_free(&err); +    return mod;  }  mod_ty @@ -1967,14 +2123,15 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,          flags->cf_flags |= iflags & PyCF_MASK;          mod = PyAST_FromNode(n, flags, filename, arena);          PyNode_Free(n); -        return mod;      }      else {          err_input(&err);          if (errcode)              *errcode = err.error; -        return NULL; +        mod = NULL;      } +    err_free(&err); +    return mod;  }  /* Simplified interface to parsefile -- return node or set exception */ @@ -1988,6 +2145,7 @@ PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int fla                                        start, NULL, NULL, &err, flags);      if (n == NULL)          err_input(&err); +    err_free(&err);      return n;  } @@ -2002,6 +2160,7 @@ PyParser_SimpleParseStringFlags(const char *str, int start, int flags)                                          start, &err, flags);      if (n == NULL)          err_input(&err); +    err_free(&err);      return n;  } @@ -2014,6 +2173,7 @@ PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,                              &_PyParser_Grammar, start, &err, flags);      if (n == NULL)          err_input(&err); +    err_free(&err);      return n;  } @@ -2027,11 +2187,23 @@ PyParser_SimpleParseStringFilename(const char *str, const char *filename, int st     even parser modules. */  void +PyParser_ClearError(perrdetail *err) +{ +    err_free(err); +} + +void  PyParser_SetError(perrdetail *err)  {      err_input(err);  } +static void +err_free(perrdetail *err) +{ +    Py_CLEAR(err->filename); +} +  /* Set the error appropriate to the given input error code (see errcode.h) */  static void @@ -2039,7 +2211,6 @@ err_input(perrdetail *err)  {      PyObject *v, *w, *errtype, *errtext;      PyObject *msg_obj = NULL; -    PyObject *filename;      char *msg = NULL;      errtype = PyExc_SyntaxError; @@ -2111,6 +2282,9 @@ err_input(perrdetail *err)      case E_IDENTIFIER:          msg = "invalid character in identifier";          break; +    case E_BADSINGLE: +        msg = "multiple statements found while compiling a single statement"; +        break;      default:          fprintf(stderr, "error=%d\n", err->error);          msg = "unknown parsing error"; @@ -2125,17 +2299,8 @@ err_input(perrdetail *err)          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; +    v = Py_BuildValue("(OiiN)", err->filename, +                      err->lineno, err->offset, errtext);      if (v != NULL) {          if (msg_obj)              w = Py_BuildValue("(OO)", msg_obj, v); @@ -2159,11 +2324,24 @@ cleanup:  void  Py_FatalError(const char *msg)  { +    const int fd = fileno(stderr); +    PyThreadState *tstate; +      fprintf(stderr, "Fatal Python error: %s\n", msg);      fflush(stderr); /* it helps in Windows debug build */      if (PyErr_Occurred()) {          PyErr_PrintEx(0);      } +    else { +        tstate = _Py_atomic_load_relaxed(&_PyThreadState_Current); +        if (tstate != NULL) { +            fputc('\n', stderr); +            fflush(stderr); +            _Py_DumpTracebackThreads(fd, tstate->interp, tstate); +        } +        _PyFaulthandler_Fini(); +    } +  #ifdef MS_WINDOWS      {          size_t len = strlen(msg); @@ -2218,6 +2396,7 @@ static void  wait_for_thread_shutdown(void)  {  #ifdef WITH_THREAD +    _Py_IDENTIFIER(_shutdown);      PyObject *result;      PyThreadState *tstate = PyThreadState_GET();      PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, @@ -2227,7 +2406,7 @@ wait_for_thread_shutdown(void)          PyErr_Clear();          return;      } -    result = PyObject_CallMethod(threading, "_shutdown", ""); +    result = _PyObject_CallMethodId(threading, &PyId__shutdown, "");      if (result == NULL) {          PyErr_WriteUnraisable(threading);      } | 
