diff options
Diffstat (limited to 'Python/pythonrun.c')
| -rw-r--r-- | Python/pythonrun.c | 171 | 
1 files changed, 111 insertions, 60 deletions
| diff --git a/Python/pythonrun.c b/Python/pythonrun.c index bea7fe1..389bcd0 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -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 *); @@ -138,12 +141,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; @@ -165,18 +169,25 @@ 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 +}  void  Py_InitializeEx(int install_sigs) @@ -250,7 +261,8 @@ Py_InitializeEx(int install_sigs)          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) @@ -289,6 +301,10 @@ Py_InitializeEx(int install_sigs)      _PyImportHooks_Init(); +    /* initialize the faulthandler module */ +    if (_PyFaulthandler_Init()) +        Py_FatalError("Py_Initialize: can't initialize faulthandler"); +      /* Initialize _warnings. */      _PyWarnings_Init(); @@ -338,9 +354,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) { -        tmp = PyObject_CallMethod(fout, "flush", ""); +        tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");          if (tmp == NULL)              PyErr_WriteUnraisable(fout);          else @@ -348,7 +365,7 @@ flush_std_files(void)      }      if (ferr != NULL && ferr != Py_None) { -        tmp = PyObject_CallMethod(ferr, "flush", ""); +        tmp = _PyObject_CallMethodId(ferr, &PyId_flush, "");          if (tmp == NULL)              PyErr_Clear();          else @@ -462,6 +479,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); @@ -511,6 +531,7 @@ Py_Finalize(void)      PyLong_Fini();      PyFloat_Fini();      PyDict_Fini(); +    PySlice_Fini();      /* Cleanup Unicode implementation */      _PyUnicode_Fini(); @@ -736,24 +757,17 @@ 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); @@ -795,6 +809,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 @@ -809,14 +828,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;      } @@ -826,9 +846,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); @@ -851,9 +871,9 @@ create_stdio(PyObject* io,      }  #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; @@ -863,7 +883,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; @@ -1101,13 +1121,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); @@ -1304,6 +1325,11 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,  {      long hold;      PyObject *v; +    _Py_IDENTIFIER(msg); +    _Py_IDENTIFIER(filename); +    _Py_IDENTIFIER(lineno); +    _Py_IDENTIFIER(offset); +    _Py_IDENTIFIER(text);      /* old style errors */      if (PyTuple_Check(err)) @@ -1312,11 +1338,11 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,      /* new style errors.  `err' is an instance */ -    if (! (v = PyObject_GetAttrString(err, "msg"))) +    if (! (v = _PyObject_GetAttrId(err, &PyId_msg)))          goto finally;      *message = v; -    if (!(v = PyObject_GetAttrString(err, "filename"))) +    if (!(v = _PyObject_GetAttrId(err, &PyId_filename)))          goto finally;      if (v == Py_None)          *filename = NULL; @@ -1324,7 +1350,7 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,          goto finally;      Py_DECREF(v); -    if (!(v = PyObject_GetAttrString(err, "lineno"))) +    if (!(v = _PyObject_GetAttrId(err, &PyId_lineno)))          goto finally;      hold = PyLong_AsLong(v);      Py_DECREF(v); @@ -1333,7 +1359,7 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,          goto finally;      *lineno = (int)hold; -    if (!(v = PyObject_GetAttrString(err, "offset"))) +    if (!(v = _PyObject_GetAttrId(err, &PyId_offset)))          goto finally;      if (v == Py_None) {          *offset = -1; @@ -1348,7 +1374,7 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,          *offset = (int)hold;      } -    if (!(v = PyObject_GetAttrString(err, "text"))) +    if (!(v = _PyObject_GetAttrId(err, &PyId_text)))          goto finally;      if (v == Py_None)          *text = NULL; @@ -1417,7 +1443,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; @@ -1524,6 +1551,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); @@ -1539,7 +1567,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; @@ -1574,6 +1602,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) { @@ -1582,10 +1611,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 { @@ -1612,7 +1641,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); @@ -1749,13 +1778,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 @@ -1763,7 +1793,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 @@ -1894,12 +1924,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 @@ -1924,14 +1955,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 */ @@ -1945,6 +1977,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;  } @@ -1959,6 +1992,7 @@ PyParser_SimpleParseStringFlags(const char *str, int start, int flags)                                          start, &err, flags);      if (n == NULL)          err_input(&err); +    err_free(&err);      return n;  } @@ -1971,6 +2005,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;  } @@ -1984,11 +2019,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 @@ -1996,7 +2043,6 @@ err_input(perrdetail *err)  {      PyObject *v, *w, *errtype, *errtext;      PyObject *msg_obj = NULL; -    PyObject *filename;      char *msg = NULL;      errtype = PyExc_SyntaxError; @@ -2082,17 +2128,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); @@ -2116,11 +2153,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); @@ -2175,6 +2225,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, @@ -2184,7 +2235,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);      } | 
