[WIP] bpo-38865: Py_FinalizeEx() cannot be called in a subinterpreter by vstinner · Pull Request #19063 · python/cpython · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Doc/c-api/init.rst
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,9 @@ Build and C API Changes

Extension modules without module state (``m_size <= 0``) are not affected.

* :c:func:`Py_FinalizeEx` cannot be called in a subinterpreter anymore.
(Contributed by Victor Stinner in :issue:`38865`.)


Deprecated
==========
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:c:func:`Py_FinalizeEx` cannot be called in a subinterpreter anymore.
29 changes: 21 additions & 8 deletions Programs/_testembed.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,7 +1165,7 @@ static volatile int _audit_subinterpreter_interpreter_count = 0;

static int _audit_subinterpreter_hook(const char *event, PyObject *args, void *userdata)
{
printf("%s\n", event);
fprintf(stderr, "audit event: %s\n", event);
if (strcmp(event, "cpython.PyInterpreterState_New") == 0) {
_audit_subinterpreter_interpreter_count += 1;
}
Expand All @@ -1178,17 +1178,30 @@ static int test_audit_subinterpreter(void)
PySys_AddAuditHook(_audit_subinterpreter_hook, NULL);
_testembed_Py_Initialize();

Py_NewInterpreter();
Py_NewInterpreter();
Py_NewInterpreter();
PyThreadState *mainstate = PyThreadState_Get();

for (int i=0; i<3; i++) {
PyThreadState *substate = Py_NewInterpreter();
if (substate == NULL) {
fprintf(stderr, "Py_NewInterpreter() failed\n");
return 1;
}
Py_EndInterpreter(substate);

/* Restore tstate after each Py_EndInterpreter() call. Otherwise the
current Python thread state is NULL and so PySys_Audit() does
nothing. */
PyThreadState_Swap(mainstate);
}

Py_Finalize();

switch (_audit_subinterpreter_interpreter_count) {
case 3: return 0;
case 0: return -1;
default: return _audit_subinterpreter_interpreter_count;
printf("audit subinterpreter count: %i\n",
_audit_subinterpreter_interpreter_count);
if (_audit_subinterpreter_interpreter_count != 3) {
return 2;
}
return 0;
}

typedef struct {
Expand Down
4 changes: 4 additions & 0 deletions Python/pylifecycle.c