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 *); ...@@ -91,6 +91,7 @@ PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *); PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *);
PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *); PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *);
PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, 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) ...@@ -529,14 +529,8 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds)
PyObject *exc, *val, *tb, *close_result; PyObject *exc, *val, *tb, *close_result;
PyErr_Fetch(&exc, &val, &tb); PyErr_Fetch(&exc, &val, &tb);
close_result = PyObject_CallMethod(result, "close", NULL); close_result = PyObject_CallMethod(result, "close", NULL);
if (close_result != NULL) { _PyErr_ReplaceException(exc, val, tb);
Py_DECREF(close_result); Py_XDECREF(close_result);
PyErr_Restore(exc, val, tb);
} else {
Py_XDECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);
}
Py_DECREF(result); Py_DECREF(result);
} }
Py_XDECREF(modeobj); Py_XDECREF(modeobj);
......
...@@ -483,15 +483,8 @@ buffered_close(buffered *self, PyObject *args) ...@@ -483,15 +483,8 @@ buffered_close(buffered *self, PyObject *args)
res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL); res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
if (exc != NULL) { if (exc != NULL) {
if (res != NULL) { _PyErr_ReplaceException(exc, val, tb);
Py_CLEAR(res); Py_CLEAR(res);
PyErr_Restore(exc, val, tb);
}
else {
Py_DECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);
}
} }
end: end:
......
...@@ -2480,15 +2480,8 @@ textiowrapper_close(textio *self, PyObject *args) ...@@ -2480,15 +2480,8 @@ textiowrapper_close(textio *self, PyObject *args)
res = PyObject_CallMethod(self->buffer, "close", NULL); res = PyObject_CallMethod(self->buffer, "close", NULL);
if (exc != NULL) { if (exc != NULL) {
if (res != NULL) { _PyErr_ReplaceException(exc, val, tb);
Py_CLEAR(res); Py_CLEAR(res);
PyErr_Restore(exc, val, tb);
}
else {
Py_DECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);
}
} }
return res; return res;
} }
......
...@@ -263,6 +263,26 @@ PyErr_Clear(void) ...@@ -263,6 +263,26 @@ PyErr_Clear(void)
PyErr_Restore(NULL, NULL, NULL); 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 */ /* Convenience functions to set a type error exception and return 0 */
int 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