From 0a28f8d379544eee897979da0ce99f0b449b49dd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 19 Jun 2019 02:54:39 +0200 Subject: [PATCH] bpo-36710: Add tstate parameter in import.c (GH-14218) * Add 'tstate' parameter to many internal import.c functions. * _PyImportZip_Init() now gets 'tstate' parameter rather than 'interp'. * Add 'interp' parameter to _PyState_ClearModules() and rename it to _PyInterpreterState_ClearModules(). * Move private _PyImport_FindBuiltin() to the internal C API; add 'tstate' parameter to it. * Remove private _PyImport_AddModuleObject() from the C API: use public PyImport_AddModuleObject() instead. * Remove private _PyImport_FindExtensionObjectEx() from the C API: use private _PyImport_FindExtensionObject() instead. --- Include/cpython/import.h | 9 +- Include/cpython/pystate.h | 1 - Include/internal/pycore_import.h | 5 + Include/internal/pycore_pylifecycle.h | 2 +- Include/internal/pycore_pystate.h | 3 + Python/import.c | 364 +++++++++++++++----------- Python/pylifecycle.c | 15 +- Python/pystate.c | 40 +-- 8 files changed, 248 insertions(+), 191 deletions(-) diff --git a/Include/cpython/import.h b/Include/cpython/import.h index 8dd7a0c5a4d..c1b47121f12 100644 --- a/Include/cpython/import.h +++ b/Include/cpython/import.h @@ -11,21 +11,14 @@ PyMODINIT_FUNC PyInit__imp(void); PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *); PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(struct _Py_Identifier *name); -PyAPI_FUNC(PyObject *) _PyImport_AddModuleObject(PyObject *name, - PyObject *modules); PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module); PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); PyAPI_FUNC(void) _PyImport_AcquireLock(void); PyAPI_FUNC(int) _PyImport_ReleaseLock(void); -PyAPI_FUNC(PyObject *) _PyImport_FindBuiltin( - const char *name, /* UTF-8 encoded string */ - PyObject *modules - ); PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObject(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObjectEx(PyObject *, PyObject *, - PyObject *); + PyAPI_FUNC(int) _PyImport_FixupBuiltin( PyObject *mod, const char *name, /* UTF-8 encoded string */ diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 94b0809cd4f..f8723517803 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -148,7 +148,6 @@ struct _ts { PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void); PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); -PyAPI_FUNC(void) _PyState_ClearModules(void); PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); /* Similar to PyThreadState_Get(), but don't issue a fatal error diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index 6b728242aad..bbcd170ab13 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -5,6 +5,11 @@ extern "C" { #endif +PyAPI_FUNC(PyObject *) _PyImport_FindBuiltin( + PyThreadState *tstate, + const char *name /* UTF-8 encoded string */ + ); + extern void _PyImport_ReInitLock(void); #ifdef __cplusplus diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 6bfadd49eef..1c475b1b118 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -55,7 +55,7 @@ extern int _PyFloat_Init(void); extern PyStatus _Py_HashRandomization_Init(const PyConfig *); extern PyStatus _PyTypes_Init(void); -extern PyStatus _PyImportZip_Init(PyInterpreterState *interp); +extern PyStatus _PyImportZip_Init(PyThreadState *tstate); /* Various internal finalizers */ diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 3ab4009770c..3bfbc272ee1 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -310,6 +310,9 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); +/* Used by PyImport_Cleanup() */ +extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp); + PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime); #ifdef __cplusplus diff --git a/Python/import.c b/Python/import.c index ab7db6bc17f..5606d3bea45 100644 --- a/Python/import.c +++ b/Python/import.c @@ -4,6 +4,7 @@ #include "Python-ast.h" #undef Yield /* undefine macro conflicting with */ +#include "pycore_pyerrors.h" #include "pycore_pyhash.h" #include "pycore_pylifecycle.h" #include "pycore_pymem.h" @@ -25,6 +26,9 @@ extern "C" { #define CACHEDIR "__pycache__" +/* Forward references */ +static PyObject *import_add_module(PyThreadState *tstate, PyObject *name); + /* See _PyImport_FixupExtensionObject() below */ static PyObject *extensions = NULL; @@ -91,25 +95,26 @@ _PyImportHooks_Init(void) } PyStatus -_PyImportZip_Init(PyInterpreterState *interp) +_PyImportZip_Init(PyThreadState *tstate) { PyObject *path_hooks, *zipimport; int err = 0; path_hooks = PySys_GetObject("path_hooks"); if (path_hooks == NULL) { - PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path_hooks"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "unable to get sys.path_hooks"); goto error; } - int verbose = interp->config.verbose; + int verbose = tstate->interp->config.verbose; if (verbose) { PySys_WriteStderr("# installing zipimport hook\n"); } zipimport = PyImport_ImportModule("zipimport"); if (zipimport == NULL) { - PyErr_Clear(); /* No zip import module -- okay */ + _PyErr_Clear(tstate); /* No zip import module -- okay */ if (verbose) { PySys_WriteStderr("# can't import zipimport\n"); } @@ -120,7 +125,7 @@ _PyImportZip_Init(PyInterpreterState *interp) &PyId_zipimporter); Py_DECREF(zipimport); if (zipimporter == NULL) { - PyErr_Clear(); /* No zipimporter object -- okay */ + _PyErr_Clear(tstate); /* No zipimporter object -- okay */ if (verbose) { PySys_WriteStderr("# can't import zipimport.zipimporter\n"); } @@ -341,26 +346,30 @@ _PyImport_GetModuleId(struct _Py_Identifier *nameid) int _PyImport_SetModule(PyObject *name, PyObject *m) { - PyObject *modules = PyImport_GetModuleDict(); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *modules = tstate->interp->modules; return PyObject_SetItem(modules, name, m); } int _PyImport_SetModuleString(const char *name, PyObject *m) { - PyObject *modules = PyImport_GetModuleDict(); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *modules = tstate->interp->modules; return PyMapping_SetItemString(modules, name, m); } -PyObject * -PyImport_GetModule(PyObject *name) +static PyObject * +import_get_module(PyThreadState *tstate, PyObject *name) { - PyObject *m; - PyObject *modules = PyImport_GetModuleDict(); + PyObject *modules = tstate->interp->modules; if (modules == NULL) { - PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "unable to get sys.modules"); return NULL; } + + PyObject *m; Py_INCREF(modules); if (PyDict_CheckExact(modules)) { m = PyDict_GetItemWithError(modules, name); /* borrowed */ @@ -368,8 +377,8 @@ PyImport_GetModule(PyObject *name) } else { m = PyObject_GetItem(modules, name); - if (m == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { - PyErr_Clear(); + if (m == NULL && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + _PyErr_Clear(tstate); } } Py_DECREF(modules); @@ -377,6 +386,14 @@ PyImport_GetModule(PyObject *name) } +PyObject * +PyImport_GetModule(PyObject *name) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return import_get_module(tstate, name); +} + + /* List of names to clear in sys */ static const char * const sys_deletes[] = { "path", "argv", "ps1", "ps2", @@ -398,15 +415,13 @@ static const char * const sys_files[] = { void PyImport_Cleanup(void) { - Py_ssize_t pos; - PyObject *key, *value, *dict; - PyInterpreterState *interp = _PyInterpreterState_Get(); - PyObject *modules = PyImport_GetModuleDict(); - PyObject *weaklist = NULL; - const char * const *p; - - if (modules == NULL) - return; /* Already done */ + PyThreadState *tstate = _PyThreadState_GET(); + PyInterpreterState *interp = tstate->interp; + PyObject *modules = interp->modules; + if (modules == NULL) { + /* Already done */ + return; + } /* Delete some special variables first. These are common places where user values hide and people complain when their @@ -424,6 +439,7 @@ PyImport_Cleanup(void) PyErr_WriteUnraisable(NULL); } + const char * const *p; for (p = sys_deletes; *p != NULL; p++) { if (verbose) { PySys_WriteStderr("# clear sys.%s\n", *p); @@ -436,9 +452,10 @@ PyImport_Cleanup(void) if (verbose) { PySys_WriteStderr("# restore sys.%s\n", *p); } - value = _PyDict_GetItemStringWithError(interp->sysdict, *(p+1)); + PyObject *value = _PyDict_GetItemStringWithError(interp->sysdict, + *(p+1)); if (value == NULL) { - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { PyErr_WriteUnraisable(NULL); } value = Py_None; @@ -452,7 +469,7 @@ PyImport_Cleanup(void) modules when they are removed from sys.modules. The name is used for diagnosis messages (in verbose mode), while the weakref helps detect those modules which have been held alive. */ - weaklist = PyList_New(0); + PyObject *weaklist = PyList_New(0); if (weaklist == NULL) { PyErr_WriteUnraisable(NULL); } @@ -486,7 +503,8 @@ PyImport_Cleanup(void) /* Remove all modules from sys.modules, hoping that garbage collection can reclaim most of them. */ if (PyDict_CheckExact(modules)) { - pos = 0; + Py_ssize_t pos = 0; + PyObject *key, *value; while (PyDict_Next(modules, &pos, &key, &value)) { CLEAR_MODULE(key, value); } @@ -497,8 +515,9 @@ PyImport_Cleanup(void) PyErr_WriteUnraisable(NULL); } else { + PyObject *key; while ((key = PyIter_Next(iterator))) { - value = PyObject_GetItem(modules, key); + PyObject *value = PyObject_GetItem(modules, key); if (value == NULL) { PyErr_WriteUnraisable(NULL); continue; @@ -526,17 +545,17 @@ PyImport_Cleanup(void) } /* Restore the original builtins dict, to ensure that any user data gets cleared. */ - dict = PyDict_Copy(interp->builtins); + PyObject *dict = PyDict_Copy(interp->builtins); if (dict == NULL) { PyErr_WriteUnraisable(NULL); } PyDict_Clear(interp->builtins); if (PyDict_Update(interp->builtins, interp->builtins_copy)) { - PyErr_Clear(); + _PyErr_Clear(tstate); } Py_XDECREF(dict); /* Clear module dict copies stored in the interpreter state */ - _PyState_ClearModules(); + _PyInterpreterState_ClearModules(tstate->interp); /* Collect references */ _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings @@ -651,7 +670,7 @@ PyImport_GetMagicTag(void) int _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, - PyObject *filename, PyObject *modules) + PyObject *filename, PyObject *modules) { PyObject *dict, *key; struct PyModuleDef *def; @@ -713,33 +732,32 @@ _PyImport_FixupBuiltin(PyObject *mod, const char *name, PyObject *modules) return res; } -PyObject * -_PyImport_FindExtensionObject(PyObject *name, PyObject *filename) +static PyObject * +import_find_extension(PyThreadState *tstate, PyObject *name, + PyObject *filename) { - PyObject *modules = PyImport_GetModuleDict(); - return _PyImport_FindExtensionObjectEx(name, filename, modules); -} + if (extensions == NULL) { + return NULL; + } -PyObject * -_PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename, - PyObject *modules) -{ - PyObject *mod, *mdict, *key; - PyModuleDef* def; - if (extensions == NULL) + PyObject *key = PyTuple_Pack(2, filename, name); + if (key == NULL) { return NULL; - key = PyTuple_Pack(2, filename, name); - if (key == NULL) - return NULL; - def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); + } + PyModuleDef* def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); Py_DECREF(key); - if (def == NULL) + if (def == NULL) { return NULL; + } + + PyObject *mod, *mdict; + PyObject *modules = tstate->interp->modules; + if (def->m_size == -1) { /* Module does not support repeated initialization */ if (def->m_base.m_copy == NULL) return NULL; - mod = _PyImport_AddModuleObject(name, modules); + mod = import_add_module(tstate, name); if (mod == NULL) return NULL; mdict = PyModule_GetDict(mod); @@ -764,23 +782,31 @@ _PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename, PyMapping_DelItem(modules, name); return NULL; } - int verbose = _PyInterpreterState_Get()->config.verbose; + + int verbose = tstate->interp->config.verbose; if (verbose) { PySys_FormatStderr("import %U # previously loaded (%R)\n", name, filename); } return mod; - } PyObject * -_PyImport_FindBuiltin(const char *name, PyObject *modules) +_PyImport_FindExtensionObject(PyObject *name, PyObject *filename) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return import_find_extension(tstate, name, filename); +} + + +PyObject * +_PyImport_FindBuiltin(PyThreadState *tstate, const char *name) { PyObject *res, *nameobj; nameobj = PyUnicode_InternFromString(name); if (nameobj == NULL) return NULL; - res = _PyImport_FindExtensionObjectEx(nameobj, nameobj, modules); + res = import_find_extension(tstate, nameobj, nameobj); Py_DECREF(nameobj); return res; } @@ -791,16 +817,16 @@ _PyImport_FindBuiltin(const char *name, PyObject *modules) Because the former action is most common, THIS DOES NOT RETURN A 'NEW' REFERENCE! */ -PyObject * -PyImport_AddModuleObject(PyObject *name) +static PyObject * +import_add_module(PyThreadState *tstate, PyObject *name) { - PyObject *modules = PyImport_GetModuleDict(); - return _PyImport_AddModuleObject(name, modules); -} + PyObject *modules = tstate->interp->modules; + if (modules == NULL) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "no import module dictionary"); + return NULL; + } -PyObject * -_PyImport_AddModuleObject(PyObject *name, PyObject *modules) -{ PyObject *m; if (PyDict_CheckExact(modules)) { m = PyDict_GetItemWithError(modules, name); @@ -809,11 +835,11 @@ _PyImport_AddModuleObject(PyObject *name, PyObject *modules) m = PyObject_GetItem(modules, name); // For backward-comaptibility we copy the behavior // of PyDict_GetItemWithError(). - if (PyErr_ExceptionMatches(PyExc_KeyError)) { - PyErr_Clear(); + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + _PyErr_Clear(tstate); } } - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { return NULL; } if (m != NULL && PyModule_Check(m)) { @@ -831,14 +857,22 @@ _PyImport_AddModuleObject(PyObject *name, PyObject *modules) return m; } +PyObject * +PyImport_AddModuleObject(PyObject *name) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return import_add_module(tstate, name); +} + + PyObject * PyImport_AddModule(const char *name) { - PyObject *nameobj, *module; - nameobj = PyUnicode_FromString(name); - if (nameobj == NULL) + PyObject *nameobj = PyUnicode_FromString(name); + if (nameobj == NULL) { return NULL; - module = PyImport_AddModuleObject(nameobj); + } + PyObject *module = PyImport_AddModuleObject(nameobj); Py_DECREF(nameobj); return module; } @@ -846,20 +880,24 @@ PyImport_AddModule(const char *name) /* Remove name from sys.modules, if it's there. */ static void -remove_module(PyObject *name) +remove_module(PyThreadState *tstate, PyObject *name) { PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - PyObject *modules = PyImport_GetModuleDict(); + _PyErr_Fetch(tstate, &type, &value, &traceback); + + PyObject *modules = tstate->interp->modules; if (!PyMapping_HasKey(modules, name)) { goto out; } if (PyMapping_DelItem(modules, name) < 0) { - Py_FatalError("import: deleting existing key in " - "sys.modules failed"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "deleting key in sys.modules failed"); + _PyErr_ChainExceptions(type, value, traceback); + return; } + out: - PyErr_Restore(type, value, traceback); + _PyErr_Restore(tstate, type, value, traceback); } @@ -944,23 +982,23 @@ error: } static PyObject * -module_dict_for_exec(PyObject *name) +module_dict_for_exec(PyThreadState *tstate, PyObject *name) { _Py_IDENTIFIER(__builtins__); PyObject *m, *d = NULL; - m = PyImport_AddModuleObject(name); + m = import_add_module(tstate, name); if (m == NULL) return NULL; /* If the module is being reloaded, we get the old module back and re-use its dict to exec the new code. */ d = PyModule_GetDict(m); if (_PyDict_GetItemIdWithError(d, &PyId___builtins__) == NULL) { - if (PyErr_Occurred() || + if (_PyErr_Occurred(tstate) || _PyDict_SetItemId(d, &PyId___builtins__, PyEval_GetBuiltins()) != 0) { - remove_module(name); + remove_module(tstate, name); return NULL; } } @@ -969,22 +1007,23 @@ module_dict_for_exec(PyObject *name) } static PyObject * -exec_code_in_module(PyObject *name, PyObject *module_dict, PyObject *code_object) +exec_code_in_module(PyThreadState *tstate, PyObject *name, + PyObject *module_dict, PyObject *code_object) { PyObject *v, *m; v = PyEval_EvalCode(code_object, module_dict, module_dict); if (v == NULL) { - remove_module(name); + remove_module(tstate, name); return NULL; } Py_DECREF(v); - m = PyImport_GetModule(name); - if (m == NULL && !PyErr_Occurred()) { - PyErr_Format(PyExc_ImportError, - "Loaded module %R not found in sys.modules", - name); + m = import_get_module(tstate, name); + if (m == NULL && !_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_ImportError, + "Loaded module %R not found in sys.modules", + name); } return m; @@ -994,11 +1033,11 @@ PyObject* PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, PyObject *cpathname) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *d, *external, *res; - PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); _Py_IDENTIFIER(_fix_up_module); - d = module_dict_for_exec(name); + d = module_dict_for_exec(tstate, name); if (d == NULL) { return NULL; } @@ -1006,7 +1045,8 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, if (pathname == NULL) { pathname = ((PyCodeObject *)co)->co_filename; } - external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); + external = PyObject_GetAttrString(tstate->interp->importlib, + "_bootstrap_external"); if (external == NULL) return NULL; res = _PyObject_CallMethodIdObjArgs(external, @@ -1015,7 +1055,7 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, Py_DECREF(external); if (res != NULL) { Py_DECREF(res); - res = exec_code_in_module(name, d, co); + res = exec_code_in_module(tstate, name, d, co); } return res; } @@ -1114,8 +1154,8 @@ is_builtin(PyObject *name) Returns a borrowed reference. */ static PyObject * -get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks, - PyObject *p) +get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, + PyObject *path_hooks, PyObject *p) { PyObject *importer; Py_ssize_t j, nhooks; @@ -1129,7 +1169,7 @@ get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks, return NULL; /* Shouldn't happen */ importer = PyDict_GetItemWithError(path_importer_cache, p); - if (importer != NULL || PyErr_Occurred()) + if (importer != NULL || _PyErr_Occurred(tstate)) return importer; /* set path_importer_cache[p] to None to avoid recursion */ @@ -1144,10 +1184,10 @@ get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks, if (importer != NULL) break; - if (!PyErr_ExceptionMatches(PyExc_ImportError)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) { return NULL; } - PyErr_Clear(); + _PyErr_Clear(tstate); } if (importer == NULL) { return Py_None; @@ -1162,13 +1202,15 @@ get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks, } PyObject * -PyImport_GetImporter(PyObject *path) { +PyImport_GetImporter(PyObject *path) +{ + PyThreadState *tstate = _PyThreadState_GET(); PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL; path_importer_cache = PySys_GetObject("path_importer_cache"); path_hooks = PySys_GetObject("path_hooks"); if (path_importer_cache != NULL && path_hooks != NULL) { - importer = get_path_importer(path_importer_cache, + importer = get_path_importer(tstate, path_importer_cache, path_hooks, path); } Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */ @@ -1188,6 +1230,7 @@ static PyObject * _imp_create_builtin(PyObject *module, PyObject *spec) /*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/ { + PyThreadState *tstate = _PyThreadState_GET(); struct _inittab *p; PyObject *name; const char *namestr; @@ -1199,7 +1242,7 @@ _imp_create_builtin(PyObject *module, PyObject *spec) } mod = _PyImport_FindExtensionObject(name, name); - if (mod || PyErr_Occurred()) { + if (mod || _PyErr_Occurred(tstate)) { Py_DECREF(name); Py_XINCREF(mod); return mod; @@ -1211,7 +1254,7 @@ _imp_create_builtin(PyObject *module, PyObject *spec) return NULL; } - PyObject *modules = NULL; + PyObject *modules = tstate->interp->modules; for (p = PyImport_Inittab; p->name != NULL; p++) { PyModuleDef *def; if (_PyUnicode_EqualToASCIIString(name, p->name)) { @@ -1237,9 +1280,6 @@ _imp_create_builtin(PyObject *module, PyObject *spec) return NULL; } def->m_base.m_init = p->initfunc; - if (modules == NULL) { - modules = PyImport_GetModuleDict(); - } if (_PyImport_FixupExtensionObject(mod, name, name, modules) < 0) { Py_DECREF(name); @@ -1328,6 +1368,7 @@ is_frozen_package(PyObject *name) int PyImport_ImportFrozenModuleObject(PyObject *name) { + PyThreadState *tstate = _PyThreadState_GET(); const struct _frozen *p; PyObject *co, *m, *d; int ispackage; @@ -1338,9 +1379,9 @@ PyImport_ImportFrozenModuleObject(PyObject *name) if (p == NULL) return 0; if (p->code == NULL) { - PyErr_Format(PyExc_ImportError, - "Excluded frozen object named %R", - name); + _PyErr_Format(tstate, PyExc_ImportError, + "Excluded frozen object named %R", + name); return -1; } size = p->size; @@ -1351,16 +1392,16 @@ PyImport_ImportFrozenModuleObject(PyObject *name) if (co == NULL) return -1; if (!PyCode_Check(co)) { - PyErr_Format(PyExc_TypeError, - "frozen object %R is not a code object", - name); + _PyErr_Format(tstate, PyExc_TypeError, + "frozen object %R is not a code object", + name); goto err_return; } if (ispackage) { /* Set __path__ to the empty list */ PyObject *l; int err; - m = PyImport_AddModuleObject(name); + m = import_add_module(tstate, name); if (m == NULL) goto err_return; d = PyModule_GetDict(m); @@ -1373,16 +1414,18 @@ PyImport_ImportFrozenModuleObject(PyObject *name) if (err != 0) goto err_return; } - d = module_dict_for_exec(name); + d = module_dict_for_exec(tstate, name); if (d == NULL) { goto err_return; } - m = exec_code_in_module(name, d, co); - if (m == NULL) + m = exec_code_in_module(tstate, name, d, co); + if (m == NULL) { goto err_return; + } Py_DECREF(co); Py_DECREF(m); return 1; + err_return: Py_DECREF(co); return -1; @@ -1438,7 +1481,7 @@ PyImport_ImportModuleNoBlock(const char *name) /* Remove importlib frames from the traceback, * except in Verbose mode. */ static void -remove_importlib_frames(PyInterpreterState *interp) +remove_importlib_frames(PyThreadState *tstate) { const char *importlib_filename = ""; const char *external_filename = ""; @@ -1452,8 +1495,8 @@ remove_importlib_frames(PyInterpreterState *interp) from the traceback. We always trim chunks which end with a call to "_call_with_frames_removed". */ - PyErr_Fetch(&exception, &value, &base_tb); - if (!exception || interp->config.verbose) { + _PyErr_Fetch(tstate, &exception, &value, &base_tb); + if (!exception || tstate->interp->config.verbose) { goto done; } @@ -1492,12 +1535,12 @@ remove_importlib_frames(PyInterpreterState *interp) tb = next; } done: - PyErr_Restore(exception, value, base_tb); + _PyErr_Restore(tstate, exception, value, base_tb); } static PyObject * -resolve_name(PyObject *name, PyObject *globals, int level) +resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level) { _Py_IDENTIFIER(__spec__); _Py_IDENTIFIER(__package__); @@ -1512,29 +1555,30 @@ resolve_name(PyObject *name, PyObject *globals, int level) int level_up; if (globals == NULL) { - PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); + _PyErr_SetString(tstate, PyExc_KeyError, "'__name__' not in globals"); goto error; } if (!PyDict_Check(globals)) { - PyErr_SetString(PyExc_TypeError, "globals must be a dict"); + _PyErr_SetString(tstate, PyExc_TypeError, "globals must be a dict"); goto error; } package = _PyDict_GetItemIdWithError(globals, &PyId___package__); if (package == Py_None) { package = NULL; } - else if (package == NULL && PyErr_Occurred()) { + else if (package == NULL && _PyErr_Occurred(tstate)) { goto error; } spec = _PyDict_GetItemIdWithError(globals, &PyId___spec__); - if (spec == NULL && PyErr_Occurred()) { + if (spec == NULL && _PyErr_Occurred(tstate)) { goto error; } if (package != NULL) { Py_INCREF(package); if (!PyUnicode_Check(package)) { - PyErr_SetString(PyExc_TypeError, "package must be a string"); + _PyErr_SetString(tstate, PyExc_TypeError, + "package must be a string"); goto error; } else if (spec != NULL && spec != Py_None) { @@ -1563,8 +1607,8 @@ resolve_name(PyObject *name, PyObject *globals, int level) goto error; } else if (!PyUnicode_Check(package)) { - PyErr_SetString(PyExc_TypeError, - "__spec__.parent must be a string"); + _PyErr_SetString(tstate, PyExc_TypeError, + "__spec__.parent must be a string"); goto error; } } @@ -1577,22 +1621,24 @@ resolve_name(PyObject *name, PyObject *globals, int level) package = _PyDict_GetItemIdWithError(globals, &PyId___name__); if (package == NULL) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_KeyError, + "'__name__' not in globals"); } goto error; } Py_INCREF(package); if (!PyUnicode_Check(package)) { - PyErr_SetString(PyExc_TypeError, "__name__ must be a string"); + _PyErr_SetString(tstate, PyExc_TypeError, + "__name__ must be a string"); goto error; } if (_PyDict_GetItemIdWithError(globals, &PyId___path__) == NULL) { Py_ssize_t dot; - if (PyErr_Occurred() || PyUnicode_READY(package) < 0) { + if (_PyErr_Occurred(tstate) || PyUnicode_READY(package) < 0) { goto error; } @@ -1614,8 +1660,9 @@ resolve_name(PyObject *name, PyObject *globals, int level) last_dot = PyUnicode_GET_LENGTH(package); if (last_dot == 0) { - PyErr_SetString(PyExc_ImportError, - "attempted relative import with no known parent package"); + _PyErr_SetString(tstate, PyExc_ImportError, + "attempted relative import " + "with no known parent package"); goto error; } @@ -1625,9 +1672,9 @@ resolve_name(PyObject *name, PyObject *globals, int level) goto error; } else if (last_dot == -1) { - PyErr_SetString(PyExc_ValueError, - "attempted relative import beyond top-level " - "package"); + _PyErr_SetString(tstate, PyExc_ValueError, + "attempted relative import beyond top-level " + "package"); goto error; } } @@ -1648,11 +1695,11 @@ resolve_name(PyObject *name, PyObject *globals, int level) } static PyObject * -import_find_and_load(PyObject *abs_name) +import_find_and_load(PyThreadState *tstate, PyObject *abs_name) { _Py_IDENTIFIER(_find_and_load); PyObject *mod = NULL; - PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + PyInterpreterState *interp = tstate->interp; int import_time = interp->config.import_time; static int import_level; static _PyTime_t accumulated; @@ -1719,16 +1766,17 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) { + PyThreadState *tstate = _PyThreadState_GET(); _Py_IDENTIFIER(_handle_fromlist); PyObject *abs_name = NULL; PyObject *final_mod = NULL; PyObject *mod = NULL; PyObject *package = NULL; - PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + PyInterpreterState *interp = tstate->interp; int has_from; if (name == NULL) { - PyErr_SetString(PyExc_ValueError, "Empty module name"); + _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); goto error; } @@ -1736,33 +1784,34 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, for added performance. */ if (!PyUnicode_Check(name)) { - PyErr_SetString(PyExc_TypeError, "module name must be a string"); + _PyErr_SetString(tstate, PyExc_TypeError, + "module name must be a string"); goto error; } if (PyUnicode_READY(name) < 0) { goto error; } if (level < 0) { - PyErr_SetString(PyExc_ValueError, "level must be >= 0"); + _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0"); goto error; } if (level > 0) { - abs_name = resolve_name(name, globals, level); + abs_name = resolve_name(tstate, name, globals, level); if (abs_name == NULL) goto error; } else { /* level == 0 */ if (PyUnicode_GET_LENGTH(name) == 0) { - PyErr_SetString(PyExc_ValueError, "Empty module name"); + _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); goto error; } abs_name = name; Py_INCREF(abs_name); } - mod = PyImport_GetModule(abs_name); - if (mod == NULL && PyErr_Occurred()) { + mod = import_get_module(tstate, abs_name); + if (mod == NULL && _PyErr_Occurred(tstate)) { goto error; } @@ -1791,7 +1840,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, } else { Py_XDECREF(mod); - mod = import_find_and_load(abs_name); + mod = import_find_and_load(tstate, abs_name); if (mod == NULL) { goto error; } @@ -1838,13 +1887,13 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, goto error; } - final_mod = PyImport_GetModule(to_return); + final_mod = import_get_module(tstate, to_return); Py_DECREF(to_return); if (final_mod == NULL) { - if (!PyErr_Occurred()) { - PyErr_Format(PyExc_KeyError, - "%R not in sys.modules as expected", - to_return); + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_KeyError, + "%R not in sys.modules as expected", + to_return); } goto error; } @@ -1878,7 +1927,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, Py_XDECREF(mod); Py_XDECREF(package); if (final_mod == NULL) { - remove_importlib_frames(interp); + remove_importlib_frames(tstate); } return final_mod; } @@ -1937,6 +1986,7 @@ PyImport_ReloadModule(PyObject *m) PyObject * PyImport_Import(PyObject *module_name) { + PyThreadState *tstate = _PyThreadState_GET(); static PyObject *silly_list = NULL; static PyObject *builtins_str = NULL; static PyObject *import_str = NULL; @@ -1980,8 +2030,9 @@ PyImport_Import(PyObject *module_name) /* Get the __import__ function from the builtins */ if (PyDict_Check(builtins)) { import = PyObject_GetItem(builtins, import_str); - if (import == NULL) - PyErr_SetObject(PyExc_KeyError, import_str); + if (import == NULL) { + _PyErr_SetObject(tstate, PyExc_KeyError, import_str); + } } else import = PyObject_GetAttr(builtins, import_str); @@ -1997,9 +2048,9 @@ PyImport_Import(PyObject *module_name) goto err; Py_DECREF(r); - r = PyImport_GetModule(module_name); - if (r == NULL && !PyErr_Occurred()) { - PyErr_SetObject(PyExc_KeyError, module_name); + r = import_get_module(tstate, module_name); + if (r == NULL && !_PyErr_Occurred(tstate)) { + _PyErr_SetObject(tstate, PyExc_KeyError, module_name); } err: @@ -2060,6 +2111,7 @@ static PyObject * _imp_init_frozen_impl(PyObject *module, PyObject *name) /*[clinic end generated code: output=fc0511ed869fd69c input=13019adfc04f3fb3]*/ { + PyThreadState *tstate = _PyThreadState_GET(); int ret; PyObject *m; @@ -2069,7 +2121,7 @@ _imp_init_frozen_impl(PyObject *module, PyObject *name) if (ret == 0) { Py_RETURN_NONE; } - m = PyImport_AddModuleObject(name); + m = import_add_module(tstate, name); Py_XINCREF(m); return m; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 54e8ce2b155..4a97295102f 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -6,6 +6,7 @@ #undef Yield /* undefine macro conflicting with */ #include "pycore_ceval.h" #include "pycore_context.h" +#include "pycore_import.h" /* _PyImport_FindBuiltin */ #include "pycore_initconfig.h" #include "pycore_fileutils.h" #include "pycore_hamt.h" @@ -197,17 +198,17 @@ init_importlib(PyInterpreterState *interp, PyObject *sysmod) } static PyStatus -init_importlib_external(PyInterpreterState *interp) +init_importlib_external(PyThreadState *tstate) { PyObject *value; - value = PyObject_CallMethod(interp->importlib, + value = PyObject_CallMethod(tstate->interp->importlib, "_install_external_importers", ""); if (value == NULL) { PyErr_Print(); return _PyStatus_ERR("external importer setup failed"); } Py_DECREF(value); - return _PyImportZip_Init(interp); + return _PyImportZip_Init(tstate); } /* Helper functions to better handle the legacy C locale @@ -924,7 +925,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) return _PyStatus_ERR("can't finish initializing sys"); } - PyStatus status = init_importlib_external(interp); + PyStatus status = init_importlib_external(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1449,7 +1450,7 @@ new_interpreter(PyThreadState **tstate_p) } interp->modules = modules; - PyObject *sysmod = _PyImport_FindBuiltin("sys", modules); + PyObject *sysmod = _PyImport_FindBuiltin(tstate, "sys"); if (sysmod != NULL) { interp->sysdict = PyModule_GetDict(sysmod); if (interp->sysdict == NULL) { @@ -1465,7 +1466,7 @@ new_interpreter(PyThreadState **tstate_p) goto handle_error; } - PyObject *bimod = _PyImport_FindBuiltin("builtins", modules); + PyObject *bimod = _PyImport_FindBuiltin(tstate, "builtins"); if (bimod != NULL) { interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) @@ -1497,7 +1498,7 @@ new_interpreter(PyThreadState **tstate_p) return status; } - status = init_importlib_external(interp); + status = init_importlib_external(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } diff --git a/Python/pystate.c b/Python/pystate.c index 833e0fb30dc..1e2b4804589 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -741,28 +741,32 @@ PyState_RemoveModule(struct PyModuleDef* def) return PyList_SetItem(state->modules_by_index, index, Py_None); } -/* used by import.c:PyImport_Cleanup */ +/* Used by PyImport_Cleanup() */ void -_PyState_ClearModules(void) +_PyInterpreterState_ClearModules(PyInterpreterState *interp) { - PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE(); - if (state->modules_by_index) { - Py_ssize_t i; - for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) { - PyObject *m = PyList_GET_ITEM(state->modules_by_index, i); - if (PyModule_Check(m)) { - /* cleanup the saved copy of module dicts */ - PyModuleDef *md = PyModule_GetDef(m); - if (md) - Py_CLEAR(md->m_base.m_copy); + if (!interp->modules_by_index) { + return; + } + + Py_ssize_t i; + for (i = 0; i < PyList_GET_SIZE(interp->modules_by_index); i++) { + PyObject *m = PyList_GET_ITEM(interp->modules_by_index, i); + if (PyModule_Check(m)) { + /* cleanup the saved copy of module dicts */ + PyModuleDef *md = PyModule_GetDef(m); + if (md) { + Py_CLEAR(md->m_base.m_copy); } } - /* Setting modules_by_index to NULL could be dangerous, so we - clear the list instead. */ - if (PyList_SetSlice(state->modules_by_index, - 0, PyList_GET_SIZE(state->modules_by_index), - NULL)) - PyErr_WriteUnraisable(state->modules_by_index); + } + + /* Setting modules_by_index to NULL could be dangerous, so we + clear the list instead. */ + if (PyList_SetSlice(interp->modules_by_index, + 0, PyList_GET_SIZE(interp->modules_by_index), + NULL)) { + PyErr_WriteUnraisable(interp->modules_by_index); } }