diff options
| -rw-r--r-- | Include/pyerrors.h | 4 | ||||
| -rw-r--r-- | Modules/_io/_iomodule.c | 15 | ||||
| -rw-r--r-- | Modules/_io/bufferedio.c | 16 | ||||
| -rw-r--r-- | Modules/_io/textio.c | 16 | ||||
| -rw-r--r-- | Python/errors.c | 24 | 
5 files changed, 33 insertions, 42 deletions
diff --git a/Include/pyerrors.h b/Include/pyerrors.h index e44fb5f0eb..02f65d6603 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -123,7 +123,9 @@ PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *);  /* Context manipulation (PEP 3134) */  PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *);  PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); - +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); +#endif  /* */ diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 7c4f9cb651..45c31a550e 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -468,19 +468,8 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds)          PyObject *exc, *val, *tb, *close_result;          PyErr_Fetch(&exc, &val, &tb);          close_result = _PyObject_CallMethodId(result, &PyId_close, NULL); -        if (close_result != NULL) { -            Py_DECREF(close_result); -            PyErr_Restore(exc, val, tb); -        } else { -            PyObject *exc2, *val2, *tb2; -            PyErr_Fetch(&exc2, &val2, &tb2); -            PyErr_NormalizeException(&exc, &val, &tb); -            Py_XDECREF(exc); -            Py_XDECREF(tb); -            PyErr_NormalizeException(&exc2, &val2, &tb2); -            PyException_SetContext(val2, val); -            PyErr_Restore(exc2, val2, tb2); -        } +        _PyErr_ChainExceptions(exc, val, tb); +        Py_XDECREF(close_result);          Py_DECREF(result);      }      Py_XDECREF(modeobj); diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 302db0ae13..8084aae2fb 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -543,20 +543,8 @@ buffered_close(buffered *self, PyObject *args)      }      if (exc != NULL) { -        if (res != NULL) { -            Py_CLEAR(res); -            PyErr_Restore(exc, val, tb); -        } -        else { -            PyObject *exc2, *val2, *tb2; -            PyErr_Fetch(&exc2, &val2, &tb2); -            PyErr_NormalizeException(&exc, &val, &tb); -            Py_DECREF(exc); -            Py_XDECREF(tb); -            PyErr_NormalizeException(&exc2, &val2, &tb2); -            PyException_SetContext(val2, val); -            PyErr_Restore(exc2, val2, tb2); -        } +        _PyErr_ChainExceptions(exc, val, tb); +        Py_CLEAR(res);      }  end: diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 635093efff..a3e82a8b44 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -2608,20 +2608,8 @@ textiowrapper_close(textio *self, PyObject *args)          res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);          if (exc != NULL) { -            if (res != NULL) { -                Py_CLEAR(res); -                PyErr_Restore(exc, val, tb); -            } -            else { -                PyObject *exc2, *val2, *tb2; -                PyErr_Fetch(&exc2, &val2, &tb2); -                PyErr_NormalizeException(&exc, &val, &tb); -                Py_DECREF(exc); -                Py_XDECREF(tb); -                PyErr_NormalizeException(&exc2, &val2, &tb2); -                PyException_SetContext(val2, val); -                PyErr_Restore(exc2, val2, tb2); -            } +            _PyErr_ChainExceptions(exc, val, tb); +            Py_CLEAR(res);          }          return res;      } diff --git a/Python/errors.c b/Python/errors.c index 996292a044..a980481110 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -384,6 +384,30 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)      Py_XDECREF(oldtraceback);  } +/* Like PyErr_Restore(), but if an exception is already set, +   set the context associated with it. + */ +void +_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) +{ +    if (exc == NULL) +        return; + +    if (PyErr_Occurred()) { +        PyObject *exc2, *val2, *tb2; +        PyErr_Fetch(&exc2, &val2, &tb2); +        PyErr_NormalizeException(&exc, &val, &tb); +        Py_DECREF(exc); +        Py_XDECREF(tb); +        PyErr_NormalizeException(&exc2, &val2, &tb2); +        PyException_SetContext(val2, val); +        PyErr_Restore(exc2, val2, tb2); +    } +    else { +        PyErr_Restore(exc, val, tb); +    } +} +  /* Convenience functions to set a type error exception and return 0 */  int  | 
