Commit aa64c46a authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #23781: Add private helper function _PyErr_ReplaceException() that

corresponds _PyErr_ChainExceptions() in Python 3 to help porting patches
from Python 3.
parent d06c201e
......@@ -91,6 +91,7 @@ PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *);
PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *);
PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**);
PyAPI_FUNC(void) _PyErr_ReplaceException(PyObject *, PyObject *, PyObject *);
/* */
......
......@@ -529,14 +529,8 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds)
PyObject *exc, *val, *tb, *close_result;
PyErr_Fetch(&exc, &val, &tb);
close_result = PyObject_CallMethod(result, "close", NULL);
if (close_result != NULL) {
Py_DECREF(close_result);
PyErr_Restore(exc, val, tb);
} else {
Py_XDECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);
}
_PyErr_ReplaceException(exc, val, tb);
Py_XDECREF(close_result);
Py_DECREF(result);
}
Py_XDECREF(modeobj);
......
......@@ -483,15 +483,8 @@ buffered_close(buffered *self, PyObject *args)
res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
if (exc != NULL) {
if (res != NULL) {
Py_CLEAR(res);
PyErr_Restore(exc, val, tb);
}
else {
Py_DECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);
}
_PyErr_ReplaceException(exc, val, tb);
Py_CLEAR(res);
}
end:
......
......@@ -2480,15 +2480,8 @@ textiowrapper_close(textio *self, PyObject *args)
res = PyObject_CallMethod(self->buffer, "close", NULL);
if (exc != NULL) {
if (res != NULL) {
Py_CLEAR(res);
PyErr_Restore(exc, val, tb);
}
else {
Py_DECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);
}
_PyErr_ReplaceException(exc, val, tb);
Py_CLEAR(res);
}
return res;
}
......
......@@ -263,6 +263,26 @@ PyErr_Clear(void)
PyErr_Restore(NULL, NULL, NULL);
}
/* Restore previously fetched exception if an exception is not set,
otherwise drop previously fetched exception.
Like _PyErr_ChainExceptions() in Python 3, but doesn't set the context.
*/
void
_PyErr_ReplaceException(PyObject *exc, PyObject *val, PyObject *tb)
{
if (exc == NULL)
return;
if (PyErr_Occurred()) {
Py_DECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);
}
else {
PyErr_Restore(exc, val, tb);
}
}
/* Convenience functions to set a type error exception and return 0 */
int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment