mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
[3.14] gh-132775: Make _PyXI_session Opaque (gh-134522)
This is mostly a refactor to clean things up a bit, most notably the "XI namespace" code.
Making the session opaque requires adding the following internal-only functions:
* _PyXI_NewSession()
* _PyXI_FreeSession()
* _PyXI_GetMainNamespace()
(cherry picked from commit 4a4ac3ab4d
, gh-134452)
Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
This commit is contained in:
parent
068d570be8
commit
04e2dd6513
4 changed files with 929 additions and 861 deletions
|
@ -444,42 +444,54 @@ _exec_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
|
|||
PyObject **p_excinfo)
|
||||
{
|
||||
assert(!_PyErr_Occurred(tstate));
|
||||
_PyXI_session session = {0};
|
||||
_PyXI_session *session = _PyXI_NewSession();
|
||||
if (session == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Prep and switch interpreters.
|
||||
if (_PyXI_Enter(&session, interp, shareables) < 0) {
|
||||
if (_PyXI_Enter(session, interp, shareables) < 0) {
|
||||
if (_PyErr_Occurred(tstate)) {
|
||||
// If an error occured at this step, it means that interp
|
||||
// was not prepared and switched.
|
||||
_PyXI_FreeSession(session);
|
||||
return -1;
|
||||
}
|
||||
// Now, apply the error from another interpreter:
|
||||
PyObject *excinfo = _PyXI_ApplyError(session.error);
|
||||
PyObject *excinfo = _PyXI_ApplyCapturedException(session);
|
||||
if (excinfo != NULL) {
|
||||
*p_excinfo = excinfo;
|
||||
}
|
||||
assert(PyErr_Occurred());
|
||||
_PyXI_FreeSession(session);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Run the script.
|
||||
int res = _run_script(script, session.main_ns);
|
||||
int res = -1;
|
||||
PyObject *mainns = _PyXI_GetMainNamespace(session);
|
||||
if (mainns == NULL) {
|
||||
goto finally;
|
||||
}
|
||||
res = _run_script(script, mainns);
|
||||
|
||||
finally:
|
||||
// Clean up and switch back.
|
||||
_PyXI_Exit(&session);
|
||||
_PyXI_Exit(session);
|
||||
|
||||
// Propagate any exception out to the caller.
|
||||
assert(!PyErr_Occurred());
|
||||
if (res < 0) {
|
||||
PyObject *excinfo = _PyXI_ApplyCapturedException(&session);
|
||||
PyObject *excinfo = _PyXI_ApplyCapturedException(session);
|
||||
if (excinfo != NULL) {
|
||||
*p_excinfo = excinfo;
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(!_PyXI_HasCapturedException(&session));
|
||||
assert(!_PyXI_HasCapturedException(session));
|
||||
}
|
||||
|
||||
_PyXI_FreeSession(session);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -824,22 +836,27 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
}
|
||||
}
|
||||
|
||||
_PyXI_session session = {0};
|
||||
_PyXI_session *session = _PyXI_NewSession();
|
||||
if (session == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Prep and switch interpreters, including apply the updates.
|
||||
if (_PyXI_Enter(&session, interp, updates) < 0) {
|
||||
if (_PyXI_Enter(session, interp, updates) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
_PyXI_ApplyCapturedException(&session);
|
||||
_PyXI_ApplyCapturedException(session);
|
||||
assert(PyErr_Occurred());
|
||||
}
|
||||
else {
|
||||
assert(!_PyXI_HasCapturedException(&session));
|
||||
assert(!_PyXI_HasCapturedException(session));
|
||||
}
|
||||
_PyXI_FreeSession(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Clean up and switch back.
|
||||
_PyXI_Exit(&session);
|
||||
_PyXI_Exit(session);
|
||||
_PyXI_FreeSession(session);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue