bpo-38858: Fix Py_Finalize() when called from a subinterpreter (GH-17297)

Use _Py_IsMainInterpreter() in Py_Initialize() and Py_Finalize() to
detect if the current interpreter is the main interpreter or not.
This commit is contained in:
Victor Stinner 2019-11-20 18:39:12 +01:00 committed by GitHub
parent de148f263f
commit b93f31fcd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 18 additions and 11 deletions

View File

@ -558,9 +558,10 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
static PyStatus static PyStatus
pycore_init_types(PyThreadState *tstate, int is_main_interp) pycore_init_types(PyThreadState *tstate)
{ {
PyStatus status; PyStatus status;
int is_main_interp = _Py_IsMainInterpreter(tstate);
status = _PyGC_Init(tstate); status = _PyGC_Init(tstate);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
@ -576,7 +577,9 @@ pycore_init_types(PyThreadState *tstate, int is_main_interp)
if (!_PyLong_Init()) { if (!_PyLong_Init()) {
return _PyStatus_ERR("can't init longs"); return _PyStatus_ERR("can't init longs");
} }
}
if (is_main_interp) {
status = _PyUnicode_Init(); status = _PyUnicode_Init();
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
@ -696,7 +699,7 @@ pyinit_config(_PyRuntimeState *runtime,
config = &tstate->interp->config; config = &tstate->interp->config;
*tstate_p = tstate; *tstate_p = tstate;
status = pycore_init_types(tstate, 1); status = pycore_init_types(tstate);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
@ -1179,6 +1182,9 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp)
_PySet_Fini(); _PySet_Fini();
_PyBytes_Fini(); _PyBytes_Fini();
_PyLong_Fini(); _PyLong_Fini();
}
if (is_main_interp) {
_PyFloat_Fini(); _PyFloat_Fini();
_PyDict_Fini(); _PyDict_Fini();
_PySlice_Fini(); _PySlice_Fini();
@ -1200,8 +1206,10 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp)
static void static void
finalize_interp_clear(PyThreadState *tstate, int is_main_interp) finalize_interp_clear(PyThreadState *tstate)
{ {
int is_main_interp = _Py_IsMainInterpreter(tstate);
/* Clear interpreter state and all thread states */ /* Clear interpreter state and all thread states */
PyInterpreterState_Clear(tstate->interp); PyInterpreterState_Clear(tstate->interp);
@ -1224,9 +1232,9 @@ finalize_interp_clear(PyThreadState *tstate, int is_main_interp)
static void static void
finalize_interp_delete(PyThreadState *tstate, int is_main_interp) finalize_interp_delete(PyThreadState *tstate)
{ {
if (is_main_interp) { if (_Py_IsMainInterpreter(tstate)) {
/* Cleanup auto-thread-state */ /* Cleanup auto-thread-state */
_PyGILState_Fini(tstate); _PyGILState_Fini(tstate);
} }
@ -1388,9 +1396,8 @@ Py_FinalizeEx(void)
} }
#endif /* Py_TRACE_REFS */ #endif /* Py_TRACE_REFS */
finalize_interp_clear(tstate, 1); finalize_interp_clear(tstate);
finalize_interp_delete(tstate);
finalize_interp_delete(tstate, 1);
#ifdef Py_TRACE_REFS #ifdef Py_TRACE_REFS
/* Display addresses (& refcnts) of all objects still alive. /* Display addresses (& refcnts) of all objects still alive.
@ -1482,7 +1489,7 @@ new_interpreter(PyThreadState **tstate_p)
} }
config = &interp->config; config = &interp->config;
status = pycore_init_types(tstate, 0); status = pycore_init_types(tstate);
/* XXX The following is lax in error checking */ /* XXX The following is lax in error checking */
PyObject *modules = PyDict_New(); PyObject *modules = PyDict_New();
@ -1634,8 +1641,8 @@ Py_EndInterpreter(PyThreadState *tstate)
} }
_PyImport_Cleanup(tstate); _PyImport_Cleanup(tstate);
finalize_interp_clear(tstate, 0); finalize_interp_clear(tstate);
finalize_interp_delete(tstate, 0); finalize_interp_delete(tstate);
} }
/* Add the __main__ module */ /* Add the __main__ module */