diff options
Diffstat (limited to 'Python/errors.c')
| -rw-r--r-- | Python/errors.c | 165 | 
1 files changed, 129 insertions, 36 deletions
| diff --git a/Python/errors.c b/Python/errors.c index 5a9a624279..626b16e46f 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -320,6 +320,39 @@ PyErr_Clear(void)      PyErr_Restore(NULL, NULL, NULL);  } +void +PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) +{ +    PyThreadState *tstate = PyThreadState_GET(); + +    *p_type = tstate->exc_type; +    *p_value = tstate->exc_value; +    *p_traceback = tstate->exc_traceback; + +    Py_XINCREF(*p_type); +    Py_XINCREF(*p_value); +    Py_XINCREF(*p_traceback); +} + +void +PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback) +{ +    PyObject *oldtype, *oldvalue, *oldtraceback; +    PyThreadState *tstate = PyThreadState_GET(); + +    oldtype = tstate->exc_type; +    oldvalue = tstate->exc_value; +    oldtraceback = tstate->exc_traceback; + +    tstate->exc_type = p_type; +    tstate->exc_value = p_value; +    tstate->exc_traceback = p_traceback; + +    Py_XDECREF(oldtype); +    Py_XDECREF(oldvalue); +    Py_XDECREF(oldtraceback); +} +  /* Convenience functions to set a type error exception and return 0 */  int @@ -341,11 +374,9 @@ PyObject *  PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)  {      PyObject *message; -    PyObject *v; +    PyObject *v, *args;      int i = errno; -#ifndef MS_WINDOWS -    char *s; -#else +#ifdef MS_WINDOWS      WCHAR *s_buf = NULL;  #endif /* Unix/Windows */ @@ -355,11 +386,14 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)  #endif  #ifndef MS_WINDOWS -    if (i == 0) -        s = "Error"; /* Sometimes errno didn't get set */ -    else -        s = strerror(i); -    message = PyUnicode_DecodeUTF8(s, strlen(s), "ignore"); +    if (i != 0) { +        char *s = strerror(i); +        message = PyUnicode_DecodeLocale(s, "surrogateescape"); +    } +    else { +        /* Sometimes errno didn't get set */ +        message = PyUnicode_FromString("Error"); +    }  #else      if (i == 0)          message = PyUnicode_FromString("Error"); /* Sometimes errno didn't get set */ @@ -395,7 +429,7 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)                  /* remove trailing cr/lf and dots */                  while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))                      s_buf[--len] = L'\0'; -                message = PyUnicode_FromUnicode(s_buf, len); +                message = PyUnicode_FromWideChar(s_buf, len);              }          }      } @@ -410,14 +444,18 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)      }      if (filenameObject != NULL) -        v = Py_BuildValue("(iOO)", i, message, filenameObject); +        args = Py_BuildValue("(iOO)", i, message, filenameObject);      else -        v = Py_BuildValue("(iO)", i, message); +        args = Py_BuildValue("(iO)", i, message);      Py_DECREF(message); -    if (v != NULL) { -        PyErr_SetObject(exc, v); -        Py_DECREF(v); +    if (args != NULL) { +        v = PyObject_Call(exc, args, NULL); +        Py_DECREF(args); +        if (v != NULL) { +            PyErr_SetObject((PyObject *) Py_TYPE(v), v); +            Py_DECREF(v); +        }      }  #ifdef MS_WINDOWS      LocalFree(s_buf); @@ -464,7 +502,7 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(      int len;      WCHAR *s_buf = NULL; /* Free via LocalFree */      PyObject *message; -    PyObject *v; +    PyObject *args, *v;      DWORD err = (DWORD)ierr;      if (err==0) err = GetLastError();      len = FormatMessageW( @@ -487,7 +525,7 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(          /* remove trailing cr/lf and dots */          while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))              s_buf[--len] = L'\0'; -        message = PyUnicode_FromUnicode(s_buf, len); +        message = PyUnicode_FromWideChar(s_buf, len);      }      if (message == NULL) @@ -496,15 +534,20 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(          return NULL;      } -    if (filenameObject != NULL) -        v = Py_BuildValue("(iOO)", err, message, filenameObject); -    else -        v = Py_BuildValue("(iO)", err, message); +    if (filenameObject == NULL) +        filenameObject = Py_None; +    /* This is the constructor signature for passing a Windows error code. +       The POSIX translation will be figured out by the constructor. */ +    args = Py_BuildValue("(iOOi)", 0, message, filenameObject, err);      Py_DECREF(message); -    if (v != NULL) { -        PyErr_SetObject(exc, v); -        Py_DECREF(v); +    if (args != NULL) { +        v = PyObject_Call(exc, args, NULL); +        Py_DECREF(args); +        if (v != NULL) { +            PyErr_SetObject((PyObject *) Py_TYPE(v), v); +            Py_DECREF(v); +        }      }      LocalFree(s_buf);      return NULL; @@ -575,6 +618,49 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(  }  #endif /* MS_WINDOWS */ +PyObject * +PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) +{ +    PyObject *args, *kwargs, *error; + +    if (msg == NULL) +        return NULL; + +    args = PyTuple_New(1); +    if (args == NULL) +        return NULL; + +    kwargs = PyDict_New(); +    if (kwargs == NULL) { +        Py_DECREF(args); +        return NULL; +    } + +    if (name == NULL) { +        name = Py_None; +    } + +    if (path == NULL) { +        path = Py_None; +    } + +    Py_INCREF(msg); +    PyTuple_SET_ITEM(args, 0, msg); +    PyDict_SetItemString(kwargs, "name", name); +    PyDict_SetItemString(kwargs, "path", path); + +    error = PyObject_Call(PyExc_ImportError, args, kwargs); +    if (error != NULL) { +        PyErr_SetObject((PyObject *)Py_TYPE(error), error); +        Py_DECREF(error); +    } + +    Py_DECREF(args); +    Py_DECREF(kwargs); + +    return NULL; +} +  void  _PyErr_BadInternalCall(const char *filename, int lineno)  { @@ -656,7 +742,7 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict)          if (bases == NULL)              goto failure;      } -    /* Create a real new-style class. */ +    /* Create a real class. */      result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",                                     dot+1, bases, dict);    failure: @@ -707,6 +793,7 @@ PyErr_NewExceptionWithDoc(const char *name, const char *doc,  void  PyErr_WriteUnraisable(PyObject *obj)  { +    _Py_IDENTIFIER(__module__);      PyObject *f, *t, *v, *tb;      PyErr_Fetch(&t, &v, &tb);      f = PySys_GetObject("stderr"); @@ -723,7 +810,7 @@ PyErr_WriteUnraisable(PyObject *obj)                      className = dot+1;              } -            moduleName = PyObject_GetAttrString(t, "__module__"); +            moduleName = _PyObject_GetAttrId(t, &PyId___module__);              if (moduleName == NULL)                  PyFile_WriteString("<unknown>", f);              else { @@ -774,6 +861,12 @@ void  PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)  {      PyObject *exc, *v, *tb, *tmp; +    _Py_IDENTIFIER(filename); +    _Py_IDENTIFIER(lineno); +    _Py_IDENTIFIER(msg); +    _Py_IDENTIFIER(offset); +    _Py_IDENTIFIER(print_file_and_line); +    _Py_IDENTIFIER(text);      /* add attributes for the line number and filename for the error */      PyErr_Fetch(&exc, &v, &tb); @@ -784,7 +877,7 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)      if (tmp == NULL)          PyErr_Clear();      else { -        if (PyObject_SetAttrString(v, "lineno", tmp)) +        if (_PyObject_SetAttrId(v, &PyId_lineno, tmp))              PyErr_Clear();          Py_DECREF(tmp);      } @@ -793,7 +886,7 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)          if (tmp == NULL)              PyErr_Clear();          else { -            if (PyObject_SetAttrString(v, "offset", tmp)) +            if (_PyObject_SetAttrId(v, &PyId_offset, tmp))                  PyErr_Clear();              Py_DECREF(tmp);          } @@ -803,35 +896,35 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)          if (tmp == NULL)              PyErr_Clear();          else { -            if (PyObject_SetAttrString(v, "filename", tmp)) +            if (_PyObject_SetAttrId(v, &PyId_filename, tmp))                  PyErr_Clear();              Py_DECREF(tmp);          }          tmp = PyErr_ProgramText(filename, lineno);          if (tmp) { -            if (PyObject_SetAttrString(v, "text", tmp)) +            if (_PyObject_SetAttrId(v, &PyId_text, tmp))                  PyErr_Clear();              Py_DECREF(tmp);          }      } -    if (PyObject_SetAttrString(v, "offset", Py_None)) { +    if (_PyObject_SetAttrId(v, &PyId_offset, Py_None)) {          PyErr_Clear();      }      if (exc != PyExc_SyntaxError) { -        if (!PyObject_HasAttrString(v, "msg")) { +        if (!_PyObject_HasAttrId(v, &PyId_msg)) {              tmp = PyObject_Str(v);              if (tmp) { -                if (PyObject_SetAttrString(v, "msg", tmp)) +                if (_PyObject_SetAttrId(v, &PyId_msg, tmp))                      PyErr_Clear();                  Py_DECREF(tmp);              } else {                  PyErr_Clear();              }          } -        if (!PyObject_HasAttrString(v, "print_file_and_line")) { -            if (PyObject_SetAttrString(v, "print_file_and_line", -                                       Py_None)) +        if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) { +            if (_PyObject_SetAttrId(v, &PyId_print_file_and_line, +                                    Py_None))                  PyErr_Clear();          }      } | 
