diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-06-19 22:05:23 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-19 22:05:23 (GMT) |
commit | b45d259bdda1de2b2d369458a9ad2e4d6f750687 (patch) | |
tree | 7e4b308f1729b757ebead804cde061bb06832cab /Python | |
parent | 35068bd059a3d9bff084ca9dcb04d51185b9ec3b (diff) | |
download | cpython-b45d259bdda1de2b2d369458a9ad2e4d6f750687.zip cpython-b45d259bdda1de2b2d369458a9ad2e4d6f750687.tar.gz cpython-b45d259bdda1de2b2d369458a9ad2e4d6f750687.tar.bz2 |
bpo-36710: Use tstate in pylifecycle.c (GH-14249)
In pylifecycle.c: pass tstate argument, rather than interp argument,
to functions.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bltinmodule.c | 4 | ||||
-rw-r--r-- | Python/import.c | 9 | ||||
-rw-r--r-- | Python/pylifecycle.c | 187 | ||||
-rw-r--r-- | Python/pystate.c | 7 | ||||
-rw-r--r-- | Python/sysmodule.c | 4 |
5 files changed, 111 insertions, 100 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index c3e3059..ae2a518 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2769,11 +2769,11 @@ static struct PyModuleDef builtinsmodule = { PyObject * -_PyBuiltin_Init(void) +_PyBuiltin_Init(PyThreadState *tstate) { PyObject *mod, *dict, *debug; - const PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; + const PyConfig *config = &tstate->interp->config; if (PyType_Ready(&PyFilter_Type) < 0 || PyType_Ready(&PyMap_Type) < 0 || diff --git a/Python/import.c b/Python/import.c index dc0d5b8..3937fbe 100644 --- a/Python/import.c +++ b/Python/import.c @@ -48,8 +48,9 @@ module _imp /* Initialize things */ PyStatus -_PyImport_Init(PyInterpreterState *interp) +_PyImport_Init(PyThreadState *tstate) { + PyInterpreterState *interp = tstate->interp; interp->builtins_copy = PyDict_Copy(interp->builtins); if (interp->builtins_copy == NULL) { return _PyStatus_ERR("Can't backup builtins dict"); @@ -58,7 +59,7 @@ _PyImport_Init(PyInterpreterState *interp) } PyStatus -_PyImportHooks_Init(void) +_PyImportHooks_Init(PyThreadState *tstate) { PyObject *v, *path_hooks = NULL; int err = 0; @@ -89,7 +90,7 @@ _PyImportHooks_Init(void) return _PyStatus_OK(); error: - PyErr_Print(); + _PyErr_Print(tstate); return _PyStatus_ERR("initializing sys.meta_path, sys.path_hooks, " "or path_importer_cache failed"); } @@ -554,7 +555,7 @@ _PyImport_Cleanup(PyThreadState *tstate) } Py_XDECREF(dict); /* Clear module dict copies stored in the interpreter state */ - _PyInterpreterState_ClearModules(tstate->interp); + _PyInterpreterState_ClearModules(interp); /* Collect references */ _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index c0b3450..10765da 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -11,6 +11,7 @@ #include "pycore_fileutils.h" #include "pycore_hamt.h" #include "pycore_pathconfig.h" +#include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" #include "pycore_pymem.h" #include "pycore_pystate.h" @@ -60,13 +61,13 @@ extern "C" { extern grammar _PyParser_Grammar; /* From graminit.c */ -/* Forward */ +/* Forward declarations */ static PyStatus add_main_module(PyInterpreterState *interp); -static PyStatus init_import_size(void); -static PyStatus init_sys_streams(PyInterpreterState *interp); -static PyStatus init_signals(void); -static void call_py_exitfuncs(PyInterpreterState *); -static void wait_for_thread_shutdown(void); +static PyStatus init_import_site(void); +static PyStatus init_sys_streams(PyThreadState *tstate); +static PyStatus init_signals(PyThreadState *tstate); +static void call_py_exitfuncs(PyThreadState *tstate); +static void wait_for_thread_shutdown(PyThreadState *tstate); static void call_ll_exitfuncs(_PyRuntimeState *runtime); int _Py_UnhandledKeyboardInterrupt = 0; @@ -147,11 +148,12 @@ Py_IsInitialized(void) */ static PyStatus -init_importlib(PyInterpreterState *interp, PyObject *sysmod) +init_importlib(PyThreadState *tstate, PyObject *sysmod) { PyObject *importlib; PyObject *impmod; PyObject *value; + PyInterpreterState *interp = tstate->interp; int verbose = interp->config.verbose; /* Import _importlib through its frozen version, _frozen_importlib. */ @@ -188,7 +190,7 @@ init_importlib(PyInterpreterState *interp, PyObject *sysmod) /* Install importlib as the implementation of import */ value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); if (value == NULL) { - PyErr_Print(); + _PyErr_Print(tstate); return _PyStatus_ERR("importlib install failed"); } Py_DECREF(value); @@ -204,7 +206,7 @@ init_importlib_external(PyThreadState *tstate) value = PyObject_CallMethod(tstate->interp->importlib, "_install_external_importers", ""); if (value == NULL) { - PyErr_Print(); + _PyErr_Print(tstate); return _PyStatus_ERR("external importer setup failed"); } Py_DECREF(value); @@ -449,7 +451,7 @@ _Py_SetLocaleFromEnv(int category) static PyStatus pyinit_core_reconfigure(_PyRuntimeState *runtime, - PyInterpreterState **interp_p, + PyThreadState **tstate_p, const PyConfig *config) { PyStatus status; @@ -457,12 +459,12 @@ pyinit_core_reconfigure(_PyRuntimeState *runtime, if (!tstate) { return _PyStatus_ERR("failed to read thread state"); } + *tstate_p = tstate; PyInterpreterState *interp = tstate->interp; if (interp == NULL) { return _PyStatus_ERR("can't make main interpreter"); } - *interp_p = interp; _PyConfig_Write(config, runtime); @@ -519,23 +521,22 @@ pycore_init_runtime(_PyRuntimeState *runtime, static PyStatus pycore_create_interpreter(_PyRuntimeState *runtime, const PyConfig *config, - PyInterpreterState **interp_p) + PyThreadState **tstate_p) { PyInterpreterState *interp = PyInterpreterState_New(); if (interp == NULL) { return _PyStatus_ERR("can't make main interpreter"); } - *interp_p = interp; PyStatus status = _PyConfig_Copy(&interp->config, config); if (_PyStatus_EXCEPTION(status)) { return status; } - config = &interp->config; PyThreadState *tstate = PyThreadState_New(interp); - if (tstate == NULL) + if (tstate == NULL) { return _PyStatus_ERR("can't make first thread"); + } (void) PyThreadState_Swap(tstate); /* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because @@ -546,11 +547,12 @@ pycore_create_interpreter(_PyRuntimeState *runtime, _PyEval_FiniThreads(&runtime->ceval); /* Auto-thread-state API */ - _PyGILState_Init(runtime, interp, tstate); + _PyGILState_Init(runtime, tstate); /* Create the GIL */ PyEval_InitThreads(); + *tstate_p = tstate; return _PyStatus_OK(); } @@ -599,9 +601,11 @@ pycore_init_types(void) static PyStatus -pycore_init_builtins(PyInterpreterState *interp) +pycore_init_builtins(PyThreadState *tstate) { - PyObject *bimod = _PyBuiltin_Init(); + PyInterpreterState *interp = tstate->interp; + + PyObject *bimod = _PyBuiltin_Init(tstate); if (bimod == NULL) { return _PyStatus_ERR("can't initialize builtins modules"); } @@ -622,14 +626,16 @@ pycore_init_builtins(PyInterpreterState *interp) static PyStatus -pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) +pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod) { - PyStatus status = _PyImport_Init(interp); + const PyConfig *config = &tstate->interp->config; + + PyStatus status = _PyImport_Init(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - status = _PyImportHooks_Init(); + status = _PyImportHooks_Init(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -639,16 +645,16 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) return _PyStatus_ERR("can't initialize warnings"); } - if (interp->config._install_importlib) { - status = _PyConfig_SetPathConfig(&interp->config); + if (config->_install_importlib) { + status = _PyConfig_SetPathConfig(config); if (_PyStatus_EXCEPTION(status)) { return status; } } /* This call sets up builtin and frozen import support */ - if (interp->config._install_importlib) { - status = init_importlib(interp, sysmod); + if (config->_install_importlib) { + status = init_importlib(tstate, sysmod); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -659,11 +665,9 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) static PyStatus pyinit_config(_PyRuntimeState *runtime, - PyInterpreterState **interp_p, + PyThreadState **tstate_p, const PyConfig *config) { - PyInterpreterState *interp; - _PyConfig_Write(config, runtime); PyStatus status = pycore_init_runtime(runtime, config); @@ -671,12 +675,13 @@ pyinit_config(_PyRuntimeState *runtime, return status; } - status = pycore_create_interpreter(runtime, config, &interp); + PyThreadState *tstate; + status = pycore_create_interpreter(runtime, config, &tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - config = &interp->config; - *interp_p = interp; + config = &tstate->interp->config; + *tstate_p = tstate; status = pycore_init_types(); if (_PyStatus_EXCEPTION(status)) { @@ -684,17 +689,17 @@ pyinit_config(_PyRuntimeState *runtime, } PyObject *sysmod; - status = _PySys_Create(runtime, interp, &sysmod); + status = _PySys_Create(runtime, tstate, &sysmod); if (_PyStatus_EXCEPTION(status)) { return status; } - status = pycore_init_builtins(interp); + status = pycore_init_builtins(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - status = pycore_init_import_warnings(interp, sysmod); + status = pycore_init_import_warnings(tstate, sysmod); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -822,7 +827,7 @@ _Py_PreInitializeFromConfig(const PyConfig *config, static PyStatus pyinit_core(_PyRuntimeState *runtime, const PyConfig *src_config, - PyInterpreterState **interp_p) + PyThreadState **tstate_p) { PyStatus status; @@ -845,10 +850,10 @@ pyinit_core(_PyRuntimeState *runtime, } if (!runtime->core_initialized) { - status = pyinit_config(runtime, interp_p, &config); + status = pyinit_config(runtime, tstate_p, &config); } else { - status = pyinit_core_reconfigure(runtime, interp_p, &config); + status = pyinit_core_reconfigure(runtime, tstate_p, &config); } if (_PyStatus_EXCEPTION(status)) { goto done; @@ -893,14 +898,14 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) * non-zero return code. */ static PyStatus -pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) +pyinit_main(_PyRuntimeState *runtime, PyThreadState *tstate) { if (!runtime->core_initialized) { return _PyStatus_ERR("runtime core not initialized"); } /* Configure the main interpreter */ - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyInterpreterState *interp = tstate->interp; PyConfig *config = &interp->config; if (runtime->initialized) { @@ -936,13 +941,13 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) return status; } - status = _PyUnicode_InitEncodings(interp); + status = _PyUnicode_InitEncodings(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } if (config->install_signal_handlers) { - status = init_signals(); + status = init_signals(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -957,7 +962,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) return status; } - status = init_sys_streams(interp); + status = init_sys_streams(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -969,7 +974,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) PyObject *warnings_module = PyImport_ImportModule("warnings"); if (warnings_module == NULL) { fprintf(stderr, "'import warnings' failed; traceback:\n"); - PyErr_Print(); + _PyErr_Print(tstate); } Py_XDECREF(warnings_module); } @@ -977,7 +982,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) runtime->initialized = 1; if (config->site_import) { - status = init_import_size(); /* Module site */ + status = init_import_site(); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -999,9 +1004,8 @@ _Py_InitializeMain(void) return status; } _PyRuntimeState *runtime = &_PyRuntime; - PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; - - return pyinit_main(runtime, interp); + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + return pyinit_main(runtime, tstate); } @@ -1020,15 +1024,15 @@ Py_InitializeFromConfig(const PyConfig *config) } _PyRuntimeState *runtime = &_PyRuntime; - PyInterpreterState *interp = NULL; - status = pyinit_core(runtime, config, &interp); + PyThreadState *tstate = NULL; + status = pyinit_core(runtime, config, &tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - config = &interp->config; + config = &tstate->interp->config; if (config->_init_main) { - status = pyinit_main(runtime, interp); + status = pyinit_main(runtime, tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1148,16 +1152,16 @@ Py_FinalizeEx(void) return status; } + /* Get current thread state and interpreter pointer */ + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyInterpreterState *interp = tstate->interp; + // Wrap up existing "threading"-module-created, non-daemon threads. - wait_for_thread_shutdown(); + wait_for_thread_shutdown(tstate); // Make any remaining pending calls. _Py_FinishPendingCalls(runtime); - /* Get current thread state and interpreter pointer */ - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - PyInterpreterState *interp = tstate->interp; - /* The interpreter is still entirely intact at this point, and the * exit funcs may be relying on that. In particular, if some thread * or exit func is still waiting to do an import, the import machinery @@ -1168,7 +1172,7 @@ Py_FinalizeEx(void) * the threads created via Threading. */ - call_py_exitfuncs(interp); + call_py_exitfuncs(tstate); /* Copy the core config, PyInterpreterState_Delete() free the core config memory */ @@ -1462,7 +1466,7 @@ new_interpreter(PyThreadState **tstate_p) return _PyStatus_ERR("can't finish initializing sys"); } } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto handle_error; } @@ -1473,7 +1477,7 @@ new_interpreter(PyThreadState **tstate_p) goto handle_error; Py_INCREF(interp->builtins); } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto handle_error; } @@ -1488,12 +1492,12 @@ new_interpreter(PyThreadState **tstate_p) return status; } - status = _PyImportHooks_Init(); + status = _PyImportHooks_Init(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - status = init_importlib(interp, sysmod); + status = init_importlib(tstate, sysmod); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1503,12 +1507,12 @@ new_interpreter(PyThreadState **tstate_p) return status; } - status = _PyUnicode_InitEncodings(interp); + status = _PyUnicode_InitEncodings(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - status = init_sys_streams(interp); + status = init_sys_streams(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1519,14 +1523,14 @@ new_interpreter(PyThreadState **tstate_p) } if (config->site_import) { - status = init_import_size(); + status = init_import_site(); if (_PyStatus_EXCEPTION(status)) { return status; } } } - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { goto handle_error; } @@ -1575,19 +1579,22 @@ Py_EndInterpreter(PyThreadState *tstate) { PyInterpreterState *interp = tstate->interp; - if (tstate != _PyThreadState_GET()) + if (tstate != _PyThreadState_GET()) { Py_FatalError("Py_EndInterpreter: thread is not current"); - if (tstate->frame != NULL) + } + if (tstate->frame != NULL) { Py_FatalError("Py_EndInterpreter: thread still has a frame"); + } interp->finalizing = 1; // Wrap up existing "threading"-module-created, non-daemon threads. - wait_for_thread_shutdown(); + wait_for_thread_shutdown(tstate); - call_py_exitfuncs(interp); + call_py_exitfuncs(tstate); - if (tstate != interp->tstate_head || tstate->next != NULL) + if (tstate != interp->tstate_head || tstate->next != NULL) { Py_FatalError("Py_EndInterpreter: not the last thread"); + } _PyImport_Cleanup(tstate); PyInterpreterState_Clear(interp); @@ -1648,7 +1655,7 @@ add_main_module(PyInterpreterState *interp) /* Import the site module (not into __main__ though) */ static PyStatus -init_import_size(void) +init_import_site(void) { PyObject *m; m = PyImport_ImportModule("site"); @@ -1835,7 +1842,7 @@ error: /* Initialize sys.stdin, stdout, stderr and builtins.open */ static PyStatus -init_sys_streams(PyInterpreterState *interp) +init_sys_streams(PyThreadState *tstate) { PyObject *iomod = NULL, *wrapper; PyObject *bimod = NULL; @@ -1844,7 +1851,7 @@ init_sys_streams(PyInterpreterState *interp) int fd; PyObject * encoding_attr; PyStatus res = _PyStatus_OK(); - PyConfig *config = &interp->config; + const PyConfig *config = &tstate->interp->config; /* Check that stdin is not a directory Using shell redirection, you can redirect stdin to a directory, @@ -1935,7 +1942,7 @@ init_sys_streams(PyInterpreterState *interp) } Py_DECREF(encoding_attr); } - PyErr_Clear(); /* Not a fatal error if codec isn't available */ + _PyErr_Clear(tstate); /* Not a fatal error if codec isn't available */ if (PySys_SetObject("__stderr__", std) < 0) { Py_DECREF(std); @@ -1983,11 +1990,12 @@ _Py_FatalError_DumpTracebacks(int fd) static int _Py_FatalError_PrintExc(int fd) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *ferr, *res; PyObject *exception, *v, *tb; int has_tb; - PyErr_Fetch(&exception, &v, &tb); + _PyErr_Fetch(tstate, &exception, &v, &tb); if (exception == NULL) { /* No current exception */ return 0; @@ -2000,7 +2008,7 @@ _Py_FatalError_PrintExc(int fd) return 0; } - PyErr_NormalizeException(&exception, &v, &tb); + _PyErr_NormalizeException(tstate, &exception, &v, &tb); if (tb == NULL) { tb = Py_None; Py_INCREF(tb); @@ -2019,10 +2027,12 @@ _Py_FatalError_PrintExc(int fd) /* sys.stderr may be buffered: call sys.stderr.flush() */ res = _PyObject_CallMethodId(ferr, &PyId_flush, NULL); - if (res == NULL) - PyErr_Clear(); - else + if (res == NULL) { + _PyErr_Clear(tstate); + } + else { Py_DECREF(res); + } return has_tb; } @@ -2173,7 +2183,7 @@ Py_ExitStatusException(PyStatus status) /* For the atexit module. */ void _Py_PyAtExit(void (*func)(PyObject *), PyObject *module) { - PyInterpreterState *is = _PyInterpreterState_Get(); + PyInterpreterState *is = _PyInterpreterState_GET_UNSAFE(); /* Guard against API misuse (see bpo-17852) */ assert(is->pyexitfunc == NULL || is->pyexitfunc == func); @@ -2183,13 +2193,14 @@ void _Py_PyAtExit(void (*func)(PyObject *), PyObject *module) } static void -call_py_exitfuncs(PyInterpreterState *istate) +call_py_exitfuncs(PyThreadState *tstate) { - if (istate->pyexitfunc == NULL) + PyInterpreterState *interp = tstate->interp; + if (interp->pyexitfunc == NULL) return; - (*istate->pyexitfunc)(istate->pyexitmodule); - PyErr_Clear(); + (*interp->pyexitfunc)(interp->pyexitmodule); + _PyErr_Clear(tstate); } /* Wait until threading._shutdown completes, provided @@ -2197,13 +2208,13 @@ call_py_exitfuncs(PyInterpreterState *istate) The shutdown routine will wait until all non-daemon "threading" threads have completed. */ static void -wait_for_thread_shutdown(void) +wait_for_thread_shutdown(PyThreadState *tstate) { _Py_IDENTIFIER(_shutdown); PyObject *result; PyObject *threading = _PyImport_GetModuleId(&PyId_threading); if (threading == NULL) { - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { PyErr_WriteUnraisable(NULL); } /* else: threading not imported */ @@ -2255,7 +2266,7 @@ Py_Exit(int sts) } static PyStatus -init_signals(void) +init_signals(PyThreadState *tstate) { #ifdef SIGPIPE PyOS_setsig(SIGPIPE, SIG_IGN); @@ -2267,7 +2278,7 @@ init_signals(void) PyOS_setsig(SIGXFSZ, SIG_IGN); #endif PyOS_InitInterrupts(); /* May imply initsignal() */ - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { return _PyStatus_ERR("can't import signal"); } return _PyStatus_OK(); diff --git a/Python/pystate.c b/Python/pystate.c index 1e2b480..503b4bf 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1143,19 +1143,18 @@ PyThreadState_IsCurrent(PyThreadState *tstate) Py_Initialize/Py_FinalizeEx */ void -_PyGILState_Init(_PyRuntimeState *runtime, - PyInterpreterState *interp, PyThreadState *tstate) +_PyGILState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) { /* must init with valid states */ - assert(interp != NULL); assert(tstate != NULL); + assert(tstate->interp != NULL); struct _gilstate_runtime_state *gilstate = &runtime->gilstate; if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { Py_FatalError("Could not allocate TSS entry"); } - gilstate->autoInterpreterState = interp; + gilstate->autoInterpreterState = tstate->interp; assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL); assert(tstate->gilstate_counter == 0); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index fcbcb3b..8da839c 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -3036,10 +3036,10 @@ error: /* Create sys module without all attributes: _PySys_InitMain() should be called later to add remaining attributes. */ PyStatus -_PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, +_PySys_Create(_PyRuntimeState *runtime, PyThreadState *tstate, PyObject **sysmod_p) { - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyInterpreterState *interp = tstate->interp; PyObject *modules = PyDict_New(); if (modules == NULL) { |