From d220a9ffe69ca8789e756da2e79caac1e5b79208 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 15 Mar 2023 23:07:42 +0000 Subject: [PATCH 1/4] gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives --- Python/pythonrun.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 34a44dd92847ba..a8f50eee3e8cab 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -698,30 +698,31 @@ _Py_HandleSystemExit(int *exitcode_p) return 0; } - PyObject *exception, *value, *tb; - PyErr_Fetch(&exception, &value, &tb); - fflush(stdout); int exitcode = 0; - if (value == NULL || value == Py_None) { + + PyObject *exc = PyErr_GetRaisedException(); + assert(exc != Py_None); + if (exc == NULL) { goto done; } - if (PyExceptionInstance_Check(value)) { - /* The error code should be in the `code' attribute. */ - PyObject *code = PyObject_GetAttr(value, &_Py_ID(code)); - if (code) { - Py_SETREF(value, code); - if (value == Py_None) - goto done; + assert(PyExceptionInstance_Check(exc)); + /* The error code should be in the `code' attribute. */ + PyObject *code = PyObject_GetAttr(exc, &_Py_ID(code)); + if (code) { + Py_SETREF(exc, code); + if (exc == Py_None) { + goto done; } - /* If we failed to dig out the 'code' attribute, - just let the else clause below print the error. */ } + /* If we failed to dig out the 'code' attribute, + * just let the else clause below print the error. + */ - if (PyLong_Check(value)) { - exitcode = (int)PyLong_AsLong(value); + if (PyLong_Check(exc)) { + exitcode = (int)PyLong_AsLong(exc); } else { PyThreadState *tstate = _PyThreadState_GET(); @@ -732,20 +733,17 @@ _Py_HandleSystemExit(int *exitcode_p) */ PyErr_Clear(); if (sys_stderr != NULL && sys_stderr != Py_None) { - PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW); + PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW); } else { - PyObject_Print(value, stderr, Py_PRINT_RAW); + PyObject_Print(exc, stderr, Py_PRINT_RAW); fflush(stderr); } PySys_WriteStderr("\n"); exitcode = 1; } - done: - /* Cleanup the exception */ - Py_CLEAR(exception); - Py_CLEAR(value); - Py_CLEAR(tb); +done: + Py_CLEAR(exc); *exitcode_p = exitcode; return 1; } From 86af53f5a701ecc0cde6596bcbaf8aeb7294c2ff Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 15 Mar 2023 23:31:11 +0000 Subject: [PATCH 2/4] flush_io too --- Python/pythonrun.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/Python/pythonrun.c b/Python/pythonrun.c index a8f50eee3e8cab..8571c4c475d4f6 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1639,35 +1639,29 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, } - static void -flush_io(void) +flush_io_stream(PyThreadState *tstate, PyObject *name) { - PyObject *f, *r; - PyObject *type, *value, *traceback; - - /* Save the current exception */ - PyErr_Fetch(&type, &value, &traceback); - - PyThreadState *tstate = _PyThreadState_GET(); - f = _PySys_GetAttr(tstate, &_Py_ID(stderr)); - if (f != NULL) { - r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); - if (r) - Py_DECREF(r); - else - PyErr_Clear(); - } - f = _PySys_GetAttr(tstate, &_Py_ID(stdout)); + PyObject *f = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (f != NULL) { - r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); - if (r) + PyObject *r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); + if (r) { Py_DECREF(r); - else + } + else { PyErr_Clear(); + } } +} - PyErr_Restore(type, value, traceback); +static void +flush_io(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *exc = _PyErr_GetRaisedException(tstate); + flush_io_stream(tstate, &_Py_ID(stderr)); + flush_io_stream(tstate, &_Py_ID(stdout)); + _PyErr_SetRaisedException(tstate, exc); } static PyObject * From 4d2a362c42c0a2581176acca9070d61ca53f4778 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 15 Mar 2023 23:32:51 +0000 Subject: [PATCH 3/4] remove redundant assert --- Python/pythonrun.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 8571c4c475d4f6..ceebddcb380c37 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -703,12 +703,11 @@ _Py_HandleSystemExit(int *exitcode_p) int exitcode = 0; PyObject *exc = PyErr_GetRaisedException(); - assert(exc != Py_None); if (exc == NULL) { goto done; } - assert(PyExceptionInstance_Check(exc)); + /* The error code should be in the `code' attribute. */ PyObject *code = PyObject_GetAttr(exc, &_Py_ID(code)); if (code) { From 0b538ce2f2acbf1879315eb2eefcb47ee324e015 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Thu, 16 Mar 2023 10:28:15 +0000 Subject: [PATCH 4/4] fix copy-paste error --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ceebddcb380c37..5381b105a39fed 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1641,7 +1641,7 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, static void flush_io_stream(PyThreadState *tstate, PyObject *name) { - PyObject *f = _PySys_GetAttr(tstate, &_Py_ID(stderr)); + PyObject *f = _PySys_GetAttr(tstate, name); if (f != NULL) { PyObject *r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); if (r) {