Skip to content

Commit 99b7a48

Browse files
Add _PyXI_session_result.
1 parent 98f3ddf commit 99b7a48

File tree

3 files changed

+140
-109
lines changed

3 files changed

+140
-109
lines changed

Include/internal/pycore_crossinterp.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,17 +350,19 @@ typedef struct xi_session _PyXI_session;
350350
PyAPI_FUNC(_PyXI_session *) _PyXI_NewSession(void);
351351
PyAPI_FUNC(void) _PyXI_FreeSession(_PyXI_session *);
352352

353+
typedef struct {
354+
PyObject *excinfo;
355+
} _PyXI_session_result;
356+
353357
PyAPI_FUNC(int) _PyXI_Enter(
354358
_PyXI_session *session,
355359
PyInterpreterState *interp,
356-
PyObject *nsupdates);
357-
PyAPI_FUNC(void) _PyXI_Exit(_PyXI_session *session);
360+
PyObject *nsupdates,
361+
_PyXI_session_result *);
362+
PyAPI_FUNC(int) _PyXI_Exit(_PyXI_session *, _PyXI_session_result *);
358363

359364
PyAPI_FUNC(PyObject *) _PyXI_GetMainNamespace(_PyXI_session *);
360365

361-
PyAPI_FUNC(PyObject *) _PyXI_ApplyCapturedException(_PyXI_session *session);
362-
PyAPI_FUNC(int) _PyXI_HasCapturedException(_PyXI_session *session);
363-
364366

365367
/*************/
366368
/* other API */

Modules/_interpretersmodule.c

Lines changed: 32 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ _run_script(_PyXIData_t *script, PyObject *ns)
441441
static int
442442
_exec_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
443443
_PyXIData_t *script, PyObject *shareables,
444-
PyObject **p_excinfo)
444+
_PyXI_session_result *result)
445445
{
446446
assert(!_PyErr_Occurred(tstate));
447447
_PyXI_session *session = _PyXI_NewSession();
@@ -450,19 +450,9 @@ _exec_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
450450
}
451451

452452
// Prep and switch interpreters.
453-
if (_PyXI_Enter(session, interp, shareables) < 0) {
454-
if (_PyErr_Occurred(tstate)) {
455-
// If an error occured at this step, it means that interp
456-
// was not prepared and switched.
457-
_PyXI_FreeSession(session);
458-
return -1;
459-
}
460-
// Now, apply the error from another interpreter:
461-
PyObject *excinfo = _PyXI_ApplyCapturedException(session);
462-
if (excinfo != NULL) {
463-
*p_excinfo = excinfo;
464-
}
465-
assert(PyErr_Occurred());
453+
if (_PyXI_Enter(session, interp, shareables, result) < 0) {
454+
// If an error occured at this step, it means that interp
455+
// was not prepared and switched.
466456
_PyXI_FreeSession(session);
467457
return -1;
468458
}
@@ -477,20 +467,7 @@ _exec_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
477467

478468
finally:
479469
// Clean up and switch back.
480-
_PyXI_Exit(session);
481-
482-
// Propagate any exception out to the caller.
483-
assert(!PyErr_Occurred());
484-
if (res < 0) {
485-
PyObject *excinfo = _PyXI_ApplyCapturedException(session);
486-
if (excinfo != NULL) {
487-
*p_excinfo = excinfo;
488-
}
489-
}
490-
else {
491-
assert(!_PyXI_HasCapturedException(session));
492-
}
493-
470+
(void)_PyXI_Exit(session, result);
494471
_PyXI_FreeSession(session);
495472
return res;
496473
}
@@ -842,21 +819,23 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs)
842819
}
843820

