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.
This commit is contained in:
Victor Stinner 2019-06-19 02:54:39 +02:00 committed by GitHub
parent 809ff1181c
commit 0a28f8d379
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 248 additions and 191 deletions

View File

@ -11,21 +11,14 @@ PyMODINIT_FUNC PyInit__imp(void);
PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *); PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *);
PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(struct _Py_Identifier *name); 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_SetModule(PyObject *name, PyObject *module);
PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module);
PyAPI_FUNC(void) _PyImport_AcquireLock(void); PyAPI_FUNC(void) _PyImport_AcquireLock(void);
PyAPI_FUNC(int) _PyImport_ReleaseLock(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_FindExtensionObject(PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObjectEx(PyObject *, PyObject *,
PyObject *);
PyAPI_FUNC(int) _PyImport_FixupBuiltin( PyAPI_FUNC(int) _PyImport_FixupBuiltin(
PyObject *mod, PyObject *mod,
const char *name, /* UTF-8 encoded string */ const char *name, /* UTF-8 encoded string */

View File

@ -148,7 +148,6 @@ struct _ts {
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void); PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void);
PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*);
PyAPI_FUNC(void) _PyState_ClearModules(void);
PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
/* Similar to PyThreadState_Get(), but don't issue a fatal error /* Similar to PyThreadState_Get(), but don't issue a fatal error

View File

@ -5,6 +5,11 @@
extern "C" { extern "C" {
#endif #endif
PyAPI_FUNC(PyObject *) _PyImport_FindBuiltin(
PyThreadState *tstate,
const char *name /* UTF-8 encoded string */
);
extern void _PyImport_ReInitLock(void); extern void _PyImport_ReInitLock(void);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -55,7 +55,7 @@ extern int _PyFloat_Init(void);
extern PyStatus _Py_HashRandomization_Init(const PyConfig *); extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
extern PyStatus _PyTypes_Init(void); extern PyStatus _PyTypes_Init(void);
extern PyStatus _PyImportZip_Init(PyInterpreterState *interp); extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
/* Various internal finalizers */ /* Various internal finalizers */

View File

@ -310,6 +310,9 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_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); PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -4,6 +4,7 @@
#include "Python-ast.h" #include "Python-ast.h"
#undef Yield /* undefine macro conflicting with <winbase.h> */ #undef Yield /* undefine macro conflicting with <winbase.h> */
#include "pycore_pyerrors.h"
#include "pycore_pyhash.h" #include "pycore_pyhash.h"
#include "pycore_pylifecycle.h" #include "pycore_pylifecycle.h"
#include "pycore_pymem.h" #include "pycore_pymem.h"
@ -25,6 +26,9 @@ extern "C" {
#define CACHEDIR "__pycache__" #define CACHEDIR "__pycache__"
/* Forward references */
static PyObject *import_add_module(PyThreadState *tstate, PyObject *name);
/* See _PyImport_FixupExtensionObject() below */ /* See _PyImport_FixupExtensionObject() below */
static PyObject *extensions = NULL; static PyObject *extensions = NULL;
@ -91,25 +95,26 @@ _PyImportHooks_Init(void)
} }
PyStatus PyStatus
_PyImportZip_Init(PyInterpreterState *interp) _PyImportZip_Init(PyThreadState *tstate)
{ {
PyObject *path_hooks, *zipimport; PyObject *path_hooks, *zipimport;
int err = 0; int err = 0;
path_hooks = PySys_GetObject("path_hooks"); path_hooks = PySys_GetObject("path_hooks");
if (path_hooks == NULL) { 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; goto error;
} }
int verbose = interp->config.verbose; int verbose = tstate->interp->config.verbose;
if (verbose) { if (verbose) {
PySys_WriteStderr("# installing zipimport hook\n"); PySys_WriteStderr("# installing zipimport hook\n");
} }
zipimport = PyImport_ImportModule("zipimport"); zipimport = PyImport_ImportModule("zipimport");
if (zipimport == NULL) { if (zipimport == NULL) {
PyErr_Clear(); /* No zip import module -- okay */ _PyErr_Clear(tstate); /* No zip import module -- okay */
if (verbose) { if (verbose) {
PySys_WriteStderr("# can't import zipimport\n"); PySys_WriteStderr("# can't import zipimport\n");
} }
@ -120,7 +125,7 @@ _PyImportZip_Init(PyInterpreterState *interp)
&PyId_zipimporter); &PyId_zipimporter);
Py_DECREF(zipimport); Py_DECREF(zipimport);
if (zipimporter == NULL) { if (zipimporter == NULL) {
PyErr_Clear(); /* No zipimporter object -- okay */ _PyErr_Clear(tstate); /* No zipimporter object -- okay */
if (verbose) { if (verbose) {
PySys_WriteStderr("# can't import zipimport.zipimporter\n"); PySys_WriteStderr("# can't import zipimport.zipimporter\n");
} }
@ -341,26 +346,30 @@ _PyImport_GetModuleId(struct _Py_Identifier *nameid)
int int
_PyImport_SetModule(PyObject *name, PyObject *m) _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); return PyObject_SetItem(modules, name, m);
} }
int int
_PyImport_SetModuleString(const char *name, PyObject *m) _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); return PyMapping_SetItemString(modules, name, m);
} }
PyObject * static PyObject *
PyImport_GetModule(PyObject *name) import_get_module(PyThreadState *tstate, PyObject *name)
{ {
PyObject *m; PyObject *modules = tstate->interp->modules;
PyObject *modules = PyImport_GetModuleDict();
if (modules == NULL) { if (modules == NULL) {
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules"); _PyErr_SetString(tstate, PyExc_RuntimeError,
"unable to get sys.modules");
return NULL; return NULL;
} }
PyObject *m;
Py_INCREF(modules); Py_INCREF(modules);
if (PyDict_CheckExact(modules)) { if (PyDict_CheckExact(modules)) {
m = PyDict_GetItemWithError(modules, name); /* borrowed */ m = PyDict_GetItemWithError(modules, name); /* borrowed */
@ -368,8 +377,8 @@ PyImport_GetModule(PyObject *name)
} }
else { else {
m = PyObject_GetItem(modules, name); m = PyObject_GetItem(modules, name);
if (m == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { if (m == NULL && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
PyErr_Clear(); _PyErr_Clear(tstate);
} }
} }
Py_DECREF(modules); 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 */ /* List of names to clear in sys */
static const char * const sys_deletes[] = { static const char * const sys_deletes[] = {
"path", "argv", "ps1", "ps2", "path", "argv", "ps1", "ps2",
@ -398,15 +415,13 @@ static const char * const sys_files[] = {
void void
PyImport_Cleanup(void) PyImport_Cleanup(void)
{ {
Py_ssize_t pos; PyThreadState *tstate = _PyThreadState_GET();
PyObject *key, *value, *dict; PyInterpreterState *interp = tstate->interp;
PyInterpreterState *interp = _PyInterpreterState_Get(); PyObject *modules = interp->modules;
PyObject *modules = PyImport_GetModuleDict(); if (modules == NULL) {
PyObject *weaklist = NULL; /* Already done */
const char * const *p; return;
}
if (modules == NULL)
return; /* Already done */
/* Delete some special variables first. These are common /* Delete some special variables first. These are common
places where user values hide and people complain when their places where user values hide and people complain when their
@ -424,6 +439,7 @@ PyImport_Cleanup(void)
PyErr_WriteUnraisable(NULL); PyErr_WriteUnraisable(NULL);
} }
const char * const *p;
for (p = sys_deletes; *p != NULL; p++) { for (p = sys_deletes; *p != NULL; p++) {
if (verbose) { if (verbose) {
PySys_WriteStderr("# clear sys.%s\n", *p); PySys_WriteStderr("# clear sys.%s\n", *p);
@ -436,9 +452,10 @@ PyImport_Cleanup(void)
if (verbose) { if (verbose) {
PySys_WriteStderr("# restore sys.%s\n", *p); 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 (value == NULL) {
if (PyErr_Occurred()) { if (_PyErr_Occurred(tstate)) {
PyErr_WriteUnraisable(NULL); PyErr_WriteUnraisable(NULL);
} }
value = Py_None; value = Py_None;
@ -452,7 +469,7 @@ PyImport_Cleanup(void)
modules when they are removed from sys.modules. The name is used modules when they are removed from sys.modules. The name is used
for diagnosis messages (in verbose mode), while the weakref helps for diagnosis messages (in verbose mode), while the weakref helps
detect those modules which have been held alive. */ detect those modules which have been held alive. */
weaklist = PyList_New(0); PyObject *weaklist = PyList_New(0);
if (weaklist == NULL) { if (weaklist == NULL) {
PyErr_WriteUnraisable(NULL); PyErr_WriteUnraisable(NULL);
} }
@ -486,7 +503,8 @@ PyImport_Cleanup(void)
/* Remove all modules from sys.modules, hoping that garbage collection /* Remove all modules from sys.modules, hoping that garbage collection
can reclaim most of them. */ can reclaim most of them. */
if (PyDict_CheckExact(modules)) { if (PyDict_CheckExact(modules)) {
pos = 0; Py_ssize_t pos = 0;
PyObject *key, *value;
while (PyDict_Next(modules, &pos, &key, &value)) { while (PyDict_Next(modules, &pos, &key, &value)) {
CLEAR_MODULE(key, value); CLEAR_MODULE(key, value);
} }
@ -497,8 +515,9 @@ PyImport_Cleanup(void)
PyErr_WriteUnraisable(NULL); PyErr_WriteUnraisable(NULL);
} }
else { else {
PyObject *key;
while ((key = PyIter_Next(iterator))) { while ((key = PyIter_Next(iterator))) {
value = PyObject_GetItem(modules, key); PyObject *value = PyObject_GetItem(modules, key);
if (value == NULL) { if (value == NULL) {
PyErr_WriteUnraisable(NULL); PyErr_WriteUnraisable(NULL);
continue; continue;
@ -526,17 +545,17 @@ PyImport_Cleanup(void)
} }
/* Restore the original builtins dict, to ensure that any /* Restore the original builtins dict, to ensure that any
user data gets cleared. */ user data gets cleared. */
dict = PyDict_Copy(interp->builtins); PyObject *dict = PyDict_Copy(interp->builtins);
if (dict == NULL) { if (dict == NULL) {
PyErr_WriteUnraisable(NULL); PyErr_WriteUnraisable(NULL);
} }
PyDict_Clear(interp->builtins); PyDict_Clear(interp->builtins);
if (PyDict_Update(interp->builtins, interp->builtins_copy)) { if (PyDict_Update(interp->builtins, interp->builtins_copy)) {
PyErr_Clear(); _PyErr_Clear(tstate);
} }
Py_XDECREF(dict); Py_XDECREF(dict);
/* Clear module dict copies stored in the interpreter state */ /* Clear module dict copies stored in the interpreter state */
_PyState_ClearModules(); _PyInterpreterState_ClearModules(tstate->interp);
/* Collect references */ /* Collect references */
_PyGC_CollectNoFail(); _PyGC_CollectNoFail();
/* Dump GC stats before it's too late, since it uses the warnings /* Dump GC stats before it's too late, since it uses the warnings
@ -651,7 +670,7 @@ PyImport_GetMagicTag(void)
int int
_PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name,
PyObject *filename, PyObject *modules) PyObject *filename, PyObject *modules)
{ {
PyObject *dict, *key; PyObject *dict, *key;
struct PyModuleDef *def; struct PyModuleDef *def;
@ -713,33 +732,32 @@ _PyImport_FixupBuiltin(PyObject *mod, const char *name, PyObject *modules)
return res; return res;
} }
PyObject * static PyObject *
_PyImport_FindExtensionObject(PyObject *name, PyObject *filename) import_find_extension(PyThreadState *tstate, PyObject *name,
PyObject *filename)
{ {
PyObject *modules = PyImport_GetModuleDict(); if (extensions == NULL) {
return _PyImport_FindExtensionObjectEx(name, filename, modules); return NULL;
} }
PyObject * PyObject *key = PyTuple_Pack(2, filename, name);
_PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename, if (key == NULL) {
PyObject *modules)
{
PyObject *mod, *mdict, *key;
PyModuleDef* def;
if (extensions == NULL)
return NULL; return NULL;
key = PyTuple_Pack(2, filename, name); }
if (key == NULL) PyModuleDef* def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key);
return NULL;
def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key);
Py_DECREF(key); Py_DECREF(key);
if (def == NULL) if (def == NULL) {
return NULL; return NULL;
}
PyObject *mod, *mdict;
PyObject *modules = tstate->interp->modules;
if (def->m_size == -1) { if (def->m_size == -1) {
/* Module does not support repeated initialization */ /* Module does not support repeated initialization */
if (def->m_base.m_copy == NULL) if (def->m_base.m_copy == NULL)
return NULL; return NULL;
mod = _PyImport_AddModuleObject(name, modules); mod = import_add_module(tstate, name);
if (mod == NULL) if (mod == NULL)
return NULL; return NULL;
mdict = PyModule_GetDict(mod); mdict = PyModule_GetDict(mod);
@ -764,23 +782,31 @@ _PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename,
PyMapping_DelItem(modules, name); PyMapping_DelItem(modules, name);
return NULL; return NULL;
} }
int verbose = _PyInterpreterState_Get()->config.verbose;
int verbose = tstate->interp->config.verbose;
if (verbose) { if (verbose) {
PySys_FormatStderr("import %U # previously loaded (%R)\n", PySys_FormatStderr("import %U # previously loaded (%R)\n",
name, filename); name, filename);
} }
return mod; return mod;
} }
PyObject * 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; PyObject *res, *nameobj;
nameobj = PyUnicode_InternFromString(name); nameobj = PyUnicode_InternFromString(name);
if (nameobj == NULL) if (nameobj == NULL)
return NULL; return NULL;
res = _PyImport_FindExtensionObjectEx(nameobj, nameobj, modules); res = import_find_extension(tstate, nameobj, nameobj);
Py_DECREF(nameobj); Py_DECREF(nameobj);
return res; 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 Because the former action is most common, THIS DOES NOT RETURN A
'NEW' REFERENCE! */ 'NEW' REFERENCE! */
PyObject * static PyObject *
PyImport_AddModuleObject(PyObject *name) import_add_module(PyThreadState *tstate, PyObject *name)
{ {
PyObject *modules = PyImport_GetModuleDict(); PyObject *modules = tstate->interp->modules;
return _PyImport_AddModuleObject(name, modules); if (modules == NULL) {
} _PyErr_SetString(tstate, PyExc_RuntimeError,
"no import module dictionary");
return NULL;
}
PyObject *
_PyImport_AddModuleObject(PyObject *name, PyObject *modules)
{
PyObject *m; PyObject *m;
if (PyDict_CheckExact(modules)) { if (PyDict_CheckExact(modules)) {
m = PyDict_GetItemWithError(modules, name); m = PyDict_GetItemWithError(modules, name);
@ -809,11 +835,11 @@ _PyImport_AddModuleObject(PyObject *name, PyObject *modules)
m = PyObject_GetItem(modules, name); m = PyObject_GetItem(modules, name);
// For backward-comaptibility we copy the behavior // For backward-comaptibility we copy the behavior
// of PyDict_GetItemWithError(). // of PyDict_GetItemWithError().
if (PyErr_ExceptionMatches(PyExc_KeyError)) { if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
PyErr_Clear(); _PyErr_Clear(tstate);
} }
} }
if (PyErr_Occurred()) { if (_PyErr_Occurred(tstate)) {
return NULL; return NULL;
} }
if (m != NULL && PyModule_Check(m)) { if (m != NULL && PyModule_Check(m)) {
@ -831,14 +857,22 @@ _PyImport_AddModuleObject(PyObject *name, PyObject *modules)
return m; return m;
} }
PyObject *
PyImport_AddModuleObject(PyObject *name)
{
PyThreadState *tstate = _PyThreadState_GET();
return import_add_module(tstate, name);
}
PyObject * PyObject *
PyImport_AddModule(const char *name) PyImport_AddModule(const char *name)
{ {
PyObject *nameobj, *module; PyObject *nameobj = PyUnicode_FromString(name);
nameobj = PyUnicode_FromString(name); if (nameobj == NULL) {
if (nameobj == NULL)
return NULL; return NULL;
module = PyImport_AddModuleObject(nameobj); }
PyObject *module = PyImport_AddModuleObject(nameobj);
Py_DECREF(nameobj); Py_DECREF(nameobj);
return module; return module;
} }
@ -846,20 +880,24 @@ PyImport_AddModule(const char *name)
/* Remove name from sys.modules, if it's there. */ /* Remove name from sys.modules, if it's there. */
static void static void
remove_module(PyObject *name) remove_module(PyThreadState *tstate, PyObject *name)
{ {
PyObject *type, *value, *traceback; PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback); _PyErr_Fetch(tstate, &type, &value, &traceback);
PyObject *modules = PyImport_GetModuleDict();
PyObject *modules = tstate->interp->modules;
if (!PyMapping_HasKey(modules, name)) { if (!PyMapping_HasKey(modules, name)) {
goto out; goto out;
} }
if (PyMapping_DelItem(modules, name) < 0) { if (PyMapping_DelItem(modules, name) < 0) {
Py_FatalError("import: deleting existing key in " _PyErr_SetString(tstate, PyExc_RuntimeError,
"sys.modules failed"); "deleting key in sys.modules failed");
_PyErr_ChainExceptions(type, value, traceback);
return;
} }
out: out:
PyErr_Restore(type, value, traceback); _PyErr_Restore(tstate, type, value, traceback);
} }
@ -944,23 +982,23 @@ error:
} }
static PyObject * static PyObject *
module_dict_for_exec(PyObject *name) module_dict_for_exec(PyThreadState *tstate, PyObject *name)
{ {
_Py_IDENTIFIER(__builtins__); _Py_IDENTIFIER(__builtins__);
PyObject *m, *d = NULL; PyObject *m, *d = NULL;
m = PyImport_AddModuleObject(name); m = import_add_module(tstate, name);
if (m == NULL) if (m == NULL)
return NULL; return NULL;
/* If the module is being reloaded, we get the old module back /* If the module is being reloaded, we get the old module back
and re-use its dict to exec the new code. */ and re-use its dict to exec the new code. */
d = PyModule_GetDict(m); d = PyModule_GetDict(m);
if (_PyDict_GetItemIdWithError(d, &PyId___builtins__) == NULL) { if (_PyDict_GetItemIdWithError(d, &PyId___builtins__) == NULL) {
if (PyErr_Occurred() || if (_PyErr_Occurred(tstate) ||
_PyDict_SetItemId(d, &PyId___builtins__, _PyDict_SetItemId(d, &PyId___builtins__,
PyEval_GetBuiltins()) != 0) PyEval_GetBuiltins()) != 0)
{ {
remove_module(name); remove_module(tstate, name);
return NULL; return NULL;
} }
} }
@ -969,22 +1007,23 @@ module_dict_for_exec(PyObject *name)
} }
static PyObject * 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; PyObject *v, *m;
v = PyEval_EvalCode(code_object, module_dict, module_dict); v = PyEval_EvalCode(code_object, module_dict, module_dict);
if (v == NULL) { if (v == NULL) {
remove_module(name); remove_module(tstate, name);
return NULL; return NULL;
} }
Py_DECREF(v); Py_DECREF(v);
m = PyImport_GetModule(name); m = import_get_module(tstate, name);
if (m == NULL && !PyErr_Occurred()) { if (m == NULL && !_PyErr_Occurred(tstate)) {
PyErr_Format(PyExc_ImportError, _PyErr_Format(tstate, PyExc_ImportError,
"Loaded module %R not found in sys.modules", "Loaded module %R not found in sys.modules",
name); name);
} }
return m; return m;
@ -994,11 +1033,11 @@ PyObject*
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
PyObject *cpathname) PyObject *cpathname)
{ {
PyThreadState *tstate = _PyThreadState_GET();
PyObject *d, *external, *res; PyObject *d, *external, *res;
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
_Py_IDENTIFIER(_fix_up_module); _Py_IDENTIFIER(_fix_up_module);
d = module_dict_for_exec(name); d = module_dict_for_exec(tstate, name);
if (d == NULL) { if (d == NULL) {
return NULL; return NULL;
} }
@ -1006,7 +1045,8 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
if (pathname == NULL) { if (pathname == NULL) {
pathname = ((PyCodeObject *)co)->co_filename; pathname = ((PyCodeObject *)co)->co_filename;
} }
external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); external = PyObject_GetAttrString(tstate->interp->importlib,
"_bootstrap_external");
if (external == NULL) if (external == NULL)
return NULL; return NULL;
res = _PyObject_CallMethodIdObjArgs(external, res = _PyObject_CallMethodIdObjArgs(external,
@ -1015,7 +1055,7 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
Py_DECREF(external); Py_DECREF(external);
if (res != NULL) { if (res != NULL) {
Py_DECREF(res); Py_DECREF(res);
res = exec_code_in_module(name, d, co); res = exec_code_in_module(tstate, name, d, co);
} }
return res; return res;
} }
@ -1114,8 +1154,8 @@ is_builtin(PyObject *name)
Returns a borrowed reference. */ Returns a borrowed reference. */
static PyObject * static PyObject *
get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks, get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache,
PyObject *p) PyObject *path_hooks, PyObject *p)
{ {
PyObject *importer; PyObject *importer;
Py_ssize_t j, nhooks; Py_ssize_t j, nhooks;
@ -1129,7 +1169,7 @@ get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks,
return NULL; /* Shouldn't happen */ return NULL; /* Shouldn't happen */
importer = PyDict_GetItemWithError(path_importer_cache, p); importer = PyDict_GetItemWithError(path_importer_cache, p);
if (importer != NULL || PyErr_Occurred()) if (importer != NULL || _PyErr_Occurred(tstate))
return importer; return importer;
/* set path_importer_cache[p] to None to avoid recursion */ /* 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) if (importer != NULL)
break; break;
if (!PyErr_ExceptionMatches(PyExc_ImportError)) { if (!_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) {
return NULL; return NULL;
} }
PyErr_Clear(); _PyErr_Clear(tstate);
} }
if (importer == NULL) { if (importer == NULL) {
return Py_None; return Py_None;
@ -1162,13 +1202,15 @@ get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks,
} }
PyObject * PyObject *
PyImport_GetImporter(PyObject *path) { PyImport_GetImporter(PyObject *path)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL; PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL;
path_importer_cache = PySys_GetObject("path_importer_cache"); path_importer_cache = PySys_GetObject("path_importer_cache");
path_hooks = PySys_GetObject("path_hooks"); path_hooks = PySys_GetObject("path_hooks");
if (path_importer_cache != NULL && path_hooks != NULL) { 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); path_hooks, path);
} }
Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */ Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */
@ -1188,6 +1230,7 @@ static PyObject *
_imp_create_builtin(PyObject *module, PyObject *spec) _imp_create_builtin(PyObject *module, PyObject *spec)
/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/ /*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/
{ {
PyThreadState *tstate = _PyThreadState_GET();
struct _inittab *p; struct _inittab *p;
PyObject *name; PyObject *name;
const char *namestr; const char *namestr;
@ -1199,7 +1242,7 @@ _imp_create_builtin(PyObject *module, PyObject *spec)
} }
mod = _PyImport_FindExtensionObject(name, name); mod = _PyImport_FindExtensionObject(name, name);
if (mod || PyErr_Occurred()) { if (mod || _PyErr_Occurred(tstate)) {
Py_DECREF(name); Py_DECREF(name);
Py_XINCREF(mod); Py_XINCREF(mod);
return mod; return mod;
@ -1211,7 +1254,7 @@ _imp_create_builtin(PyObject *module, PyObject *spec)
return NULL; return NULL;
} }
PyObject *modules = NULL; PyObject *modules = tstate->interp->modules;
for (p = PyImport_Inittab; p->name != NULL; p++) { for (p = PyImport_Inittab; p->name != NULL; p++) {
PyModuleDef *def; PyModuleDef *def;
if (_PyUnicode_EqualToASCIIString(name, p->name)) { if (_PyUnicode_EqualToASCIIString(name, p->name)) {
@ -1237,9 +1280,6 @@ _imp_create_builtin(PyObject *module, PyObject *spec)
return NULL; return NULL;
} }
def->m_base.m_init = p->initfunc; def->m_base.m_init = p->initfunc;
if (modules == NULL) {
modules = PyImport_GetModuleDict();
}
if (_PyImport_FixupExtensionObject(mod, name, name, if (_PyImport_FixupExtensionObject(mod, name, name,
modules) < 0) { modules) < 0) {
Py_DECREF(name); Py_DECREF(name);
@ -1328,6 +1368,7 @@ is_frozen_package(PyObject *name)
int int
PyImport_ImportFrozenModuleObject(PyObject *name) PyImport_ImportFrozenModuleObject(PyObject *name)
{ {
PyThreadState *tstate = _PyThreadState_GET();
const struct _frozen *p; const struct _frozen *p;
PyObject *co, *m, *d; PyObject *co, *m, *d;
int ispackage; int ispackage;
@ -1338,9 +1379,9 @@ PyImport_ImportFrozenModuleObject(PyObject *name)
if (p == NULL) if (p == NULL)
return 0; return 0;
if (p->code == NULL) { if (p->code == NULL) {
PyErr_Format(PyExc_ImportError, _PyErr_Format(tstate, PyExc_ImportError,
"Excluded frozen object named %R", "Excluded frozen object named %R",
name); name);
return -1; return -1;
} }
size = p->size; size = p->size;
@ -1351,16 +1392,16 @@ PyImport_ImportFrozenModuleObject(PyObject *name)
if (co == NULL) if (co == NULL)
return -1; return -1;
if (!PyCode_Check(co)) { if (!PyCode_Check(co)) {
PyErr_Format(PyExc_TypeError, _PyErr_Format(tstate, PyExc_TypeError,
"frozen object %R is not a code object", "frozen object %R is not a code object",
name); name);
goto err_return; goto err_return;
} }
if (ispackage) { if (ispackage) {
/* Set __path__ to the empty list */ /* Set __path__ to the empty list */
PyObject *l; PyObject *l;
int err; int err;
m = PyImport_AddModuleObject(name); m = import_add_module(tstate, name);
if (m == NULL) if (m == NULL)
goto err_return; goto err_return;
d = PyModule_GetDict(m); d = PyModule_GetDict(m);
@ -1373,16 +1414,18 @@ PyImport_ImportFrozenModuleObject(PyObject *name)
if (err != 0) if (err != 0)
goto err_return; goto err_return;
} }
d = module_dict_for_exec(name); d = module_dict_for_exec(tstate, name);
if (d == NULL) { if (d == NULL) {
goto err_return; goto err_return;
} }
m = exec_code_in_module(name, d, co); m = exec_code_in_module(tstate, name, d, co);
if (m == NULL) if (m == NULL) {
goto err_return; goto err_return;
}
Py_DECREF(co); Py_DECREF(co);
Py_DECREF(m); Py_DECREF(m);
return 1; return 1;
err_return: err_return:
Py_DECREF(co); Py_DECREF(co);
return -1; return -1;
@ -1438,7 +1481,7 @@ PyImport_ImportModuleNoBlock(const char *name)
/* Remove importlib frames from the traceback, /* Remove importlib frames from the traceback,
* except in Verbose mode. */ * except in Verbose mode. */
static void static void
remove_importlib_frames(PyInterpreterState *interp) remove_importlib_frames(PyThreadState *tstate)
{ {
const char *importlib_filename = "<frozen importlib._bootstrap>"; const char *importlib_filename = "<frozen importlib._bootstrap>";
const char *external_filename = "<frozen importlib._bootstrap_external>"; const char *external_filename = "<frozen importlib._bootstrap_external>";
@ -1452,8 +1495,8 @@ remove_importlib_frames(PyInterpreterState *interp)
from the traceback. We always trim chunks from the traceback. We always trim chunks
which end with a call to "_call_with_frames_removed". */ which end with a call to "_call_with_frames_removed". */
PyErr_Fetch(&exception, &value, &base_tb); _PyErr_Fetch(tstate, &exception, &value, &base_tb);
if (!exception || interp->config.verbose) { if (!exception || tstate->interp->config.verbose) {
goto done; goto done;
} }
@ -1492,12 +1535,12 @@ remove_importlib_frames(PyInterpreterState *interp)
tb = next; tb = next;
} }
done: done:
PyErr_Restore(exception, value, base_tb); _PyErr_Restore(tstate, exception, value, base_tb);
} }
static PyObject * 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(__spec__);
_Py_IDENTIFIER(__package__); _Py_IDENTIFIER(__package__);
@ -1512,29 +1555,30 @@ resolve_name(PyObject *name, PyObject *globals, int level)
int level_up; int level_up;
if (globals == NULL) { if (globals == NULL) {
PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); _PyErr_SetString(tstate, PyExc_KeyError, "'__name__' not in globals");
goto error; goto error;
} }
if (!PyDict_Check(globals)) { 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; goto error;
} }
package = _PyDict_GetItemIdWithError(globals, &PyId___package__); package = _PyDict_GetItemIdWithError(globals, &PyId___package__);
if (package == Py_None) { if (package == Py_None) {
package = NULL; package = NULL;
} }
else if (package == NULL && PyErr_Occurred()) { else if (package == NULL && _PyErr_Occurred(tstate)) {
goto error; goto error;
} }
spec = _PyDict_GetItemIdWithError(globals, &PyId___spec__); spec = _PyDict_GetItemIdWithError(globals, &PyId___spec__);
if (spec == NULL && PyErr_Occurred()) { if (spec == NULL && _PyErr_Occurred(tstate)) {
goto error; goto error;
} }
if (package != NULL) { if (package != NULL) {
Py_INCREF(package); Py_INCREF(package);
if (!PyUnicode_Check(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; goto error;
} }
else if (spec != NULL && spec != Py_None) { else if (spec != NULL && spec != Py_None) {
@ -1563,8 +1607,8 @@ resolve_name(PyObject *name, PyObject *globals, int level)
goto error; goto error;
} }
else if (!PyUnicode_Check(package)) { else if (!PyUnicode_Check(package)) {
PyErr_SetString(PyExc_TypeError, _PyErr_SetString(tstate, PyExc_TypeError,
"__spec__.parent must be a string"); "__spec__.parent must be a string");
goto error; goto error;
} }
} }
@ -1577,22 +1621,24 @@ resolve_name(PyObject *name, PyObject *globals, int level)
package = _PyDict_GetItemIdWithError(globals, &PyId___name__); package = _PyDict_GetItemIdWithError(globals, &PyId___name__);
if (package == NULL) { if (package == NULL) {
if (!PyErr_Occurred()) { if (!_PyErr_Occurred(tstate)) {
PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); _PyErr_SetString(tstate, PyExc_KeyError,
"'__name__' not in globals");
} }
goto error; goto error;
} }
Py_INCREF(package); Py_INCREF(package);
if (!PyUnicode_Check(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; goto error;
} }
if (_PyDict_GetItemIdWithError(globals, &PyId___path__) == NULL) { if (_PyDict_GetItemIdWithError(globals, &PyId___path__) == NULL) {
Py_ssize_t dot; Py_ssize_t dot;
if (PyErr_Occurred() || PyUnicode_READY(package) < 0) { if (_PyErr_Occurred(tstate) || PyUnicode_READY(package) < 0) {
goto error; goto error;
} }
@ -1614,8 +1660,9 @@ resolve_name(PyObject *name, PyObject *globals, int level)
last_dot = PyUnicode_GET_LENGTH(package); last_dot = PyUnicode_GET_LENGTH(package);
if (last_dot == 0) { if (last_dot == 0) {
PyErr_SetString(PyExc_ImportError, _PyErr_SetString(tstate, PyExc_ImportError,
"attempted relative import with no known parent package"); "attempted relative import "
"with no known parent package");
goto error; goto error;
} }
@ -1625,9 +1672,9 @@ resolve_name(PyObject *name, PyObject *globals, int level)
goto error; goto error;
} }
else if (last_dot == -1) { else if (last_dot == -1) {
PyErr_SetString(PyExc_ValueError, _PyErr_SetString(tstate, PyExc_ValueError,
"attempted relative import beyond top-level " "attempted relative import beyond top-level "
"package"); "package");
goto error; goto error;
} }
} }
@ -1648,11 +1695,11 @@ resolve_name(PyObject *name, PyObject *globals, int level)
} }
static PyObject * static PyObject *
import_find_and_load(PyObject *abs_name) import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
{ {
_Py_IDENTIFIER(_find_and_load); _Py_IDENTIFIER(_find_and_load);
PyObject *mod = NULL; PyObject *mod = NULL;
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); PyInterpreterState *interp = tstate->interp;
int import_time = interp->config.import_time; int import_time = interp->config.import_time;
static int import_level; static int import_level;
static _PyTime_t accumulated; static _PyTime_t accumulated;
@ -1719,16 +1766,17 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
PyObject *locals, PyObject *fromlist, PyObject *locals, PyObject *fromlist,
int level) int level)
{ {
PyThreadState *tstate = _PyThreadState_GET();
_Py_IDENTIFIER(_handle_fromlist); _Py_IDENTIFIER(_handle_fromlist);
PyObject *abs_name = NULL; PyObject *abs_name = NULL;
PyObject *final_mod = NULL; PyObject *final_mod = NULL;
PyObject *mod = NULL; PyObject *mod = NULL;
PyObject *package = NULL; PyObject *package = NULL;
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); PyInterpreterState *interp = tstate->interp;
int has_from; int has_from;
if (name == NULL) { if (name == NULL) {
PyErr_SetString(PyExc_ValueError, "Empty module name"); _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name");
goto error; goto error;
} }
@ -1736,33 +1784,34 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
for added performance. */ for added performance. */
if (!PyUnicode_Check(name)) { 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; goto error;
} }
if (PyUnicode_READY(name) < 0) { if (PyUnicode_READY(name) < 0) {
goto error; goto error;
} }
if (level < 0) { if (level < 0) {
PyErr_SetString(PyExc_ValueError, "level must be >= 0"); _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0");
goto error; goto error;
} }
if (level > 0) { if (level > 0) {
abs_name = resolve_name(name, globals, level); abs_name = resolve_name(tstate, name, globals, level);
if (abs_name == NULL) if (abs_name == NULL)
goto error; goto error;
} }
else { /* level == 0 */ else { /* level == 0 */
if (PyUnicode_GET_LENGTH(name) == 0) { if (PyUnicode_GET_LENGTH(name) == 0) {
PyErr_SetString(PyExc_ValueError, "Empty module name"); _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name");
goto error; goto error;
} }
abs_name = name; abs_name = name;
Py_INCREF(abs_name); Py_INCREF(abs_name);
} }
mod = PyImport_GetModule(abs_name); mod = import_get_module(tstate, abs_name);
if (mod == NULL && PyErr_Occurred()) { if (mod == NULL && _PyErr_Occurred(tstate)) {
goto error; goto error;
} }
@ -1791,7 +1840,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
} }
else { else {
Py_XDECREF(mod); Py_XDECREF(mod);
mod = import_find_and_load(abs_name); mod = import_find_and_load(tstate, abs_name);
if (mod == NULL) { if (mod == NULL) {
goto error; goto error;
} }
@ -1838,13 +1887,13 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
goto error; goto error;
} }
final_mod = PyImport_GetModule(to_return); final_mod = import_get_module(tstate, to_return);
Py_DECREF(to_return); Py_DECREF(to_return);
if (final_mod == NULL) { if (final_mod == NULL) {
if (!PyErr_Occurred()) { if (!_PyErr_Occurred(tstate)) {
PyErr_Format(PyExc_KeyError, _PyErr_Format(tstate, PyExc_KeyError,
"%R not in sys.modules as expected", "%R not in sys.modules as expected",
to_return); to_return);
} }
goto error; goto error;
} }
@ -1878,7 +1927,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
Py_XDECREF(mod); Py_XDECREF(mod);
Py_XDECREF(package); Py_XDECREF(package);
if (final_mod == NULL) { if (final_mod == NULL) {
remove_importlib_frames(interp); remove_importlib_frames(tstate);
} }
return final_mod; return final_mod;
} }
@ -1937,6 +1986,7 @@ PyImport_ReloadModule(PyObject *m)
PyObject * PyObject *
PyImport_Import(PyObject *module_name) PyImport_Import(PyObject *module_name)
{ {
PyThreadState *tstate = _PyThreadState_GET();
static PyObject *silly_list = NULL; static PyObject *silly_list = NULL;
static PyObject *builtins_str = NULL; static PyObject *builtins_str = NULL;
static PyObject *import_str = NULL; static PyObject *import_str = NULL;
@ -1980,8 +2030,9 @@ PyImport_Import(PyObject *module_name)
/* Get the __import__ function from the builtins */ /* Get the __import__ function from the builtins */
if (PyDict_Check(builtins)) { if (PyDict_Check(builtins)) {
import = PyObject_GetItem(builtins, import_str); import = PyObject_GetItem(builtins, import_str);
if (import == NULL) if (import == NULL) {
PyErr_SetObject(PyExc_KeyError, import_str); _PyErr_SetObject(tstate, PyExc_KeyError, import_str);
}
} }
else else
import = PyObject_GetAttr(builtins, import_str); import = PyObject_GetAttr(builtins, import_str);
@ -1997,9 +2048,9 @@ PyImport_Import(PyObject *module_name)
goto err; goto err;
Py_DECREF(r); Py_DECREF(r);
r = PyImport_GetModule(module_name); r = import_get_module(tstate, module_name);
if (r == NULL && !PyErr_Occurred()) { if (r == NULL && !_PyErr_Occurred(tstate)) {
PyErr_SetObject(PyExc_KeyError, module_name); _PyErr_SetObject(tstate, PyExc_KeyError, module_name);
} }
err: err:
@ -2060,6 +2111,7 @@ static PyObject *
_imp_init_frozen_impl(PyObject *module, PyObject *name) _imp_init_frozen_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=fc0511ed869fd69c input=13019adfc04f3fb3]*/ /*[clinic end generated code: output=fc0511ed869fd69c input=13019adfc04f3fb3]*/
{ {
PyThreadState *tstate = _PyThreadState_GET();
int ret; int ret;
PyObject *m; PyObject *m;
@ -2069,7 +2121,7 @@ _imp_init_frozen_impl(PyObject *module, PyObject *name)
if (ret == 0) { if (ret == 0) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
m = PyImport_AddModuleObject(name); m = import_add_module(tstate, name);
Py_XINCREF(m); Py_XINCREF(m);
return m; return m;
} }

View File

@ -6,6 +6,7 @@
#undef Yield /* undefine macro conflicting with <winbase.h> */ #undef Yield /* undefine macro conflicting with <winbase.h> */
#include "pycore_ceval.h" #include "pycore_ceval.h"
#include "pycore_context.h" #include "pycore_context.h"
#include "pycore_import.h" /* _PyImport_FindBuiltin */
#include "pycore_initconfig.h" #include "pycore_initconfig.h"
#include "pycore_fileutils.h" #include "pycore_fileutils.h"
#include "pycore_hamt.h" #include "pycore_hamt.h"
@ -197,17 +198,17 @@ init_importlib(PyInterpreterState *interp, PyObject *sysmod)
} }
static PyStatus static PyStatus
init_importlib_external(PyInterpreterState *interp) init_importlib_external(PyThreadState *tstate)
{ {
PyObject *value; PyObject *value;
value = PyObject_CallMethod(interp->importlib, value = PyObject_CallMethod(tstate->interp->importlib,
"_install_external_importers", ""); "_install_external_importers", "");
if (value == NULL) { if (value == NULL) {
PyErr_Print(); PyErr_Print();
return _PyStatus_ERR("external importer setup failed"); return _PyStatus_ERR("external importer setup failed");
} }
Py_DECREF(value); Py_DECREF(value);
return _PyImportZip_Init(interp); return _PyImportZip_Init(tstate);
} }
/* Helper functions to better handle the legacy C locale /* 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"); return _PyStatus_ERR("can't finish initializing sys");
} }
PyStatus status = init_importlib_external(interp); PyStatus status = init_importlib_external(tstate);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
@ -1449,7 +1450,7 @@ new_interpreter(PyThreadState **tstate_p)
} }
interp->modules = modules; interp->modules = modules;
PyObject *sysmod = _PyImport_FindBuiltin("sys", modules); PyObject *sysmod = _PyImport_FindBuiltin(tstate, "sys");
if (sysmod != NULL) { if (sysmod != NULL) {
interp->sysdict = PyModule_GetDict(sysmod); interp->sysdict = PyModule_GetDict(sysmod);
if (interp->sysdict == NULL) { if (interp->sysdict == NULL) {
@ -1465,7 +1466,7 @@ new_interpreter(PyThreadState **tstate_p)
goto handle_error; goto handle_error;
} }
PyObject *bimod = _PyImport_FindBuiltin("builtins", modules); PyObject *bimod = _PyImport_FindBuiltin(tstate, "builtins");
if (bimod != NULL) { if (bimod != NULL) {
interp->builtins = PyModule_GetDict(bimod); interp->builtins = PyModule_GetDict(bimod);
if (interp->builtins == NULL) if (interp->builtins == NULL)
@ -1497,7 +1498,7 @@ new_interpreter(PyThreadState **tstate_p)
return status; return status;
} }
status = init_importlib_external(interp); status = init_importlib_external(tstate);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }

View File

@ -741,28 +741,32 @@ PyState_RemoveModule(struct PyModuleDef* def)
return PyList_SetItem(state->modules_by_index, index, Py_None); return PyList_SetItem(state->modules_by_index, index, Py_None);
} }
/* used by import.c:PyImport_Cleanup */ /* Used by PyImport_Cleanup() */
void void
_PyState_ClearModules(void) _PyInterpreterState_ClearModules(PyInterpreterState *interp)
{ {
PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE(); if (!interp->modules_by_index) {
if (state->modules_by_index) { return;
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); Py_ssize_t i;
if (PyModule_Check(m)) { for (i = 0; i < PyList_GET_SIZE(interp->modules_by_index); i++) {
/* cleanup the saved copy of module dicts */ PyObject *m = PyList_GET_ITEM(interp->modules_by_index, i);
PyModuleDef *md = PyModule_GetDef(m); if (PyModule_Check(m)) {
if (md) /* cleanup the saved copy of module dicts */
Py_CLEAR(md->m_base.m_copy); 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, /* Setting modules_by_index to NULL could be dangerous, so we
0, PyList_GET_SIZE(state->modules_by_index), clear the list instead. */
NULL)) if (PyList_SetSlice(interp->modules_by_index,
PyErr_WriteUnraisable(state->modules_by_index); 0, PyList_GET_SIZE(interp->modules_by_index),
NULL)) {
PyErr_WriteUnraisable(interp->modules_by_index);
} }
} }