Skip to content

Commit 6b9d4cb

Browse files
iritkatrielFidget-Spinner
authored andcommitted
pythongh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (python#102743)
1 parent df9a322 commit 6b9d4cb

File tree

1 file changed

+35
-44
lines changed

1 file changed

+35
-44
lines changed

Python/pythonrun.c

+35-44
Original file line numberDiff line numberDiff line change
@@ -698,30 +698,30 @@ _Py_HandleSystemExit(int *exitcode_p)
698698
return 0;
699699
}
700700

701-
PyObject *exception, *value, *tb;
702-
PyErr_Fetch(&exception, &value, &tb);
703-
704701
fflush(stdout);
705702

706703
int exitcode = 0;
707-
if (value == NULL || value == Py_None) {
704+
705+
PyObject *exc = PyErr_GetRaisedException();
706+
if (exc == NULL) {
708707
goto done;
709708
}
709+
assert(PyExceptionInstance_Check(exc));
710710

711-
if (PyExceptionInstance_Check(value)) {
712-
/* The error code should be in the `code' attribute. */
713-
PyObject *code = PyObject_GetAttr(value, &_Py_ID(code));
714-
if (code) {
715-
Py_SETREF(value, code);
716-
if (value == Py_None)
717-
goto done;
711+
/* The error code should be in the `code' attribute. */
712+
PyObject *code = PyObject_GetAttr(exc, &_Py_ID(code));
713+
if (code) {
714+
Py_SETREF(exc, code);
715+
if (exc == Py_None) {
716+
goto done;
718717
}
719-
/* If we failed to dig out the 'code' attribute,
720-
just let the else clause below print the error. */
721718
}
719+
/* If we failed to dig out the 'code' attribute,
720+
* just let the else clause below print the error.
721+
*/
722722

723-
if (PyLong_Check(value)) {
724-
exitcode = (int)PyLong_AsLong(value);
723+
if (PyLong_Check(exc)) {
724+
exitcode = (int)PyLong_AsLong(exc);
725725
}
726726
else {
727727
PyThreadState *tstate = _PyThreadState_GET();
@@ -732,20 +732,17 @@ _Py_HandleSystemExit(int *exitcode_p)
732732
*/
733733
PyErr_Clear();
734734
if (sys_stderr != NULL && sys_stderr != Py_None) {
735-
PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW);
735+
PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW);
736736
} else {
737-
PyObject_Print(value, stderr, Py_PRINT_RAW);
737+
PyObject_Print(exc, stderr, Py_PRINT_RAW);
738738
fflush(stderr);
739739
}
740740
PySys_WriteStderr("\n");
741741
exitcode = 1;
742742
}
743743

744-
done:
745-
/* Cleanup the exception */
746-
Py_CLEAR(exception);
747-
Py_CLEAR(value);
748-
Py_CLEAR(tb);
744+
done:
745+
Py_CLEAR(exc);
749746
*exitcode_p = exitcode;
750747
return 1;
751748
}
@@ -1641,35 +1638,29 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
16411638

16421639
}
16431640

1644-
16451641
static void
1646-
flush_io(void)
1642+
flush_io_stream(PyThreadState *tstate, PyObject *name)
16471643
{
1648-
PyObject *f, *r;
1649-
PyObject *type, *value, *traceback;
1650-
1651-
/* Save the current exception */
1652-
PyErr_Fetch(&type, &value, &traceback);
1653-
1654-
PyThreadState *tstate = _PyThreadState_GET();
1655-
f = _PySys_GetAttr(tstate, &_Py_ID(stderr));
1656-
if (f != NULL) {
1657-
r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
1658-
if (r)
1659-
Py_DECREF(r);
1660-
else
1661-
PyErr_Clear();
1662-
}
1663-
f = _PySys_GetAttr(tstate, &_Py_ID(stdout));
1644+
PyObject *f = _PySys_GetAttr(tstate, name);
16641645
if (f != NULL) {
1665-
r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
1666-
if (r)
1646+
PyObject *r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
1647+
if (r) {
16671648
Py_DECREF(r);
1668-
else
1649+
}
1650+
else {
16691651
PyErr_Clear();
1652+
}
16701653
}
1654+
}
16711655

1672-
PyErr_Restore(type, value, traceback);
1656+
static void
1657+
flush_io(void)
1658+
{
1659+
PyThreadState *tstate = _PyThreadState_GET();
1660+
PyObject *exc = _PyErr_GetRaisedException(tstate);
1661+
flush_io_stream(tstate, &_Py_ID(stderr));
1662+
flush_io_stream(tstate, &_Py_ID(stdout));
1663+
_PyErr_SetRaisedException(tstate, exc);
16731664
}
16741665

16751666
static PyObject *

0 commit comments

Comments
 (0)