844821
// Prep and switch interpreters, including apply the updates.
845-
if (_PyXI_Enter(session, interp, updates) < 0) {
846-
if (!PyErr_Occurred()) {
847-
_PyXI_ApplyCapturedException(session);
848-
assert(PyErr_Occurred());
849-
}
850-
else {
851-
assert(!_PyXI_HasCapturedException(session));
852-
}
822+
if (_PyXI_Enter(session, interp, updates, NULL) < 0) {
853823
_PyXI_FreeSession(session);
854824
return NULL;
855825
}
856826

857827
// Clean up and switch back.
858-
_PyXI_Exit(session);
828+
assert(!PyErr_Occurred());
829+
int res = _PyXI_Exit(session, NULL);
859830
_PyXI_FreeSession(session);
831+
assert(res == 0);
832+
if (res < 0) {
833+
// unreachable
834+
if (!PyErr_Occurred()) {
835+
PyErr_SetString(PyExc_RuntimeError, "unresolved error");
836+
}
837+
return NULL;
838+
}
860839

861840
Py_RETURN_NONE;
862841
}
@@ -918,12 +897,12 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
918897
return NULL;
919898
}
920899

921-
PyObject *excinfo = NULL;
922-
int res = _exec_in_interpreter(tstate, interp, &xidata, shared, &excinfo);
900+
_PyXI_session_result result = {0};
901+
int res = _exec_in_interpreter(tstate, interp, &xidata, shared, &result);
923902
_PyXIData_Release(&xidata);
924903
if (res < 0) {
925-
assert((excinfo == NULL) != (PyErr_Occurred() == NULL));
926-
return excinfo;
904+
assert((result.excinfo == NULL) != (PyErr_Occurred() == NULL));
905+
return result.excinfo;
927906
}
928907
Py_RETURN_NONE;
929908
#undef FUNCNAME
@@ -981,12 +960,12 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
981960
return NULL;
982961
}
983962

984-
PyObject *excinfo = NULL;
985-
int res = _exec_in_interpreter(tstate, interp, &xidata, shared, &excinfo);
963+
_PyXI_session_result result = {0};
964+
int res = _exec_in_interpreter(tstate, interp, &xidata, shared, &result);
986965
_PyXIData_Release(&xidata);
987966
if (res < 0) {
988-
assert((excinfo == NULL) != (PyErr_Occurred() == NULL));
989-
return excinfo;
967+
assert((result.excinfo == NULL) != (PyErr_Occurred() == NULL));
968+
return result.excinfo;
990969
}
991970
Py_RETURN_NONE;
992971
#undef FUNCNAME
@@ -1043,12 +1022,12 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
10431022
return NULL;
10441023
}
10451024

1046-
PyObject *excinfo = NULL;
1047-
int res = _exec_in_interpreter(tstate, interp, &xidata, shared, &excinfo);
1025+
_PyXI_session_result result = {0};
1026+
int res = _exec_in_interpreter(tstate, interp, &xidata, shared, &result);
10481027
_PyXIData_Release(&xidata);
10491028
if (res < 0) {
1050-
assert((excinfo == NULL) != (PyErr_Occurred() == NULL));
1051-
return excinfo;
1029+
assert((result.excinfo == NULL) != (PyErr_Occurred() == NULL));
1030+
return result.excinfo;
10521031
}
10531032
Py_RETURN_NONE;
10541033
#undef FUNCNAME
@@ -1104,12 +1083,12 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
11041083
return NULL;
11051084
}
11061085

1107-
PyObject *excinfo = NULL;
1108-
int res = _exec_in_interpreter(tstate, interp, &xidata, NULL, &excinfo);
1086+
_PyXI_session_result result = {0};
1087+
int res = _exec_in_interpreter(tstate, interp, &xidata, NULL, &result);
11091088
_PyXIData_Release(&xidata);
11101089
if (res < 0) {
1111-
assert((excinfo == NULL) != (PyErr_Occurred() == NULL));
1112-
return excinfo;
1090+
assert((result.excinfo == NULL) != (PyErr_Occurred() == NULL));
1091+
return result.excinfo;
11131092
}
11141093
Py_RETURN_NONE;
11151094
#undef FUNCNAME

0 commit comments

Comments
 (0)