Skip to content

Commit

Permalink
gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternat…
Browse files Browse the repository at this point in the history
…ives (#102816)
  • Loading branch information
iritkatriel authored and Fidget-Spinner committed Mar 27, 2023
1 parent 1820891 commit ba86d35
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 27 deletions.
8 changes: 2 additions & 6 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -851,9 +851,7 @@ dummy_func(
}
assert(exc && PyExceptionInstance_Check(exc));
Py_INCREF(exc);
PyObject *typ = Py_NewRef(PyExceptionInstance_Class(exc));
PyObject *tb = PyException_GetTraceback(exc);
_PyErr_Restore(tstate, typ, exc, tb);
_PyErr_SetRaisedException(tstate, exc);
goto exception_unwind;
}

Expand All @@ -864,9 +862,7 @@ dummy_func(
}
else {
Py_INCREF(exc);
PyObject *typ = Py_NewRef(PyExceptionInstance_Class(exc));
PyObject *tb = PyException_GetTraceback(exc);
_PyErr_Restore(tstate, typ, exc, tb);
_PyErr_SetRaisedException(tstate, exc);
goto exception_unwind;
}
}
Expand Down
8 changes: 2 additions & 6 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 14 additions & 14 deletions Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,7 @@ PyImport_AddModule(const char *name)
static void
remove_module(PyThreadState *tstate, PyObject *name)
{
PyObject *type, *value, *traceback;
_PyErr_Fetch(tstate, &type, &value, &traceback);
PyObject *exc = _PyErr_GetRaisedException(tstate);

PyObject *modules = MODULES(tstate->interp);
if (PyDict_CheckExact(modules)) {
Expand All @@ -403,7 +402,7 @@ remove_module(PyThreadState *tstate, PyObject *name)
}
}

_PyErr_ChainExceptions(type, value, traceback);
_PyErr_ChainExceptions1(exc);
}


Expand Down Expand Up @@ -2324,32 +2323,34 @@ remove_importlib_frames(PyThreadState *tstate)
const char *remove_frames = "_call_with_frames_removed";
int always_trim = 0;
int in_importlib = 0;
PyObject *exception, *value, *base_tb, *tb;
PyObject **prev_link, **outer_link = NULL;
PyObject *base_tb = NULL;

/* Synopsis: if it's an ImportError, we trim all importlib chunks
from the traceback. We always trim chunks
which end with a call to "_call_with_frames_removed". */

_PyErr_Fetch(tstate, &exception, &value, &base_tb);
if (!exception || _PyInterpreterState_GetConfig(tstate->interp)->verbose) {
PyObject *exc = _PyErr_GetRaisedException(tstate);
if (exc == NULL || _PyInterpreterState_GetConfig(tstate->interp)->verbose) {
goto done;
}

if (PyType_IsSubtype((PyTypeObject *) exception,
(PyTypeObject *) PyExc_ImportError))
if (PyType_IsSubtype(Py_TYPE(exc), (PyTypeObject *) PyExc_ImportError)) {
always_trim = 1;
}

assert(PyExceptionInstance_Check(exc));
base_tb = PyException_GetTraceback(exc);
prev_link = &base_tb;
tb = base_tb;
PyObject *tb = base_tb;
while (tb != NULL) {
assert(PyTraceBack_Check(tb));
PyTracebackObject *traceback = (PyTracebackObject *)tb;
PyObject *next = (PyObject *) traceback->tb_next;
PyFrameObject *frame = traceback->tb_frame;
PyCodeObject *code = PyFrame_GetCode(frame);
int now_in_importlib;

assert(PyTraceBack_Check(tb));
now_in_importlib = _PyUnicode_EqualToASCIIString(code->co_filename, importlib_filename) ||
_PyUnicode_EqualToASCIIString(code->co_filename, external_filename);
if (now_in_importlib && !in_importlib) {
Expand All @@ -2370,15 +2371,14 @@ remove_importlib_frames(PyThreadState *tstate)
Py_DECREF(code);
tb = next;
}
assert(PyExceptionInstance_Check(value));
assert((PyObject *)Py_TYPE(value) == exception);
if (base_tb == NULL) {
base_tb = Py_None;
Py_INCREF(Py_None);
}
PyException_SetTraceback(value, base_tb);
PyException_SetTraceback(exc, base_tb);
done:
_PyErr_Restore(tstate, exception, value, base_tb);
Py_XDECREF(base_tb);
_PyErr_SetRaisedException(tstate, exc);
}


Expand Down
2 changes: 1 addition & 1 deletion Python/pythonrun.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "pycore_interp.h" // PyInterpreterState.importlib
#include "pycore_object.h" // _PyDebug_PrintTotalRefs()
#include "pycore_parser.h" // _PyParser_ASTFromString()
#include "pycore_pyerrors.h" // _PyErr_Fetch, _Py_Offer_Suggestions
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException, _Py_Offer_Suggestions
#include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_sysmodule.h" // _PySys_Audit()
Expand Down

0 comments on commit ba86d35

Please sign in to comment.