gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (#102743)

This commit is contained in:
Irit Katriel 2023-03-16 16:21:49 +00:00 committed by GitHub
parent 84e20c689a
commit 61d6c110d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 37 additions and 46 deletions

View File

@ -698,30 +698,30 @@ _Py_HandleSystemExit(int *exitcode_p)
return 0; return 0;
} }
PyObject *exception, *value, *tb;
PyErr_Fetch(&exception, &value, &tb);
fflush(stdout); fflush(stdout);
int exitcode = 0; int exitcode = 0;
if (value == NULL || value == Py_None) {
PyObject *exc = PyErr_GetRaisedException();
if (exc == NULL) {
goto done; goto done;
} }
assert(PyExceptionInstance_Check(exc));
if (PyExceptionInstance_Check(value)) { /* The error code should be in the `code' attribute. */
/* The error code should be in the `code' attribute. */ PyObject *code = PyObject_GetAttr(exc, &_Py_ID(code));
PyObject *code = PyObject_GetAttr(value, &_Py_ID(code)); if (code) {
if (code) { Py_SETREF(exc, code);
Py_SETREF(value, code); if (exc == Py_None) {
if (value == Py_None) goto done;
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)) { if (PyLong_Check(exc)) {
exitcode = (int)PyLong_AsLong(value); exitcode = (int)PyLong_AsLong(exc);
} }
else { else {
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
@ -732,20 +732,17 @@ _Py_HandleSystemExit(int *exitcode_p)
*/ */
PyErr_Clear(); PyErr_Clear();
if (sys_stderr != NULL && sys_stderr != Py_None) { 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 { } else {
PyObject_Print(value, stderr, Py_PRINT_RAW); PyObject_Print(exc, stderr, Py_PRINT_RAW);
fflush(stderr); fflush(stderr);
} }
PySys_WriteStderr("\n"); PySys_WriteStderr("\n");
exitcode = 1; exitcode = 1;
} }
done: done:
/* Cleanup the exception */ Py_CLEAR(exc);
Py_CLEAR(exception);
Py_CLEAR(value);
Py_CLEAR(tb);
*exitcode_p = exitcode; *exitcode_p = exitcode;
return 1; return 1;
} }
@ -1641,35 +1638,29 @@ 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, name);
if (f != NULL) {
PyObject *r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
if (r) {
Py_DECREF(r);
}
else {
PyErr_Clear();
}
}
}
static void static void
flush_io(void) flush_io(void)
{ {
PyObject *f, *r;
PyObject *type, *value, *traceback;
/* Save the current exception */
PyErr_Fetch(&type, &value, &traceback);
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
f = _PySys_GetAttr(tstate, &_Py_ID(stderr)); PyObject *exc = _PyErr_GetRaisedException(tstate);
if (f != NULL) { flush_io_stream(tstate, &_Py_ID(stderr));
r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); flush_io_stream(tstate, &_Py_ID(stdout));
if (r) _PyErr_SetRaisedException(tstate, exc);
Py_DECREF(r);
else
PyErr_Clear();
}
f = _PySys_GetAttr(tstate, &_Py_ID(stdout));
if (f != NULL) {
r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush));
if (r)
Py_DECREF(r);
else
PyErr_Clear();
}
PyErr_Restore(type, value, traceback);
} }
static PyObject * static PyObject *