Skip to content

Commit e2bd2a7

Browse files
Issue python#21715: Extracted shared complicated code in the _io module to new
_PyErr_ChainExceptions() function.
1 parent 0ddbf47 commit e2bd2a7

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
@@ -468,19 +468,8 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds)
468468
PyObject *exc, *val, *tb, *close_result;
469469
PyErr_Fetch(&exc, &val, &tb);
470470
close_result = _PyObject_CallMethodId(result, &PyId_close, NULL);
471-
if (close_result != NULL) {
472-
Py_DECREF(close_result);
473-
PyErr_Restore(exc, val, tb);
474-
} else {
475-
PyObject *exc2, *val2, *tb2;
476-
PyErr_Fetch(&exc2, &val2, &tb2);
477-
PyErr_NormalizeException(&exc, &val, &tb);
478-
Py_XDECREF(exc);
479-
Py_XDECREF(tb);
480-
PyErr_NormalizeException(&exc2, &val2, &tb2);
481-
PyException_SetContext(val2, val);
482-
PyErr_Restore(exc2, val2, tb2);
483-
}
471+
_PyErr_ChainExceptions(exc, val, tb);
472+
Py_XDECREF(close_result);
484473
Py_DECREF(result);
485474
}
486475
Py_XDECREF(modeobj);

Modules/_io/bufferedio.c

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

545545
if (exc != NULL) {
546-
if (res != NULL) {
547-
Py_CLEAR(res);
548-
PyErr_Restore(exc, val, tb);
549-
}
550-
else {
551-
PyObject *exc2, *val2, *tb2;
552-
PyErr_Fetch(&exc2, &val2, &tb2);
553-
PyErr_NormalizeException(&exc, &val, &tb);
554-
Py_DECREF(exc);
555-
Py_XDECREF(tb);
556-
PyErr_NormalizeException(&exc2, &val2, &tb2);
557-
PyException_SetContext(val2, val);
558-
PyErr_Restore(exc2, val2, tb2);
559-
}
546+
_PyErr_ChainExceptions(exc, val, tb);
547+
Py_CLEAR(res);
560548
}
561549

562550
end:

Modules/_io/textio.c

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

26092609
res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);
26102610
if (exc != NULL) {
2611-
if (res != NULL) {
2612-
Py_CLEAR(res);
2613-
PyErr_Restore(exc, val, tb);
2614-
}
2615-
else {
2616-
PyObject *exc2, *val2, *tb2;
2617-
PyErr_Fetch(&exc2, &val2, &tb2);
2618-
PyErr_NormalizeException(&exc, &val, &tb);
2619-
Py_DECREF(exc);
2620-
Py_XDECREF(tb);
2621-
PyErr_NormalizeException(&exc2, &val2, &tb2);
2622-
PyException_SetContext(val2, val);
2623-
PyErr_Restore(exc2, val2, tb2);
2624-
}
2611+
_PyErr_ChainExceptions(exc, val, tb);
2612+
Py_CLEAR(res);
26252613
}
26262614
return res;
26272615
}

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)