Skip to content

Commit 78184af

Browse files
Issue python#21715: Extracted shared complicated code in the _io module to new
_PyErr_ChainExceptions() function.
2 parents 94262eb + e2bd2a7 commit 78184af

File tree

5 files changed

+33
-42
lines changed

5 files changed

+33
-42
lines changed

Include/pyerrors.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *);
123123
/* Context manipulation (PEP 3134) */
124124
PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *);
125125
PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *);
126-
126+
#ifndef Py_LIMITED_API
127+
PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
128+
#endif
127129

128130
/* */
129131

Modules/_io/_iomodule.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -458,19 +458,8 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds)
458458
PyObject *exc, *val, *tb, *close_result;
459459
PyErr_Fetch(&exc, &val, &tb);
460460
close_result = _PyObject_CallMethodId(result, &PyId_close, NULL);
461-
if (close_result != NULL) {
462-
Py_DECREF(close_result);
463-
PyErr_Restore(exc, val, tb);
464-
} else {
465-
PyObject *exc2, *val2, *tb2;
466-
PyErr_Fetch(&exc2, &val2, &tb2);
467-
PyErr_NormalizeException(&exc, &val, &tb);
468-
Py_XDECREF(exc);
469-
Py_XDECREF(tb);
470-
PyErr_NormalizeException(&exc2, &val2, &tb2);
471-
PyException_SetContext(val2, val);
472-
PyErr_Restore(exc2, val2, tb2);
473-
}
461+
_PyErr_ChainExceptions(exc, val, tb);
462+
Py_XDECREF(close_result);
474463
Py_DECREF(result);
475464
}
476465
Py_XDECREF(modeobj);

Modules/_io/bufferedio.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -561,20 +561,8 @@ buffered_close(buffered *self, PyObject *args)
561561
}
562562

563563
if (exc != NULL) {
564-
if (res != NULL) {
565-
Py_CLEAR(res);
566-
PyErr_Restore(exc, val, tb);
567-
}
568-
else {
569-
PyObject *exc2, *val2, *tb2;
570-
PyErr_Fetch(&exc2, &val2, &tb2);
571-
PyErr_NormalizeException(&exc, &val, &tb);
572-
Py_DECREF(exc);
573-
Py_XDECREF(tb);
574-
PyErr_NormalizeException(&exc2, &val2, &tb2);
575-
PyException_SetContext(val2, val);
576-
PyErr_Restore(exc2, val2, tb2);
577-
}
564+
_PyErr_ChainExceptions(exc, val, tb);
565+
Py_CLEAR(res);
578566
}
579567

580568
end:

Modules/_io/textio.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,20 +2614,8 @@ textiowrapper_close(textio *self, PyObject *args)
26142614

26152615
res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);
26162616
if (exc != NULL) {
2617-
if (res != NULL) {
2618-
Py_CLEAR(res);
2619-
PyErr_Restore(exc, val, tb);
2620-
}
2621-
else {
2622-
PyObject *exc2, *val2, *tb2;
2623-
PyErr_Fetch(&exc2, &val2, &tb2);
2624-
PyErr_NormalizeException(&exc, &val, &tb);
2625-
Py_DECREF(exc);
2626-
Py_XDECREF(tb);
2627-
PyErr_NormalizeException(&exc2, &val2, &tb2);
2628-
PyException_SetContext(val2, val);
2629-
PyErr_Restore(exc2, val2, tb2);
2630-
}
2617+
_PyErr_ChainExceptions(exc, val, tb);
2618+
Py_CLEAR(res);
26312619
}
26322620
return res;
26332621
}

Python/errors.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,30 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
384384
Py_XDECREF(oldtraceback);
385385
}
386386

387+
/* Like PyErr_Restore(), but if an exception is already set,
388+
set the context associated with it.
389+
*/
390+
void
391+
_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb)
392+
{
393+
if (exc == NULL)
394+
return;
395+
396+
if (PyErr_Occurred()) {
397+
PyObject *exc2, *val2, *tb2;
398+
PyErr_Fetch(&exc2, &val2, &tb2);
399+
PyErr_NormalizeException(&exc, &val, &tb);
400+
Py_DECREF(exc);
401+
Py_XDECREF(tb);
402+
PyErr_NormalizeException(&exc2, &val2, &tb2);
403+
PyException_SetContext(val2, val);
404+
PyErr_Restore(exc2, val2, tb2);
405+
}
406+
else {
407+
PyErr_Restore(exc, val, tb);
408+
}
409+
}
410+
387411
/* Convenience functions to set a type error exception and return 0 */
388412

389413
int

0 commit comments

Comments
 (0)