#include "Python.h"
#include "pycore_audit.h"
#include "pycore_ceval.h"
#include "pycore_critical_section.h"
#include "pycore_dict.h"
#include "pycore_hashtable.h"
#include "pycore_import.h"
#include "pycore_initconfig.h"
#include "pycore_interp.h"
#include "pycore_interpframe.h"
#include "pycore_lazyimportobject.h"
#include "pycore_long.h"
#include "pycore_magic_number.h"
#include "pycore_moduleobject.h"
#include "pycore_namespace.h"
#include "pycore_object.h"
#include "pycore_pyatomic_ft_wrappers.h"
#include "pycore_pyerrors.h"
#include "pycore_pyhash.h"
#include "pycore_pylifecycle.h"
#include "pycore_pymem.h"
#include "pycore_pystate.h"
#include "pycore_setobject.h"
#include "pycore_sysmodule.h"
#include "pycore_time.h"
#include "pycore_traceback.h"
#include "pycore_unicodeobject.h"
#include "pycore_weakref.h"
#include "marshal.h"
#include "pycore_importdl.h"
#include "pydtrace.h"
#include <stdbool.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
module _imp
[clinic start generated code]*/
#include "clinic/import.c.h"
#ifndef NDEBUG
static bool
is_interpreter_isolated(PyInterpreterState *interp)
{
return !_Py_IsMainInterpreter(interp)
&& !(interp->feature_flags & Py_RTFLAGS_USE_MAIN_OBMALLOC)
&& interp->ceval.own_gil;
}
#endif
extern struct _inittab _PyImport_Inittab[];
struct _inittab *PyImport_Inittab = _PyImport_Inittab;
static struct _inittab *inittab_copy = NULL;
#define INITTAB _PyRuntime.imports.inittab
#define LAST_MODULE_INDEX _PyRuntime.imports.last_module_index
#define EXTENSIONS _PyRuntime.imports.extensions
#define MODULES(interp) \
(interp)->imports.modules
#define MODULES_BY_INDEX(interp) \
(interp)->imports.modules_by_index
#define LAZY_MODULES(interp) \
(interp)->imports.lazy_modules
#define LAZY_PENDING_SUBMODULES(interp) \
(interp)->imports.lazy_pending_submodules
#define IMPORTLIB(interp) \
(interp)->imports.importlib
#define OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp) \
(interp)->imports.override_multi_interp_extensions_check
#define OVERRIDE_FROZEN_MODULES(interp) \
(interp)->imports.override_frozen_modules
#ifdef HAVE_DLOPEN
# define DLOPENFLAGS(interp) \
(interp)->imports.dlopenflags
#endif
#define IMPORT_FUNC(interp) \
(interp)->imports.import_func
#define LAZY_IMPORT_FUNC(interp) \
(interp)->imports.lazy_import_func
#define IMPORT_LOCK(interp) \
(interp)->imports.lock
#define FIND_AND_LOAD(interp) \
(interp)->imports.find_and_load
#define LAZY_IMPORTS_MODE(interp) \
(interp)->imports.lazy_imports_mode
#define LAZY_IMPORTS_FILTER(interp) \
(interp)->imports.lazy_imports_filter
#ifdef Py_GIL_DISABLED
#define LAZY_IMPORTS_LOCK(interp) PyMutex_Lock(&(interp)->imports.lazy_mutex)
#define LAZY_IMPORTS_UNLOCK(interp) PyMutex_Unlock(&(interp)->imports.lazy_mutex)
#else
#define LAZY_IMPORTS_LOCK(interp)
#define LAZY_IMPORTS_UNLOCK(interp)
#endif
#define _IMPORT_TIME_HEADER(interp) \
do { \
if (FIND_AND_LOAD((interp)).header) { \
fputs("import time: self [us] | cumulative | imported package\n", \
stderr); \
FIND_AND_LOAD((interp)).header = 0; \
} \
} while (0)
in different threads to return with a partially loaded module.
These calls are serialized by the global interpreter lock. */
void
_PyImport_AcquireLock(PyInterpreterState *interp)
{
_PyRecursiveMutex_Lock(&IMPORT_LOCK(interp));
}
void
_PyImport_ReleaseLock(PyInterpreterState *interp)
{
_PyRecursiveMutex_Unlock(&IMPORT_LOCK(interp));
}
void
_PyImport_ReInitLock(PyInterpreterState *interp)
{
IMPORT_LOCK(interp).thread = PyThread_get_thread_ident_ex();
}
PyObject *
_PyImport_InitModules(PyInterpreterState *interp)
{
assert(MODULES(interp) == NULL);
MODULES(interp) = PyDict_New();
if (MODULES(interp) == NULL) {
return NULL;
}
return MODULES(interp);
}
PyObject *
_PyImport_GetModules(PyInterpreterState *interp)
{
return MODULES(interp);
}
PyObject *
_PyImport_GetModulesRef(PyInterpreterState *interp)
{
_PyImport_AcquireLock(interp);
PyObject *modules = MODULES(interp);
if (modules == NULL) {
modules = Py_None;
}
Py_INCREF(modules);
_PyImport_ReleaseLock(interp);
return modules;
}
void
_PyImport_ClearModules(PyInterpreterState *interp)
{
Py_SETREF(MODULES(interp), NULL);
}
static inline PyObject *
get_modules_dict(PyThreadState *tstate, bool fatal)
{
* since sys.modules could be swapped out and decref'ed to 0
* before the caller is done using it. However, that is highly
* unlikely, especially since we can rely on a global lock
* (i.e. the GIL) for thread-safety. */
PyObject *modules = MODULES(tstate->interp);
if (modules == NULL) {
if (fatal) {
Py_FatalError("interpreter has no modules dictionary");
}
_PyErr_SetString(tstate, PyExc_RuntimeError,
"unable to get sys.modules");
return NULL;
}
return modules;
}
PyObject *
PyImport_GetModuleDict(void)
{
PyThreadState *tstate = _PyThreadState_GET();
return get_modules_dict(tstate, true);
}
int
_PyImport_SetModule(PyObject *name, PyObject *m)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *modules = get_modules_dict(tstate, true);
return PyObject_SetItem(modules, name, m);
}
int
_PyImport_SetModuleString(const char *name, PyObject *m)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *modules = get_modules_dict(tstate, true);
return PyMapping_SetItemString(modules, name, m);
}
static PyObject *
import_get_module(PyThreadState *tstate, PyObject *name)
{
PyObject *modules = get_modules_dict(tstate, false);
if (modules == NULL) {
return NULL;
}
PyObject *m;
Py_INCREF(modules);
(void)PyMapping_GetOptionalItem(modules, name, &m);
Py_DECREF(modules);
return m;
}
PyObject *
_PyImport_InitLazyModules(PyInterpreterState *interp)
{
assert(LAZY_MODULES(interp) == NULL &&
LAZY_PENDING_SUBMODULES(interp) == NULL);
LAZY_PENDING_SUBMODULES(interp) = PyDict_New();
LAZY_MODULES(interp) = PySet_New(0);
return LAZY_MODULES(interp);
}
void
_PyImport_ClearLazyModules(PyInterpreterState *interp)
{
Py_CLEAR(LAZY_MODULES(interp));
Py_CLEAR(LAZY_PENDING_SUBMODULES(interp));
}
static PyObject *
get_importtime_name(PyObject *name)
{
PyObject *exc = PyErr_GetRaisedException();
PyObject *encoded = PyUnicode_AsEncodedString(name, "utf-8",
"backslashreplace");
if (encoded == NULL) {
PyErr_Clear();
}
PyErr_SetRaisedException(exc);
return encoded;
}
static int
import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *name)
{
PyObject *spec;
__spec__._initializing is true.
NOTE: because of this, initializing must be set *before*
stuffing the new module in sys.modules.
*/
int rc = PyObject_GetOptionalAttr(mod, &_Py_ID(__spec__), &spec);
if (rc > 0) {
rc = _PyModuleSpec_IsInitializing(spec);
Py_DECREF(spec);
}
if (rc == 0) {
goto done;
}
else if (rc < 0) {
return rc;
}
PyObject *value = PyObject_CallMethodOneArg(
IMPORTLIB(interp), &_Py_ID(_lock_unlock_module), name);
if (value == NULL) {
return -1;
}
Py_DECREF(value);
done:
imported module has already been loaded.
*/
if (_PyInterpreterState_GetConfig(interp)->import_time == 2) {
_IMPORT_TIME_HEADER(interp);
#define import_level FIND_AND_LOAD(interp).import_level
PyObject *encoded_name = get_importtime_name(name);
fprintf(stderr, "import time: cached | cached | %*s\n",
import_level*2,
encoded_name != NULL ? PyBytes_AS_STRING(encoded_name) : "?");
Py_XDECREF(encoded_name);
#undef import_level
}
return 0;
}
static void remove_importlib_frames(PyThreadState *tstate);
PyObject *
PyImport_GetModule(PyObject *name)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *mod;
mod = import_get_module(tstate, name);
if (mod != NULL && mod != Py_None) {
if (import_ensure_initialized(tstate->interp, mod, name) < 0) {
goto error;
}
removed it (due to import failure) between our import_get_module()
call and the _initializing check in import_ensure_initialized(). */
PyObject *mod_check = import_get_module(tstate, name);
if (mod_check != mod) {
Py_XDECREF(mod_check);
if (_PyErr_Occurred(tstate)) {
goto error;
}
"not found" rather than trying to keep up with racing
modifications to sys.modules; returning the new value would
require looping to redo the ensure_initialized check. */
Py_DECREF(mod);
return NULL;
}
Py_DECREF(mod_check);
}
return mod;
error:
Py_DECREF(mod);
remove_importlib_frames(tstate);
return NULL;
}
First check the modules dictionary if there's one there,
if not, create a new one and insert it in the modules dictionary. */
static PyObject *
import_add_module_lock_held(PyObject *modules, PyObject *name)
{
PyObject *m;
if (PyMapping_GetOptionalItem(modules, name, &m) < 0) {
return NULL;
}
if (m != NULL && PyModule_Check(m)) {
return m;
}
Py_XDECREF(m);
m = PyModule_NewObject(name);
if (m == NULL)
return NULL;
if (PyObject_SetItem(modules, name, m) != 0) {
Py_DECREF(m);
return NULL;
}
return m;
}
static PyObject *
import_add_module(PyThreadState *tstate, PyObject *name)
{
PyObject *modules = get_modules_dict(tstate, false);
if (modules == NULL) {
return NULL;
}
PyObject *m;
Py_BEGIN_CRITICAL_SECTION(modules);
m = import_add_module_lock_held(modules, name);
Py_END_CRITICAL_SECTION();
return m;
}
PyObject *
PyImport_AddModuleRef(const char *name)
{
PyObject *name_obj = PyUnicode_FromString(name);
if (name_obj == NULL) {
return NULL;
}
PyThreadState *tstate = _PyThreadState_GET();
PyObject *module = import_add_module(tstate, name_obj);
Py_DECREF(name_obj);
return module;
}
PyObject *
PyImport_AddModuleObject(PyObject *name)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *mod = import_add_module(tstate, name);
if (!mod) {
return NULL;
}
PyObject *ref = PyWeakref_NewRef(mod, NULL);
Py_DECREF(mod);
if (ref == NULL) {
return NULL;
}
mod = _PyWeakref_GET_REF(ref);
Py_DECREF(ref);
Py_XDECREF(mod);
if (mod == NULL && !PyErr_Occurred()) {
PyErr_SetString(PyExc_RuntimeError,
"sys.modules does not hold a strong reference "
"to the module");
}
return mod;
}
PyObject *
PyImport_AddModule(const char *name)
{
PyObject *nameobj = PyUnicode_FromString(name);
if (nameobj == NULL) {
return NULL;
}
PyObject *module = PyImport_AddModuleObject(nameobj);
Py_DECREF(nameobj);
return module;
}
* Can be called with an exception raised.
* If fail to remove name a new exception will be chained with the old
* exception, otherwise the old exception is preserved.
*/
static void
remove_module(PyThreadState *tstate, PyObject *name)
{
PyObject *exc = _PyErr_GetRaisedException(tstate);
PyObject *modules = get_modules_dict(tstate, true);
if (PyDict_CheckExact(modules)) {
(void)PyDict_Pop(modules, name, NULL);
}
else if (PyMapping_DelItem(modules, name) < 0) {
if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
_PyErr_Clear(tstate);
}
}
_PyErr_ChainExceptions1(exc);
}
Py_ssize_t
_PyImport_GetNextModuleIndex(void)
{
return _Py_atomic_add_ssize(&LAST_MODULE_INDEX, 1) + 1;
}
#ifndef NDEBUG
struct extensions_cache_value;
static struct extensions_cache_value * _find_cached_def(PyModuleDef *);
static Py_ssize_t _get_cached_module_index(struct extensions_cache_value *);
#endif
static Py_ssize_t
_get_module_index_from_def(PyModuleDef *def)
{
Py_ssize_t index = def->m_base.m_index;
#ifndef NDEBUG
struct extensions_cache_value *cached = _find_cached_def(def);
assert(cached == NULL || index == _get_cached_module_index(cached));
#endif
return index;
}
static void
_set_module_index(PyModuleDef *def, Py_ssize_t index)
{
assert(index > 0);
if (index == def->m_base.m_index) {
}
else if (def->m_base.m_index == 0) {
* We assert here to catch this in dev, but keep going otherwise. */
assert(def->m_base.m_index != 0);
def->m_base.m_index = index;
}
else {
* We replace the old value. */
assert(def->m_base.m_index > 0);
def->m_base.m_index = index;
}
}
static const char *
_modules_by_index_check(PyInterpreterState *interp, Py_ssize_t index)
{
if (index <= 0) {
return "invalid module index";
}
if (MODULES_BY_INDEX(interp) == NULL) {
return "Interpreters module-list not accessible.";
}
if (index >= PyList_GET_SIZE(MODULES_BY_INDEX(interp))) {
return "Module index out of bounds.";
}
return NULL;
}
static PyObject *
_modules_by_index_get(PyInterpreterState *interp, Py_ssize_t index)
{
if (_modules_by_index_check(interp, index) != NULL) {
return NULL;
}
PyObject *res = PyList_GET_ITEM(MODULES_BY_INDEX(interp), index);
return res==Py_None ? NULL : res;
}
static int
_modules_by_index_set(PyInterpreterState *interp,
Py_ssize_t index, PyObject *module)
{
assert(index > 0);
if (MODULES_BY_INDEX(interp) == NULL) {
MODULES_BY_INDEX(interp) = PyList_New(0);
if (MODULES_BY_INDEX(interp) == NULL) {
return -1;
}
}
while (PyList_GET_SIZE(MODULES_BY_INDEX(interp)) <= index) {
if (PyList_Append(MODULES_BY_INDEX(interp), Py_None) < 0) {
return -1;
}
}
return PyList_SetItem(MODULES_BY_INDEX(interp), index, Py_NewRef(module));
}
static int
_modules_by_index_clear_one(PyInterpreterState *interp, Py_ssize_t index)
{
const char *err = _modules_by_index_check(interp, index);
if (err != NULL) {
Py_FatalError(err);
return -1;
}
return PyList_SetItem(MODULES_BY_INDEX(interp), index, Py_NewRef(Py_None));
}
PyObject*
PyState_FindModule(PyModuleDef* module)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
if (module->m_slots) {
return NULL;
}
Py_ssize_t index = _get_module_index_from_def(module);
return _modules_by_index_get(interp, index);
}
(and was removed from the limited API in 3.6). However, we're
playing it safe and keeping it around for any stable ABI extensions
built against 3.2-3.5. */
int
_PyState_AddModule(PyThreadState *tstate, PyObject* module, PyModuleDef* def)
{
if (!def) {
assert(_PyErr_Occurred(tstate));
return -1;
}
if (def->m_slots) {
_PyErr_SetString(tstate,
PyExc_SystemError,
"PyState_AddModule called on module with slots");
return -1;
}
assert(def->m_slots == NULL);
Py_ssize_t index = _get_module_index_from_def(def);
return _modules_by_index_set(tstate->interp, index, module);
}
int
PyState_AddModule(PyObject* module, PyModuleDef* def)
{
if (!def) {
Py_FatalError("module definition is NULL");
return -1;
}
PyThreadState *tstate = _PyThreadState_GET();
if (def->m_slots) {
_PyErr_SetString(tstate,
PyExc_SystemError,
"PyState_AddModule called on module with slots");
return -1;
}
PyInterpreterState *interp = tstate->interp;
Py_ssize_t index = _get_module_index_from_def(def);
if (MODULES_BY_INDEX(interp) &&
index < PyList_GET_SIZE(MODULES_BY_INDEX(interp)) &&
module == PyList_GET_ITEM(MODULES_BY_INDEX(interp), index))
{
_Py_FatalErrorFormat(__func__, "module %p already added", module);
return -1;
}
assert(def->m_slots == NULL);
return _modules_by_index_set(interp, index, module);
}
int
PyState_RemoveModule(PyModuleDef* def)
{
PyThreadState *tstate = _PyThreadState_GET();
if (def->m_slots) {
_PyErr_SetString(tstate,
PyExc_SystemError,
"PyState_RemoveModule called on module with slots");
return -1;
}
Py_ssize_t index = _get_module_index_from_def(def);
return _modules_by_index_clear_one(tstate->interp, index);
}
void
_PyImport_ClearModulesByIndex(PyInterpreterState *interp)
{
if (!MODULES_BY_INDEX(interp)) {
return;
}
Py_ssize_t i;
for (i = 0; i < PyList_GET_SIZE(MODULES_BY_INDEX(interp)); i++) {
PyObject *m = PyList_GET_ITEM(MODULES_BY_INDEX(interp), i);
if (PyModule_Check(m)) {
PyModuleDef *md = PyModule_GetDef(m);
if (md) {
Py_CLEAR(md->m_base.m_copy);
}
}
}
clear the list instead. */
if (PyList_SetSlice(MODULES_BY_INDEX(interp),
0, PyList_GET_SIZE(MODULES_BY_INDEX(interp)),
NULL)) {
PyErr_FormatUnraisable("Exception ignored while "
"clearing interpreters module list");
}
}
It may help to have a big picture view of what happens
when an extension is loaded. This includes when it is imported
for the first time.
Here's a summary, using importlib._bootstrap._load() as a starting point.
1. importlib._bootstrap._load()
2. _load(): acquire import lock
3. _load() -> importlib._bootstrap._load_unlocked()
4. _load_unlocked() -> importlib._bootstrap.module_from_spec()
5. module_from_spec() -> ExtensionFileLoader.create_module()
6. create_module() -> _imp.create_dynamic()
(see below)
7. module_from_spec() -> importlib._bootstrap._init_module_attrs()
8. _load_unlocked(): sys.modules[name] = module
9. _load_unlocked() -> ExtensionFileLoader.exec_module()
10. exec_module() -> _imp.exec_dynamic()
(see below)
11. _load(): release import lock
...for single-phase init modules, where m_size == -1:
(6). first time (not found in _PyRuntime.imports.extensions):
A. _imp_create_dynamic_impl() -> import_find_extension()
B. _imp_create_dynamic_impl() -> _PyImport_GetModuleExportHooks()
C. _PyImport_GetModuleExportHooks(): load <module init func>
D. _imp_create_dynamic_impl() -> import_run_extension()
E. import_run_extension() -> _PyImport_RunModInitFunc()
F. _PyImport_RunModInitFunc(): call <module init func>
G. <module init func> -> PyModule_Create() -> PyModule_Create2()
-> PyModule_CreateInitialized()
H. PyModule_CreateInitialized() -> PyModule_New()
I. PyModule_CreateInitialized(): allocate mod->md_state
J. PyModule_CreateInitialized() -> PyModule_AddFunctions()
K. PyModule_CreateInitialized() -> PyModule_SetDocString()
L. PyModule_CreateInitialized(): set mod->md_def
M. <module init func>: initialize the module, etc.
N. import_run_extension()
-> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
O. import_run_extension(): set __file__
P. import_run_extension() -> update_global_state_for_extension()
Q. update_global_state_for_extension():
copy __dict__ into def->m_base.m_copy
R. update_global_state_for_extension():
add it to _PyRuntime.imports.extensions
S. import_run_extension() -> finish_singlephase_extension()
T. finish_singlephase_extension():
add it to interp->imports.modules_by_index
U. finish_singlephase_extension(): add it to sys.modules
Step (Q) is skipped for core modules (sys/builtins).
(6). subsequent times (found in _PyRuntime.imports.extensions):
A. _imp_create_dynamic_impl() -> import_find_extension()
B. import_find_extension() -> reload_singlephase_extension()
C. reload_singlephase_extension()
-> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
D. reload_singlephase_extension() -> import_add_module()
E. if name in sys.modules: use that module
F. else:
1. import_add_module() -> PyModule_NewObject()
2. import_add_module(): set it on sys.modules
G. reload_singlephase_extension(): copy the "m_copy" dict into __dict__
H. reload_singlephase_extension(): add to modules_by_index
(10). (every time):
A. noop
...for single-phase init modules, where m_size >= 0:
(6). not main interpreter and never loaded there - every time (not found in _PyRuntime.imports.extensions):
A-P. (same as for m_size == -1)
Q. _PyImport_RunModInitFunc(): set def->m_base.m_init
R. (skipped)
S-U. (same as for m_size == -1)
(6). main interpreter - first time (not found in _PyRuntime.imports.extensions):
A-P. (same as for m_size == -1)
Q. _PyImport_RunModInitFunc(): set def->m_base.m_init
R-U. (same as for m_size == -1)
(6). subsequent times (found in _PyRuntime.imports.extensions):
A. _imp_create_dynamic_impl() -> import_find_extension()
B. import_find_extension() -> reload_singlephase_extension()
C. reload_singlephase_extension()
-> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
D. reload_singlephase_extension(): call def->m_base.m_init (see above)
E. reload_singlephase_extension(): add the module to sys.modules
F. reload_singlephase_extension(): add to modules_by_index
(10). every time:
A. noop
...for multi-phase init modules from PyModInit_* (PyModuleDef):
(6). every time:
A. _imp_create_dynamic_impl() -> import_find_extension() (not found)
B. _imp_create_dynamic_impl() -> _PyImport_GetModuleExportHooks()
C. _PyImport_GetModuleExportHooks(): load <module init func>
D. _imp_create_dynamic_impl() -> import_run_extension()
E. import_run_extension() -> _PyImport_RunModInitFunc()
F. _PyImport_RunModInitFunc(): call <module init func>
G. import_run_extension() -> PyModule_FromDefAndSpec()
PyModule_FromDefAndSpec():
H. PyModule_FromDefAndSpec(): gather/check moduledef slots
I. if there's a Py_mod_create slot:
1. PyModule_FromDefAndSpec(): call its function
J. else:
1. PyModule_FromDefAndSpec() -> PyModule_NewObject()
K: PyModule_FromDefAndSpec(): set mod->md_def
L. PyModule_FromDefAndSpec() -> _add_methods_to_object()
M. PyModule_FromDefAndSpec() -> PyModule_SetDocString()
(10). every time:
A. _imp_exec_dynamic_impl() -> exec_builtin_or_dynamic()
B. if mod->md_state == NULL (including if m_size == 0):
1. exec_builtin_or_dynamic() -> PyModule_Exec()
2. PyModule_Exec(): allocate mod->md_state
3. if there's a Py_mod_exec slot:
1. PyModule_Exec(): call its function
...for multi-phase init modules from PyModExport_* (slots array):
(6). every time:
A. _imp_create_dynamic_impl() -> import_find_extension() (not found)
B. _imp_create_dynamic_impl() -> _PyImport_GetModuleExportHooks()
C. _PyImport_GetModuleExportHooks(): load <module export func>
D. _imp_create_dynamic_impl() -> import_run_modexport()
E. import_run_modexport(): call <module init func>
F. import_run_modexport() -> PyModule_FromSlotsAndSpec()
G. PyModule_FromSlotsAndSpec(): create temporary PyModuleDef-like
H. PyModule_FromSlotsAndSpec() -> PyModule_FromDefAndSpec()
(PyModule_FromDefAndSpec behaves as for PyModInit_*, above)
(10). every time: as for PyModInit_*, above
*/
This is a bit of a hack: when the shared library is loaded,
the module name is "package.module", but the module calls
PyModule_Create*() with just "module" for the name. The shared
library loader squirrels away the true name of the module in
_PyRuntime.imports.pkgcontext, and PyModule_Create*() will
substitute this (if the name actually matches).
*/
static _Py_thread_local const char *pkgcontext = NULL;
# define PKGCONTEXT pkgcontext
const char *
_PyImport_ResolveNameWithPackageContext(const char *name)
{
if (PKGCONTEXT != NULL) {
const char *p = strrchr(PKGCONTEXT, '.');
if (p != NULL && strcmp(name, p+1) == 0) {
name = PKGCONTEXT;
PKGCONTEXT = NULL;
}
}
return name;
}
const char *
_PyImport_SwapPackageContext(const char *newcontext)
{
const char *oldcontext = PKGCONTEXT;
PKGCONTEXT = newcontext;
return oldcontext;
}
#ifdef HAVE_DLOPEN
int
_PyImport_GetDLOpenFlags(PyInterpreterState *interp)
{
return FT_ATOMIC_LOAD_INT_RELAXED(DLOPENFLAGS(interp));
}
void
_PyImport_SetDLOpenFlags(PyInterpreterState *interp, int new_val)
{
FT_ATOMIC_STORE_INT_RELAXED(DLOPENFLAGS(interp), new_val);
}
#endif
static int
exec_builtin_or_dynamic(PyObject *mod) {
void *state;
if (!PyModule_Check(mod)) {
return 0;
}
state = PyModule_GetState(mod);
if (state) {
return 0;
}
return PyModule_Exec(mod);
}
static int clear_singlephase_extension(PyInterpreterState *interp,
PyObject *name, PyObject *filename);
int
_PyImport_ClearExtension(PyObject *name, PyObject *filename)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
if (clear_singlephase_extension(interp, name, filename) < 0) {
return -1;
}
return 0;
}
We support a number of kinds of single-phase init builtin/extension modules:
* "basic"
* no module state (PyModuleDef.m_size == -1)
* does not support repeated init (we use PyModuleDef.m_base.m_copy)
* may have process-global state
* the module's def is cached in _PyRuntime.imports.extensions,
by (name, filename)
* "reinit"
* no module state (PyModuleDef.m_size == 0)
* supports repeated init (m_copy is never used)
* should not have any process-global state
* its def is never cached in _PyRuntime.imports.extensions
(except, currently, under the main interpreter, for some reason)
* "with state" (almost the same as reinit)
* has module state (PyModuleDef.m_size > 0)
* supports repeated init (m_copy is never used)
* should not have any process-global state
* its def is never cached in _PyRuntime.imports.extensions
(except, currently, under the main interpreter, for some reason)
There are also variants within those classes:
* two or more modules share a PyModuleDef
* a module's init func uses another module's PyModuleDef
* a module's init func calls another's module's init func
* a module's init "func" is actually a variable statically initialized
to another module's init func
* two or modules share "methods"
* a module's init func copies another module's PyModuleDef
(with a different name)
* (basic-only) two or modules share process-global state
In the first case, where modules share a PyModuleDef, the following
notable weirdness happens:
* the module's __name__ matches the def, not the requested name
* the last module (with the same def) to be imported for the first time wins
* returned by PyState_Find_Module() (via interp->modules_by_index)
* (non-basic-only) its init func is used when re-loading any of them
(via the def's m_init)
* (basic-only) the copy of its __dict__ is used when re-loading any of them
(via the def's m_copy)
However, the following happens as expected:
* a new module object (with its own __dict__) is created for each request
* the module's __spec__ has the requested name
* the loaded module is cached in sys.modules under the requested name
* the m_index field of the shared def is not changed,
so at least PyState_FindModule() will always look in the same place
For "basic" modules there are other quirks:
* (whether sharing a def or not) when loaded the first time,
m_copy is set before _init_module_attrs() is called
in importlib._bootstrap.module_from_spec(),
so when the module is re-loaded, the previous value
for __wpec__ (and others) is reset, possibly unexpectedly.
Generally, when multiple interpreters are involved, some of the above
gets even messier.
*/
static inline void
extensions_lock_acquire(void)
{
PyMutex_Lock(&_PyRuntime.imports.extensions.mutex);
}
static inline void
extensions_lock_release(void)
{
PyMutex_Unlock(&_PyRuntime.imports.extensions.mutex);
}
loaded). To prevent initializing an extension module more than
once, we keep a static dictionary 'extensions' keyed by the tuple
(module name, module name) (for built-in modules) or by
(filename, module name) (for dynamically loaded modules), containing these
modules. A copy of the module's dictionary is stored by calling
fix_up_extension() immediately after the module initialization
function succeeds. A copy can be retrieved from there by calling
import_find_extension().
Modules which do support multiple initialization set their m_size
field to a non-negative number (indicating the size of the
module-specific state). They are still recorded in the extensions
dictionary, to avoid loading shared libraries twice.
*/
typedef struct cached_m_dict {
PyObject *copied;
int64_t interpid;
} *cached_m_dict_t;
struct extensions_cache_value {
PyModuleDef *def;
This is only set for legacy (single-phase init) extension modules
and only used for those that support multiple initializations
(m_size >= 0).
It is set by update_global_state_for_extension(). */
PyModInitFunction m_init;
This is set for all extension modules but only used for legacy ones.
(See PyInterpreterState.modules_by_index for more info.) */
Py_ssize_t m_index;
This is only set/used for legacy modules that do not support
multiple initializations.
It is set exclusively by fixup_cached_def(). */
cached_m_dict_t m_dict;
struct cached_m_dict _m_dict;
_Py_ext_module_origin origin;
#ifdef Py_GIL_DISABLED
* reinitialized from m_dict rather than calling their initialization
* function again. */
bool md_requires_gil;
#endif
};
static struct extensions_cache_value *
alloc_extensions_cache_value(void)
{
struct extensions_cache_value *value
= PyMem_RawMalloc(sizeof(struct extensions_cache_value));
if (value == NULL) {
PyErr_NoMemory();
return NULL;
}
*value = (struct extensions_cache_value){0};
return value;
}
static void
free_extensions_cache_value(struct extensions_cache_value *value)
{
PyMem_RawFree(value);
}
static Py_ssize_t
_get_cached_module_index(struct extensions_cache_value *cached)
{
assert(cached->m_index > 0);
return cached->m_index;
}
static void
fixup_cached_def(struct extensions_cache_value *value)
{
* to another module, and we're replacing them here. This can
* cause problems later if the old module is reloaded.
*
* Also, we don't decref any old cached values first when we
* replace them here, in case we need to restore them in the
* near future. Instead, the caller is responsible for wrapping
* this up by calling cleanup_old_cached_def() or
* restore_old_cached_def() if there was an error. */
PyModuleDef *def = value->def;
assert(def != NULL);
and will never be freed. Otherwise, we would incref here. */
_Py_SetImmortalUntracked((PyObject *)def);
def->m_base.m_init = value->m_init;
assert(value->m_index > 0);
_set_module_index(def, value->m_index);
* expect m_copy to be NULL. */
assert(def->m_base.m_copy == NULL
|| def->m_base.m_init == NULL
|| value->m_dict != NULL);
if (value->m_dict != NULL) {
assert(value->m_dict->copied != NULL);
def->m_base.m_copy = Py_NewRef(value->m_dict->copied);
}
}
static void
restore_old_cached_def(PyModuleDef *def, PyModuleDef_Base *oldbase)
{
def->m_base = *oldbase;
}
static void
cleanup_old_cached_def(PyModuleDef_Base *oldbase)
{
Py_XDECREF(oldbase->m_copy);
}
static void
del_cached_def(struct extensions_cache_value *value)
{
However, this decref would be problematic if the module def were
dynamically allocated, it were the last ref, and this function
were called with an interpreter other than the def's owner. */
assert(value->def == NULL || _Py_IsImmortal(value->def));
Py_XDECREF(value->def->m_base.m_copy);
value->def->m_base.m_copy = NULL;
}
static int
init_cached_m_dict(struct extensions_cache_value *value, PyObject *m_dict)
{
assert(value != NULL);
assert(value->m_dict == NULL);
if (m_dict == NULL) {
return 0;
}
assert(PyDict_Check(m_dict));
assert(value->origin != _Py_ext_module_origin_CORE);
PyInterpreterState *interp = _PyInterpreterState_GET();
assert(!is_interpreter_isolated(interp));
* interpreter. That's a problem if the interpreter has
* its own obmalloc state or if the module is successfully
* imported into such an interpreter. If the interpreter
* has its own GIL then there may be data races and
* PyImport_ClearModulesByIndex() can crash. Normally,
* a single-phase init module cannot be imported in an
* isolated interpreter, but there are ways around that.
* Hence, heere be dragons! Ideally we would instead do
* something like make a read-only, immortal copy of the
* dict using PyMem_RawMalloc() and store *that* in m_copy.
* Then we'd need to make sure to clear that when the
* runtime is finalized, rather than in
* PyImport_ClearModulesByIndex(). */
PyObject *copied = PyDict_Copy(m_dict);
if (copied == NULL) {
return -1;
}
value->_m_dict = (struct cached_m_dict){
.copied=copied,
.interpid=PyInterpreterState_GetID(interp),
};
value->m_dict = &value->_m_dict;
return 0;
}
static void
del_cached_m_dict(struct extensions_cache_value *value)
{
if (value->m_dict != NULL) {
assert(value->m_dict == &value->_m_dict);
assert(value->m_dict->copied != NULL);
* to decref the dict using the owning interpreter. */
Py_XDECREF(value->m_dict->copied);
value->m_dict = NULL;
}
}
static PyObject * get_core_module_dict(
PyInterpreterState *interp, PyObject *name, PyObject *path);
static PyObject *
get_cached_m_dict(struct extensions_cache_value *value,
PyObject *name, PyObject *path)
{
assert(value != NULL);
PyInterpreterState *interp = _PyInterpreterState_GET();
for which we don't cache m_dict. */
if (value->origin == _Py_ext_module_origin_CORE) {
return get_core_module_dict(interp, name, path);
}
assert(value->def != NULL);
PyObject *m_dict = value->def->m_base.m_copy;
Py_XINCREF(m_dict);
return m_dict;
}
static void
del_extensions_cache_value(void *raw)
{
struct extensions_cache_value *value = raw;
if (value != NULL) {
del_cached_m_dict(value);
del_cached_def(value);
free_extensions_cache_value(value);
}
}
static void *
hashtable_key_from_2_strings(PyObject *str1, PyObject *str2, const char sep)
{
const char *str1_data = _PyUnicode_AsUTF8NoNUL(str1);
const char *str2_data = _PyUnicode_AsUTF8NoNUL(str2);
if (str1_data == NULL || str2_data == NULL) {
return NULL;
}
Py_ssize_t str1_len = strlen(str1_data);
Py_ssize_t str2_len = strlen(str2_data);
assert(SIZE_MAX - str1_len - str2_len > 2);
size_t size = str1_len + 1 + str2_len + 1;
char *key = PyMem_RawMalloc(size);
if (key == NULL) {
PyErr_NoMemory();
return NULL;
}
memcpy(key, str1_data, str1_len);
key[str1_len] = sep;
memcpy(key + str1_len + 1, str2_data, str2_len);
key[size - 1] = '\0';
assert(strlen(key) == size - 1);
return key;
}
static Py_uhash_t
hashtable_hash_str(const void *key)
{
return Py_HashBuffer(key, strlen((const char *)key));
}
static int
hashtable_compare_str(const void *key1, const void *key2)
{
return strcmp((const char *)key1, (const char *)key2) == 0;
}
static void
hashtable_destroy_str(void *ptr)
{
PyMem_RawFree(ptr);
}
#ifndef NDEBUG
struct hashtable_next_match_def_data {
PyModuleDef *def;
struct extensions_cache_value *matched;
};
static int
hashtable_next_match_def(_Py_hashtable_t *ht,
const void *key, const void *value, void *user_data)
{
if (value == NULL) {
return 0;
}
struct hashtable_next_match_def_data *data
= (struct hashtable_next_match_def_data *)user_data;
struct extensions_cache_value *cur
= (struct extensions_cache_value *)value;
if (cur->def == data->def) {
data->matched = cur;
return 1;
}
return 0;
}
static struct extensions_cache_value *
_find_cached_def(PyModuleDef *def)
{
struct hashtable_next_match_def_data data = {0};
(void)_Py_hashtable_foreach(
EXTENSIONS.hashtable, hashtable_next_match_def, &data);
return data.matched;
}
#endif
#define HTSEP ':'
static int
_extensions_cache_init(void)
{
_Py_hashtable_allocator_t alloc = {PyMem_RawMalloc, PyMem_RawFree};
EXTENSIONS.hashtable = _Py_hashtable_new_full(
hashtable_hash_str,
hashtable_compare_str,
hashtable_destroy_str,
del_extensions_cache_value,
&alloc
);
if (EXTENSIONS.hashtable == NULL) {
PyErr_NoMemory();
return -1;
}
return 0;
}
static _Py_hashtable_entry_t *
_extensions_cache_find_unlocked(PyObject *path, PyObject *name,
void **p_key)
{
if (EXTENSIONS.hashtable == NULL) {
return NULL;
}
void *key = hashtable_key_from_2_strings(path, name, HTSEP);
if (key == NULL) {
return NULL;
}
_Py_hashtable_entry_t *entry =
_Py_hashtable_get_entry(EXTENSIONS.hashtable, key);
if (p_key != NULL) {
*p_key = key;
}
else {
hashtable_destroy_str(key);
}
return entry;
}
static struct extensions_cache_value *
_extensions_cache_get(PyObject *path, PyObject *name)
{
struct extensions_cache_value *value = NULL;
extensions_lock_acquire();
_Py_hashtable_entry_t *entry =
_extensions_cache_find_unlocked(path, name, NULL);
if (entry == NULL) {
goto finally;
}
value = (struct extensions_cache_value *)entry->value;
finally:
extensions_lock_release();
return value;
}
static struct extensions_cache_value *
_extensions_cache_set(PyObject *path, PyObject *name,
PyModuleDef *def, PyModInitFunction m_init,
Py_ssize_t m_index, PyObject *m_dict,
_Py_ext_module_origin origin, bool requires_gil)
{
struct extensions_cache_value *value = NULL;
void *key = NULL;
struct extensions_cache_value *newvalue = NULL;
PyModuleDef_Base olddefbase = def->m_base;
assert(def != NULL);
assert(m_init == NULL || m_dict == NULL);
* to have remained loaded, so it must be the same pointer. */
assert(def->m_base.m_init == NULL || def->m_base.m_init == m_init);
assert(def->m_base.m_copy == NULL || m_dict != NULL);
assert((origin == _Py_ext_module_origin_DYNAMIC) == (name != path));
assert(origin != _Py_ext_module_origin_CORE || m_dict == NULL);
extensions_lock_acquire();
if (EXTENSIONS.hashtable == NULL) {
if (_extensions_cache_init() < 0) {
goto finally;
}
}
_Py_hashtable_entry_t *entry =
_extensions_cache_find_unlocked(path, name, &key);
value = entry == NULL
? NULL
: (struct extensions_cache_value *)entry->value;
if (value != NULL) {
* being imported recursively from its PyInit_* or Py_mod_* function.
* (That function presumably handles returning a partially
* constructed module in such a case.)
* We can reuse the existing cache value; it is owned by the cache.
* (Entries get removed from it in exceptional circumstances,
* after interpreter shutdown, and in runtime shutdown.)
*/
goto finally_oldvalue;
}
newvalue = alloc_extensions_cache_value();
if (newvalue == NULL) {
goto finally;
}
*newvalue = (struct extensions_cache_value){
.def=def,
.m_init=m_init,
.m_index=m_index,
.origin=origin,
#ifdef Py_GIL_DISABLED
.md_requires_gil=requires_gil,
#endif
};
#ifndef Py_GIL_DISABLED
(void)requires_gil;
#endif
if (init_cached_m_dict(newvalue, m_dict) < 0) {
goto finally;
}
fixup_cached_def(newvalue);
if (entry == NULL) {
if (_Py_hashtable_set(EXTENSIONS.hashtable, key, newvalue) < 0) {
PyErr_NoMemory();
goto finally;
}
key = NULL;
}
else if (value == NULL) {
entry->value = newvalue;
}
else {
assert(value->def == def);
* to have remained loaded, so it must be the same pointer. */
assert(value->m_init == m_init);
assert((value->m_dict == NULL) == (m_dict == NULL));
Py_UNREACHABLE();
}
value = newvalue;
finally:
if (value == NULL) {
restore_old_cached_def(def, &olddefbase);
if (newvalue != NULL) {
del_extensions_cache_value(newvalue);
}
}
else {
cleanup_old_cached_def(&olddefbase);
}
finally_oldvalue:
extensions_lock_release();
if (key != NULL) {
hashtable_destroy_str(key);
}
return value;
}
static void
_extensions_cache_delete(PyObject *path, PyObject *name)
{
extensions_lock_acquire();
if (EXTENSIONS.hashtable == NULL) {
goto finally;
}
_Py_hashtable_entry_t *entry =
_extensions_cache_find_unlocked(path, name, NULL);
if (entry == NULL) {
goto finally;
}
if (entry->value == NULL) {
goto finally;
}
struct extensions_cache_value *value = entry->value;
entry->value = NULL;
del_extensions_cache_value(value);
finally:
extensions_lock_release();
}
static void
_extensions_cache_clear_all(void)
{
so we don't need to worry about the lock. */
_Py_hashtable_destroy(EXTENSIONS.hashtable);
EXTENSIONS.hashtable = NULL;
}
#undef HTSEP
static bool
check_multi_interp_extensions(PyInterpreterState *interp)
{
int override = OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp);
if (override < 0) {
return false;
}
else if (override > 0) {
return true;
}
else if (_PyInterpreterState_HasFeature(
interp, Py_RTFLAGS_MULTI_INTERP_EXTENSIONS)) {
return true;
}
return false;
}
int
_PyImport_CheckSubinterpIncompatibleExtensionAllowed(const char *name)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
if (check_multi_interp_extensions(interp)) {
assert(!_Py_IsMainInterpreter(interp));
PyErr_Format(PyExc_ImportError,
"module %s does not support loading in subinterpreters",
name);
return -1;
}
return 0;
}
#ifdef Py_GIL_DISABLED
int
_PyImport_CheckGILForModule(PyObject* module, PyObject *module_name)
{
PyThreadState *tstate = _PyThreadState_GET();
if (module == NULL) {
_PyEval_DisableGIL(tstate);
return 0;
}
if (!PyModule_Check(module) ||
((PyModuleObject *)module)->md_requires_gil)
{
if (PyModule_Check(module)) {
assert(((PyModuleObject *)module)->md_token_is_def);
}
if (_PyImport_EnableGILAndWarn(tstate, module_name) < 0) {
return -1;
}
}
else {
_PyEval_DisableGIL(tstate);
}
return 0;
}
int
_PyImport_EnableGILAndWarn(PyThreadState *tstate, PyObject *module_name)
{
if (_PyEval_EnableGILPermanent(tstate)) {
return PyErr_WarnFormat(
PyExc_RuntimeWarning,
1,
"The global interpreter lock (GIL) has been enabled to load "
"module '%U', which has not declared that it can run safely "
"without the GIL. To override this behavior and keep the GIL "
"disabled (at your own risk), run with PYTHON_GIL=0 or -Xgil=0.",
module_name
);
}
const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
if (config->enable_gil == _PyConfig_GIL_DEFAULT && config->verbose) {
PySys_FormatStderr("# loading module '%U', which requires the GIL\n",
module_name);
}
return 0;
}
#endif
static PyThreadState *
switch_to_main_interpreter(PyThreadState *tstate)
{
if (_Py_IsMainInterpreter(tstate->interp)) {
return tstate;
}
PyThreadState *main_tstate = _PyThreadState_NewBound(
_PyInterpreterState_Main(), _PyThreadState_WHENCE_EXEC);
if (main_tstate == NULL) {
return NULL;
}
#ifndef NDEBUG
PyThreadState *old_tstate = PyThreadState_Swap(main_tstate);
assert(old_tstate == tstate);
#else
(void)PyThreadState_Swap(main_tstate);
#endif
return main_tstate;
}
static void
switch_back_from_main_interpreter(PyThreadState *tstate,
PyThreadState *main_tstate,
PyObject *tempobj)
{
assert(main_tstate == PyThreadState_GET());
assert(_Py_IsMainInterpreter(main_tstate->interp));
assert(tstate->interp != main_tstate->interp);
* to the subinterpreter. */
if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
PyErr_Clear();
}
else {
PyErr_PrintEx(0);
}
}
Py_XDECREF(tempobj);
PyThreadState_Clear(main_tstate);
(void)PyThreadState_Swap(tstate);
PyThreadState_Delete(main_tstate);
}
static PyObject *
get_core_module_dict(PyInterpreterState *interp,
PyObject *name, PyObject *path)
{
if (path == name) {
assert(!PyErr_Occurred());
if (PyUnicode_CompareWithASCIIString(name, "sys") == 0) {
return Py_NewRef(interp->sysdict_copy);
}
assert(!PyErr_Occurred());
if (PyUnicode_CompareWithASCIIString(name, "builtins") == 0) {
return Py_NewRef(interp->builtins_copy);
}
assert(!PyErr_Occurred());
}
return NULL;
}
#ifndef NDEBUG
static inline int
is_core_module(PyInterpreterState *interp, PyObject *name, PyObject *path)
{
so we can't rely on get_core_module_dict() here. */
if (path == name) {
if (PyUnicode_CompareWithASCIIString(name, "sys") == 0) {
return 1;
}
if (PyUnicode_CompareWithASCIIString(name, "builtins") == 0) {
return 1;
}
}
return 0;
}
static _Py_ext_module_kind
_get_extension_kind(PyModuleDef *def, bool check_size)
{
_Py_ext_module_kind kind;
if (def == NULL) {
* from m_copy. Ideally we'd do away with this case. */
kind = _Py_ext_module_kind_SINGLEPHASE;
}
else if (def->m_slots != NULL) {
kind = _Py_ext_module_kind_MULTIPHASE;
}
else if (check_size && def->m_size == -1) {
kind = _Py_ext_module_kind_SINGLEPHASE;
}
else if (def->m_base.m_init != NULL) {
kind = _Py_ext_module_kind_SINGLEPHASE;
}
else {
kind = _Py_ext_module_kind_UNKNOWN;
}
return kind;
}
* and PyModule_FromDefAndSpec() checks m_size
* so we skip m_size. */
#define assert_multiphase_def(def) \
do { \
_Py_ext_module_kind kind = _get_extension_kind(def, false); \
assert(kind == _Py_ext_module_kind_MULTIPHASE \
\
|| kind == _Py_ext_module_kind_UNKNOWN); \
} while (0)
#define assert_singlephase_def(def) \
do { \
_Py_ext_module_kind kind = _get_extension_kind(def, true); \
assert(kind == _Py_ext_module_kind_SINGLEPHASE \
|| kind == _Py_ext_module_kind_UNKNOWN); \
} while (0)
#define assert_singlephase(cached) \
do { \
_Py_ext_module_kind kind = _get_extension_kind(cached->def, true); \
assert(kind == _Py_ext_module_kind_SINGLEPHASE); \
} while (0)
#else
#define assert_multiphase_def(def)
#define assert_singlephase_def(def)
#define assert_singlephase(cached)
#endif
struct singlephase_global_update {
PyModInitFunction m_init;
Py_ssize_t m_index;
PyObject *m_dict;
_Py_ext_module_origin origin;
bool md_requires_gil;
};
static struct extensions_cache_value *
update_global_state_for_extension(PyThreadState *tstate,
PyObject *path, PyObject *name,
PyModuleDef *def,
struct singlephase_global_update *singlephase)
{
struct extensions_cache_value *cached = NULL;
PyModInitFunction m_init = NULL;
PyObject *m_dict = NULL;
if (singlephase == NULL) {
assert(def->m_base.m_init == NULL);
assert(def->m_base.m_copy == NULL);
}
else {
if (singlephase->m_init != NULL) {
assert(singlephase->m_dict == NULL);
assert(def->m_base.m_copy == NULL);
assert(def->m_size >= 0);
m_init = singlephase->m_init;
}
else if (singlephase->m_dict == NULL) {
assert(is_core_module(tstate->interp, name, path));
assert(def->m_size == -1);
assert(def->m_base.m_copy == NULL);
assert(def->m_base.m_init == NULL);
}
else {
assert(PyDict_Check(singlephase->m_dict));
assert(def->m_size == -1);
assert(!is_core_module(tstate->interp, name, path));
assert(PyUnicode_CompareWithASCIIString(name, "sys") != 0);
assert(PyUnicode_CompareWithASCIIString(name, "builtins") != 0);
m_dict = singlephase->m_dict;
}
}
if (_Py_IsMainInterpreter(tstate->interp) || def->m_size == -1) {
#ifndef NDEBUG
cached = _extensions_cache_get(path, name);
assert(cached == NULL || cached->def == def);
#endif
cached = _extensions_cache_set(
path, name, def, m_init, singlephase->m_index, m_dict,
singlephase->origin, singlephase->md_requires_gil);
if (cached == NULL) {
return NULL;
}
}
return cached;
}
* by PyModule_FromDefAndSpec(). */
static int
finish_singlephase_extension(PyThreadState *tstate, PyObject *mod,
struct extensions_cache_value *cached,
PyObject *name, PyObject *modules)
{
assert(mod != NULL && PyModule_Check(mod));
assert(cached->def == _PyModule_GetDefOrNull(mod));
Py_ssize_t index = _get_cached_module_index(cached);
if (_modules_by_index_set(tstate->interp, index, mod) < 0) {
return -1;
}
if (modules != NULL) {
if (PyObject_SetItem(modules, name, mod) < 0) {
return -1;
}
}
return 0;
}
static PyObject *
reload_singlephase_extension(PyThreadState *tstate,
struct extensions_cache_value *cached,
struct _Py_ext_module_loader_info *info)
{
PyModuleDef *def = cached->def;
assert(def != NULL);
assert_singlephase(cached);
PyObject *mod = NULL;
in an interpreter that allows legacy modules
but is not allowed in the current interpreter. */
const char *name_buf = PyUnicode_AsUTF8(info->name);
assert(name_buf != NULL);
if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
return NULL;
}
PyObject *modules = get_modules_dict(tstate, true);
if (def->m_size == -1) {
assert(cached->m_init == NULL);
assert(def->m_base.m_init == NULL);
PyObject *m_copy = get_cached_m_dict(cached, info->name, info->path);
if (m_copy == NULL) {
assert(!PyErr_Occurred());
return NULL;
}
mod = import_add_module(tstate, info->name);
if (mod == NULL) {
Py_DECREF(m_copy);
return NULL;
}
PyObject *mdict = PyModule_GetDict(mod);
if (mdict == NULL) {
Py_DECREF(m_copy);
Py_DECREF(mod);
return NULL;
}
int rc = PyDict_Update(mdict, m_copy);
Py_DECREF(m_copy);
if (rc < 0) {
Py_DECREF(mod);
return NULL;
}
#ifdef Py_GIL_DISABLED
if (def->m_base.m_copy != NULL) {
((PyModuleObject *)mod)->md_requires_gil = cached->md_requires_gil;
}
#endif
* because _PyImport_ClearModulesByIndex() might break
* due to violating interpreter isolation.
* See the note in set_cached_m_dict().
* Until that is solved, we leave md_def set to NULL. */
assert(_PyModule_GetDefOrNull(mod) == NULL
|| _PyModule_GetDefOrNull(mod) == def);
}
else {
assert(cached->m_dict == NULL);
assert(def->m_base.m_copy == NULL);
PyModInitFunction p0 = def->m_base.m_init;
if (p0 == NULL) {
assert(!PyErr_Occurred());
return NULL;
}
struct _Py_ext_module_loader_result res;
if (_PyImport_RunModInitFunc(p0, info, &res) < 0) {
_Py_ext_module_loader_result_apply_error(&res, name_buf);
return NULL;
}
assert(!PyErr_Occurred());
assert(res.err == NULL);
assert(res.kind == _Py_ext_module_kind_SINGLEPHASE);
mod = res.module;
* Then we would probably need to update the global cache.
* However, we don't expect anyone to change the def. */
assert(res.def == def);
_Py_ext_module_loader_result_clear(&res);
if (info->filename != NULL) {
if (PyModule_AddObjectRef(mod, "__file__", info->filename) < 0) {
PyErr_Clear();
}
}
if (PyObject_SetItem(modules, info->name, mod) == -1) {
Py_DECREF(mod);
return NULL;
}
}
Py_ssize_t index = _get_cached_module_index(cached);
if (_modules_by_index_set(tstate->interp, index, mod) < 0) {
PyMapping_DelItem(modules, info->name);
Py_DECREF(mod);
return NULL;
}
return mod;
}
static PyObject *
import_find_extension(PyThreadState *tstate,
struct _Py_ext_module_loader_info *info,
struct extensions_cache_value **p_cached)
{
struct extensions_cache_value *cached
= _extensions_cache_get(info->path, info->name);
if (cached == NULL) {
return NULL;
}
assert(cached->def != NULL);
assert_singlephase(cached);
*p_cached = cached;
in an interpreter that allows legacy modules
but is not allowed in the current interpreter. */
const char *name_buf = PyUnicode_AsUTF8(info->name);
assert(name_buf != NULL);
if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
return NULL;
}
PyObject *mod = reload_singlephase_extension(tstate, cached, info);
if (mod == NULL) {
return NULL;
}
int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
if (verbose) {
PySys_FormatStderr("import %U # previously loaded (%R)\n",
info->name, info->path);
}
return mod;
}
static PyObject *
import_run_modexport(PyThreadState *tstate, PyModExportFunction ex0,
struct _Py_ext_module_loader_info *info,
PyObject *spec)
{
* and code for for single-phase modules.
*/
PySlot *slots = ex0();
if (!slots) {
if (!PyErr_Occurred()) {
PyErr_Format(
PyExc_SystemError,
"module export hook for module %R failed without setting an exception",
info->name);
}
return NULL;
}
if (PyErr_Occurred()) {
PyErr_Format(
PyExc_SystemError,
"module export hook for module %R raised unreported exception",
info->name);
}
PyObject *result = PyModule_FromSlotsAndSpec(slots, spec);
if (!result) {
return NULL;
}
if (PyModule_Check(result)) {
PyModuleObject *mod = (PyModuleObject *)result;
if (mod && !mod->md_token) {
mod->md_token = slots;
}
}
return result;
}
static PyObject *
import_run_extension(PyThreadState *tstate, PyModInitFunction p0,
struct _Py_ext_module_loader_info *info,
PyObject *spec, PyObject *modules)
{
assert(!is_core_module(tstate->interp, info->name, info->path));
PyObject *mod = NULL;
PyModuleDef *def = NULL;
struct extensions_cache_value *cached = NULL;
const char *name_buf = PyBytes_AS_STRING(info->name_encoded);
* multi-phase init until after we call its init function. Even
* in isolated interpreters (that do not support single-phase init),
* the init function will run without restriction. For multi-phase
* init modules that isn't a problem because the init function only
* runs PyModuleDef_Init() on the module's def and then returns it.
*
* However, for single-phase init the module's init function will
* create the module, create other objects (and allocate other
* memory), populate it and its module state, and initialize static
* types. Some modules store other objects and data in global C
* variables and register callbacks with the runtime/stdlib or
* even external libraries (which is part of why we can't just
* dlclose() the module in the error case). That's a problem
* for isolated interpreters since all of the above happens
* and only then * will the import fail. Memory will leak,
* callbacks will still get used, and sometimes there
* will be crashes (memory access violations
* and use-after-free).
*
* To put it another way, if the module is single-phase init
* then the import will probably break interpreter isolation
* and should fail ASAP. However, the module's init function
* will still get run. That means it may still store state
* in the shared-object/DLL address space (which never gets
* closed/cleared), including objects (e.g. static types).
* This is a problem for isolated subinterpreters since each
* has its own object allocator. If the loaded shared-object
* still holds a reference to an object after the corresponding
* interpreter has finalized then either we must let it leak
* or else any later use of that object by another interpreter
* (or across multiple init-fini cycles) will crash the process.
*
* To avoid all of that, we make sure the module's init function
* is always run first with the main interpreter active. If it was
* already the main interpreter then we can continue loading the
* module like normal. Otherwise, right after the init function,
* we take care of some import state bookkeeping, switch back
* to the subinterpreter, check for single-phase init,
* and then continue loading like normal. */
bool switched = false;
* (one that shares obmalloc/GIL with main interp),
* but there isn't a big advantage, we anticipate
* such interpreters will be increasingly uncommon,
* and the code is a bit simpler if we always switch
* to the main interpreter. */
PyThreadState *main_tstate = switch_to_main_interpreter(tstate);
if (main_tstate == NULL) {
return NULL;
}
else if (main_tstate != tstate) {
switched = true;
* by getting the main interpreter's import lock here.
* It's unlikely to matter though. */
}
struct _Py_ext_module_loader_result res;
int rc = _PyImport_RunModInitFunc(p0, info, &res);
bool main_error = false;
if (rc < 0) {
assert(res.module == NULL);
}
else {
assert(!PyErr_Occurred());
assert(res.err == NULL);
mod = res.module;
res.module = NULL;
def = res.def;
assert(def != NULL);
* while still using the main interpreter. */
if (res.kind == _Py_ext_module_kind_SINGLEPHASE) {
if (info->filename != NULL) {
PyObject *filename = NULL;
if (switched) {
filename = _PyUnicode_Copy(info->filename);
if (filename == NULL) {
main_error = true;
goto main_finally;
}
}
else {
filename = Py_NewRef(info->filename);
}
PyInterpreterState *interp = _PyInterpreterState_GET();
_PyUnicode_InternImmortal(interp, &filename);
if (PyModule_AddObjectRef(mod, "__file__", filename) < 0) {
PyErr_Clear();
}
}
assert(def->m_base.m_index != 0);
struct singlephase_global_update singlephase = {
.m_index=def->m_base.m_index,
.origin=info->origin,
#ifdef Py_GIL_DISABLED
.md_requires_gil=((PyModuleObject *)mod)->md_requires_gil,
#endif
};
if (def->m_size == -1) {
assert(def->m_base.m_init == NULL);
singlephase.m_dict = PyModule_GetDict(mod);
assert(singlephase.m_dict != NULL);
}
else {
assert(def->m_size >= 0);
assert(def->m_base.m_copy == NULL);
singlephase.m_init = p0;
}
cached = update_global_state_for_extension(
main_tstate, info->path, info->name, def, &singlephase);
if (cached == NULL) {
assert(PyErr_Occurred());
main_error = true;
goto main_finally;
}
}
}
main_finally:
if (rc < 0) {
_Py_ext_module_loader_result_apply_error(&res, name_buf);
}
if (switched) {
if (rc < 0 || main_error) {
assert(PyErr_Occurred());
PyErr_FormatUnraisable("Exception while importing from subinterpreter");
}
assert(main_tstate != tstate);
switch_back_from_main_interpreter(tstate, main_tstate, mod);
* reloaded in the subinterpreter. */
mod = NULL;
if (rc < 0 || main_error) {
PyErr_SetString(PyExc_ImportError,
"failed to import from subinterpreter due to exception");
goto error;
}
}
if (rc < 0) {
goto error;
}
if (main_error) {
goto error;
}
if (res.kind == _Py_ext_module_kind_MULTIPHASE) {
assert_multiphase_def(def);
assert(mod == NULL);
* to _PyImport_GetModuleExportHooks() and _PyImport_RunModInitFunc(). */
mod = PyModule_FromDefAndSpec(def, spec);
if (mod == NULL) {
goto error;
}
}
else {
assert(res.kind == _Py_ext_module_kind_SINGLEPHASE);
assert_singlephase_def(def);
if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
goto error;
}
assert(!PyErr_Occurred());
if (switched) {
* function, so now we will "reload" the module from the
* cached data using the original subinterpreter. */
assert(mod == NULL);
mod = reload_singlephase_extension(tstate, cached, info);
if (mod == NULL) {
goto error;
}
assert(!PyErr_Occurred());
assert(PyModule_Check(mod));
}
else {
assert(mod != NULL);
assert(PyModule_Check(mod));
PyObject *modules = get_modules_dict(tstate, true);
if (finish_singlephase_extension(
tstate, mod, cached, info->name, modules) < 0)
{
goto error;
}
}
}
_Py_ext_module_loader_result_clear(&res);
return mod;
error:
Py_XDECREF(mod);
_Py_ext_module_loader_result_clear(&res);
return NULL;
}
static int
clear_singlephase_extension(PyInterpreterState *interp,
PyObject *name, PyObject *path)
{
struct extensions_cache_value *cached = _extensions_cache_get(path, name);
if (cached == NULL) {
if (PyErr_Occurred()) {
return -1;
}
return 0;
}
PyModuleDef *def = cached->def;
def->m_base.m_init = NULL;
Py_CLEAR(def->m_base.m_copy);
def->m_base.m_index = 0;
Py_ssize_t index = _get_cached_module_index(cached);
if (_modules_by_index_check(interp, index) == NULL) {
if (_modules_by_index_clear_one(interp, index) < 0) {
return -1;
}
}
* See the note in import_run_extension(). */
PyThreadState *tstate = PyThreadState_GET();
PyThreadState *main_tstate = switch_to_main_interpreter(tstate);
if (main_tstate == NULL) {
return -1;
}
_extensions_cache_delete(path, name);
if (main_tstate != tstate) {
switch_back_from_main_interpreter(tstate, main_tstate, NULL);
}
return 0;
}
int
_PyImport_FixupBuiltin(PyThreadState *tstate, PyObject *mod, const char *name,
PyObject *modules)
{
int res = -1;
assert(mod != NULL && PyModule_Check(mod));
PyObject *nameobj;
nameobj = PyUnicode_InternFromString(name);
if (nameobj == NULL) {
return -1;
}
PyModuleDef *def = _PyModule_GetDefOrNull(mod);
if (def == NULL) {
assert(!PyErr_Occurred());
PyErr_BadInternalCall();
goto finally;
}
* (sys and builtins). These modules are single-phase init with no
* module state, but we also don't populate def->m_base.m_copy
* for them. */
assert(is_core_module(tstate->interp, nameobj, nameobj));
assert_singlephase_def(def);
assert(def->m_size == -1);
assert(def->m_base.m_copy == NULL);
assert(def->m_base.m_index >= 0);
* so we have to do the extra check to make sure the module
* isn't already in the global cache before calling
* update_global_state_for_extension(). */
struct extensions_cache_value *cached
= _extensions_cache_get(nameobj, nameobj);
if (cached == NULL) {
struct singlephase_global_update singlephase = {
.m_index=def->m_base.m_index,
.m_dict=NULL,
.origin=_Py_ext_module_origin_CORE,
#ifdef Py_GIL_DISABLED
.md_requires_gil=false,
#endif
};
cached = update_global_state_for_extension(
tstate, nameobj, nameobj, def, &singlephase);
if (cached == NULL) {
goto finally;
}
}
if (finish_singlephase_extension(tstate, mod, cached, nameobj, modules) < 0) {
goto finally;
}
res = 0;
finally:
Py_DECREF(nameobj);
return res;
}
static int
is_builtin(PyObject *name)
{
int i;
struct _inittab *inittab = INITTAB;
for (i = 0; inittab[i].name != NULL; i++) {
if (_PyUnicode_EqualToASCIIString(name, inittab[i].name)) {
if (inittab[i].initfunc == NULL)
return -1;
else
return 1;
}
}
return 0;
}
static struct _inittab*
lookup_inittab_entry(const struct _Py_ext_module_loader_info* info)
{
for (struct _inittab *p = INITTAB; p->name != NULL; p++) {
if (_PyUnicode_EqualToASCIIString(info->name, p->name)) {
return p;
}
}
return NULL;
}
static PyObject*
create_builtin(
PyThreadState *tstate, PyObject *name,
PyObject *spec,
PyModInitFunction initfunc)
{
struct _Py_ext_module_loader_info info;
if (_Py_ext_module_loader_info_init_for_builtin(&info, name) < 0) {
return NULL;
}
struct extensions_cache_value *cached = NULL;
PyObject *mod = import_find_extension(tstate, &info, &cached);
if (mod != NULL) {
assert(!_PyErr_Occurred(tstate));
assert(cached != NULL);
assert(_PyModule_GetDefOrNull(mod) == NULL
|| cached->def == _PyModule_GetDefOrNull(mod));
assert_singlephase(cached);
goto finally;
}
else if (_PyErr_Occurred(tstate)) {
goto finally;
}
* but def->m_base.m_copy was cleared (e.g. subinterp fini)
* then we have to do a little dance here. */
if (cached != NULL) {
assert(cached->def->m_base.m_copy == NULL);
_extensions_cache_delete(info.path, info.name);
}
PyModInitFunction p0 = NULL;
if (initfunc == NULL) {
struct _inittab *entry = lookup_inittab_entry(&info);
if (entry == NULL) {
mod = NULL;
_PyErr_SetModuleNotFoundError(name);
goto finally;
}
p0 = (PyModInitFunction)entry->initfunc;
}
else {
p0 = initfunc;
}
if (p0 == NULL) {
assert(is_core_module(tstate->interp, info.name, info.path));
mod = import_add_module(tstate, info.name);
goto finally;
}
#ifdef Py_GIL_DISABLED
_PyEval_EnableGILTransient(tstate);
#endif
mod = import_run_extension(
tstate, p0, &info, spec, get_modules_dict(tstate, true));
#ifdef Py_GIL_DISABLED
if (_PyImport_CheckGILForModule(mod, info.name) < 0) {
Py_CLEAR(mod);
goto finally;
}
#endif
finally:
_Py_ext_module_loader_info_clear(&info);
return mod;
}
PyObject*
PyImport_CreateModuleFromInitfunc(
PyObject *spec, PyObject *(*initfunc)(void))
{
if (initfunc == NULL) {
PyErr_BadInternalCall();
return NULL;
}
PyThreadState *tstate = _PyThreadState_GET();
PyObject *name = PyObject_GetAttr(spec, &_Py_ID(name));
if (name == NULL) {
return NULL;
}
if (!PyUnicode_Check(name)) {
PyErr_Format(PyExc_TypeError,
"spec name must be string, not %T", name);
Py_DECREF(name);
return NULL;
}
PyObject *mod = create_builtin(tstate, name, spec, initfunc);
Py_DECREF(name);
return mod;
}
to the table of built-in modules. This should normally be called
*before* Py_Initialize(). When the table resize fails, -1 is
returned and the existing table is unchanged.
After a similar function by Just van Rossum. */
int
PyImport_ExtendInittab(struct _inittab *newtab)
{
struct _inittab *p;
size_t i, n;
int res = 0;
if (INITTAB != NULL) {
Py_FatalError("PyImport_ExtendInittab() may not be called after Py_Initialize()");
}
for (n = 0; newtab[n].name != NULL; n++)
;
if (n == 0)
return 0;
for (i = 0; PyImport_Inittab[i].name != NULL; i++)
;
to release the memory in _PyImport_Fini2() */
p = NULL;
if (i + n <= SIZE_MAX / sizeof(struct _inittab) - 1) {
size_t size = sizeof(struct _inittab) * (i + n + 1);
p = _PyMem_DefaultRawRealloc(inittab_copy, size);
}
if (p == NULL) {
res = -1;
goto done;
}
to PyImport_ExtendInittab(). */
if (inittab_copy != PyImport_Inittab) {
memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab));
}
memcpy(p + i, newtab, (n + 1) * sizeof(struct _inittab));
PyImport_Inittab = inittab_copy = p;
done:
return res;
}
int
PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void))
{
struct _inittab newtab[2];
if (INITTAB != NULL) {
Py_FatalError("PyImport_AppendInittab() may not be called after Py_Initialize()");
}
memset(newtab, '\0', sizeof newtab);
newtab[0].name = name;
newtab[0].initfunc = initfunc;
return PyImport_ExtendInittab(newtab);
}
static int
init_builtin_modules_table(void)
{
size_t size;
for (size = 0; PyImport_Inittab[size].name != NULL; size++)
;
size++;
struct _inittab *copied = _PyMem_DefaultRawMalloc(size * sizeof(struct _inittab));
if (copied == NULL) {
return -1;
}
memcpy(copied, PyImport_Inittab, size * sizeof(struct _inittab));
INITTAB = copied;
return 0;
}
static void
fini_builtin_modules_table(void)
{
struct _inittab *inittab = INITTAB;
INITTAB = NULL;
_PyMem_DefaultRawFree(inittab);
}
PyObject *
_PyImport_GetBuiltinModuleNames(void)
{
PyObject *list = PyList_New(0);
if (list == NULL) {
return NULL;
}
struct _inittab *inittab = INITTAB;
for (Py_ssize_t i = 0; inittab[i].name != NULL; i++) {
PyObject *name = PyUnicode_FromString(inittab[i].name);
if (name == NULL) {
Py_DECREF(list);
return NULL;
}
if (PyList_Append(list, name) < 0) {
Py_DECREF(name);
Py_DECREF(list);
return NULL;
}
Py_DECREF(name);
}
return list;
}
long
PyImport_GetMagicNumber(void)
{
return PYC_MAGIC_NUMBER_TOKEN;
}
extern const char * _PySys_ImplCacheTag;
const char *
PyImport_GetMagicTag(void)
{
return _PySys_ImplCacheTag;
}
* WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is
* removed from sys.modules, to avoid leaving damaged module objects
* in sys.modules. The caller may wish to restore the original
* module object (if any) in this case; PyImport_ReloadModule is an
* example.
*
* Note that PyImport_ExecCodeModuleWithPathnames() is the preferred, richer
* interface. The other two exist primarily for backward compatibility.
*/
PyObject *
PyImport_ExecCodeModule(const char *name, PyObject *co)
{
return PyImport_ExecCodeModuleWithPathnames(
name, co, (char *)NULL, (char *)NULL);
}
PyObject *
PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname)
{
return PyImport_ExecCodeModuleWithPathnames(
name, co, pathname, (char *)NULL);
}
PyObject *
PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co,
const char *pathname,
const char *cpathname)
{
PyObject *m = NULL;
PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL;
nameobj = PyUnicode_FromString(name);
if (nameobj == NULL)
return NULL;
if (cpathname != NULL) {
cpathobj = PyUnicode_DecodeFSDefault(cpathname);
if (cpathobj == NULL)
goto error;
}
else
cpathobj = NULL;
if (pathname != NULL) {
pathobj = PyUnicode_DecodeFSDefault(pathname);
if (pathobj == NULL)
goto error;
}
else if (cpathobj != NULL) {
PyInterpreterState *interp = _PyInterpreterState_GET();
if (interp == NULL) {
Py_FatalError("no current interpreter");
}
external= PyObject_GetAttrString(IMPORTLIB(interp),
"_bootstrap_external");
if (external != NULL) {
pathobj = PyObject_CallMethodOneArg(
external, &_Py_ID(_get_sourcefile), cpathobj);
Py_DECREF(external);
}
if (pathobj == NULL)
PyErr_Clear();
}
else
pathobj = NULL;
m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj);
error:
Py_DECREF(nameobj);
Py_XDECREF(pathobj);
Py_XDECREF(cpathobj);
return m;
}
static PyObject *
module_dict_for_exec(PyThreadState *tstate, PyObject *name)
{
PyObject *m, *d;
m = import_add_module(tstate, name);
if (m == NULL)
return NULL;
and re-use its dict to exec the new code. */
d = PyModule_GetDict(m);
int r = PyDict_Contains(d, &_Py_ID(__builtins__));
if (r == 0) {
r = PyDict_SetItem(d, &_Py_ID(__builtins__), PyEval_GetBuiltins());
}
if (r < 0) {
remove_module(tstate, name);
Py_DECREF(m);
return NULL;
}
Py_INCREF(d);
Py_DECREF(m);
return d;
}
static PyObject *
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(tstate, name);
return NULL;
}
Py_DECREF(v);
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;
}
PyObject*
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
PyObject *cpathname)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *d, *external, *res;
d = module_dict_for_exec(tstate, name);
if (d == NULL) {
return NULL;
}
if (pathname == NULL) {
pathname = ((PyCodeObject *)co)->co_filename;
}
external = PyObject_GetAttrString(IMPORTLIB(tstate->interp),
"_bootstrap_external");
if (external == NULL) {
Py_DECREF(d);
return NULL;
}
res = PyObject_CallMethodObjArgs(external, &_Py_ID(_fix_up_module),
d, name, pathname, cpathname, NULL);
Py_DECREF(external);
if (res != NULL) {
Py_DECREF(res);
res = exec_code_in_module(tstate, name, d, co);
}
Py_DECREF(d);
return res;
}
static void
update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname)
{
PyObject *constants, *tmp;
Py_ssize_t i, n;
if (PyUnicode_Compare(co->co_filename, oldname))
return;
Py_XSETREF(co->co_filename, Py_NewRef(newname));
constants = co->co_consts;
n = PyTuple_GET_SIZE(constants);
for (i = 0; i < n; i++) {
tmp = PyTuple_GET_ITEM(constants, i);
if (PyCode_Check(tmp))
update_code_filenames((PyCodeObject *)tmp,
oldname, newname);
}
}
static void
update_compiled_module(PyCodeObject *co, PyObject *newname)
{
PyObject *oldname;
if (PyUnicode_Compare(co->co_filename, newname) == 0)
return;
oldname = co->co_filename;
Py_INCREF(oldname);
update_code_filenames(co, oldname, newname);
Py_DECREF(oldname);
}
to the original module name. If it is an alias but the original
module isn't known then "alias" is set to NULL while true is returned. */
static bool
resolve_module_alias(const char *name, const struct _module_alias *aliases,
const char **alias)
{
const struct _module_alias *entry;
for (entry = aliases; ; entry++) {
if (entry->name == NULL) {
return false;
}
if (strcmp(name, entry->name) == 0) {
if (alias != NULL) {
*alias = entry->orig;
}
return true;
}
}
}
static bool
use_frozen(void)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
int override = OVERRIDE_FROZEN_MODULES(interp);
if (override > 0) {
return true;
}
else if (override < 0) {
return false;
}
else {
return interp->config.use_frozen_modules;
}
}
static PyObject *
list_frozen_module_names(void)
{
PyObject *names = PyList_New(0);
if (names == NULL) {
return NULL;
}
bool enabled = use_frozen();
const struct _frozen *p;
#define ADD_MODULE(name) \
do { \
PyObject *nameobj = PyUnicode_FromString(name); \
if (nameobj == NULL) { \
goto error; \
} \
int res = PyList_Append(names, nameobj); \
Py_DECREF(nameobj); \
if (res != 0) { \
goto error; \
} \
} while(0)
for (p = _PyImport_FrozenBootstrap; ; p++) {
if (p->name == NULL) {
break;
}
ADD_MODULE(p->name);
}
for (p = _PyImport_FrozenStdlib; ; p++) {
if (p->name == NULL) {
break;
}
if (enabled) {
ADD_MODULE(p->name);
}
}
for (p = _PyImport_FrozenTest; ; p++) {
if (p->name == NULL) {
break;
}
if (enabled) {
ADD_MODULE(p->name);
}
}
#undef ADD_MODULE
if (PyImport_FrozenModules != NULL) {
for (p = PyImport_FrozenModules; ; p++) {
if (p->name == NULL) {
break;
}
PyObject *nameobj = PyUnicode_FromString(p->name);
if (nameobj == NULL) {
goto error;
}
int found = PySequence_Contains(names, nameobj);
if (found < 0) {
Py_DECREF(nameobj);
goto error;
}
else if (found) {
Py_DECREF(nameobj);
}
else {
int res = PyList_Append(names, nameobj);
Py_DECREF(nameobj);
if (res != 0) {
goto error;
}
}
}
}
return names;
error:
Py_DECREF(names);
return NULL;
}
typedef enum {
FROZEN_OKAY,
FROZEN_BAD_NAME,
FROZEN_NOT_FOUND,
FROZEN_DISABLED,
FROZEN_EXCLUDED,
(module is present but marked as unimportable, stops search). */
FROZEN_INVALID,
(eg. does not contain executable code). */
} frozen_status;
static inline void
set_frozen_error(frozen_status status, PyObject *modname)
{
const char *err = NULL;
switch (status) {
case FROZEN_BAD_NAME:
case FROZEN_NOT_FOUND:
err = "No such frozen object named %R";
break;
case FROZEN_DISABLED:
err = "Frozen modules are disabled and the frozen object named %R is not essential";
break;
case FROZEN_EXCLUDED:
err = "Excluded frozen object named %R";
break;
case FROZEN_INVALID:
err = "Frozen object named %R is invalid";
break;
case FROZEN_OKAY:
break;
default:
Py_UNREACHABLE();
}
if (err != NULL) {
PyObject *msg = PyUnicode_FromFormat(err, modname);
if (msg == NULL) {
PyErr_Clear();
}
PyErr_SetImportError(msg, modname, NULL);
Py_XDECREF(msg);
}
}
static const struct _frozen *
look_up_frozen(const char *name)
{
const struct _frozen *p;
for (p = _PyImport_FrozenBootstrap; ; p++) {
if (p->name == NULL) {
break;
}
if (strcmp(name, p->name) == 0) {
return p;
}
}
if (PyImport_FrozenModules != NULL) {
for (p = PyImport_FrozenModules; ; p++) {
if (p->name == NULL) {
break;
}
if (strcmp(name, p->name) == 0) {
return p;
}
}
}
if (use_frozen()) {
for (p = _PyImport_FrozenStdlib; ; p++) {
if (p->name == NULL) {
break;
}
if (strcmp(name, p->name) == 0) {
return p;
}
}
for (p = _PyImport_FrozenTest; ; p++) {
if (p->name == NULL) {
break;
}
if (strcmp(name, p->name) == 0) {
return p;
}
}
}
return NULL;
}
struct frozen_info {
PyObject *nameobj;
const char *data;
Py_ssize_t size;
bool is_package;
bool is_alias;
const char *origname;
};
static frozen_status
find_frozen(PyObject *nameobj, struct frozen_info *info)
{
if (info != NULL) {
memset(info, 0, sizeof(*info));
}
if (nameobj == NULL || nameobj == Py_None) {
return FROZEN_BAD_NAME;
}
const char *name = _PyUnicode_AsUTF8NoNUL(nameobj);
if (name == NULL) {
PyErr_Clear();
return FROZEN_BAD_NAME;
}
const struct _frozen *p = look_up_frozen(name);
if (p == NULL) {
return FROZEN_NOT_FOUND;
}
if (info != NULL) {
info->nameobj = nameobj;
info->data = (const char *)p->code;
info->size = p->size;
info->is_package = p->is_package;
if (p->size < 0) {
info->size = -(p->size);
info->is_package = true;
}
info->origname = name;
info->is_alias = resolve_module_alias(name, _PyImport_FrozenAliases,
&info->origname);
}
if (p->code == NULL) {
return FROZEN_EXCLUDED;
}
if (p->code[0] == '\0' || p->size == 0) {
return FROZEN_INVALID;
}
return FROZEN_OKAY;
}
static PyObject *
unmarshal_frozen_code(PyInterpreterState *interp, struct frozen_info *info)
{
PyObject *co = PyMarshal_ReadObjectFromString(info->data, info->size);
if (co == NULL) {
PyErr_Clear();
set_frozen_error(FROZEN_INVALID, info->nameobj);
return NULL;
}
if (!PyCode_Check(co)) {
PyErr_Format(PyExc_TypeError,
"frozen object %R is not a code object",
info->nameobj);
Py_DECREF(co);
return NULL;
}
return co;
}
Return 1 for success, 0 if the module is not found, and -1 with
an exception set if the initialization failed.
This function is also used from frozenmain.c */
int
PyImport_ImportFrozenModuleObject(PyObject *name)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *co, *m, *d = NULL;
int err;
struct frozen_info info;
frozen_status status = find_frozen(name, &info);
if (status == FROZEN_NOT_FOUND || status == FROZEN_DISABLED) {
return 0;
}
else if (status == FROZEN_BAD_NAME) {
return 0;
}
else if (status != FROZEN_OKAY) {
set_frozen_error(status, name);
return -1;
}
co = unmarshal_frozen_code(tstate->interp, &info);
if (co == NULL) {
return -1;
}
if (info.is_package) {
PyObject *l;
m = import_add_module(tstate, name);
if (m == NULL)
goto err_return;
d = PyModule_GetDict(m);
l = PyList_New(0);
if (l == NULL) {
Py_DECREF(m);
goto err_return;
}
err = PyDict_SetItemString(d, "__path__", l);
Py_DECREF(l);
Py_DECREF(m);
if (err != 0)
goto err_return;
}
d = module_dict_for_exec(tstate, name);
if (d == NULL) {
goto err_return;
}
m = exec_code_in_module(tstate, name, d, co);
if (m == NULL) {
goto err_return;
}
Py_DECREF(m);
PyObject *origname;
if (info.origname) {
origname = PyUnicode_FromString(info.origname);
if (origname == NULL) {
goto err_return;
}
}
else {
origname = Py_NewRef(Py_None);
}
err = PyDict_SetItemString(d, "__origname__", origname);
Py_DECREF(origname);
if (err != 0) {
goto err_return;
}
Py_DECREF(d);
Py_DECREF(co);
return 1;
err_return:
Py_XDECREF(d);
Py_DECREF(co);
return -1;
}
int
PyImport_ImportFrozenModule(const char *name)
{
PyObject *nameobj;
int ret;
nameobj = PyUnicode_InternFromString(name);
if (nameobj == NULL)
return -1;
ret = PyImport_ImportFrozenModuleObject(nameobj);
Py_DECREF(nameobj);
return ret;
}
_imp.exec_builtin() since importlib is not initialized yet. Initializing
importlib requires the _imp module: this function fix the bootstrap issue.
*/
static PyObject*
bootstrap_imp(PyThreadState *tstate)
{
PyObject *name = PyUnicode_FromString("_imp");
if (name == NULL) {
return NULL;
}
PyObject *attrs = Py_BuildValue("{sO}", "name", name);
if (attrs == NULL) {
goto error;
}
PyObject *spec = _PyNamespace_New(attrs);
Py_DECREF(attrs);
if (spec == NULL) {
goto error;
}
PyObject *mod = create_builtin(tstate, name, spec, NULL);
Py_CLEAR(name);
Py_DECREF(spec);
if (mod == NULL) {
goto error;
}
assert(mod != Py_None);
if (exec_builtin_or_dynamic(mod) < 0) {
Py_DECREF(mod);
goto error;
}
return mod;
error:
Py_XDECREF(name);
return NULL;
}
call this twice without an intervening Py_FinalizeEx() call. When
initializations fail, a fatal error is issued and the function does
not return. On return, the first thread and interpreter state have
been created.
Locking: you must hold the interpreter lock while calling this.
(If the lock has not yet been initialized, that's equivalent to
having the lock, but you cannot use multiple threads.)
*/
static int
init_importlib(PyThreadState *tstate, PyObject *sysmod)
{
assert(!_PyErr_Occurred(tstate));
PyInterpreterState *interp = tstate->interp;
int verbose = _PyInterpreterState_GetConfig(interp)->verbose;
if (verbose) {
PySys_FormatStderr("import _frozen_importlib # frozen\n");
}
if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) {
return -1;
}
PyObject *importlib = PyImport_AddModuleRef("_frozen_importlib");
if (importlib == NULL) {
return -1;
}
IMPORTLIB(interp) = importlib;
if (verbose) {
PySys_FormatStderr("import _imp # builtin\n");
}
PyObject *imp_mod = bootstrap_imp(tstate);
if (imp_mod == NULL) {
return -1;
}
if (_PyImport_SetModuleString("_imp", imp_mod) < 0) {
Py_DECREF(imp_mod);
return -1;
}
PyObject *value = PyObject_CallMethod(importlib, "_install",
"OO", sysmod, imp_mod);
Py_DECREF(imp_mod);
if (value == NULL) {
return -1;
}
Py_DECREF(value);
assert(!_PyErr_Occurred(tstate));
return 0;
}
static int
init_importlib_external(PyInterpreterState *interp)
{
PyObject *value;
value = PyObject_CallMethod(IMPORTLIB(interp),
"_install_external_importers", "");
if (value == NULL) {
return -1;
}
Py_DECREF(value);
return 0;
}
PyObject *
_PyImport_GetImportlibLoader(PyInterpreterState *interp,
const char *loader_name)
{
return PyObject_GetAttrString(IMPORTLIB(interp), loader_name);
}
PyObject *
_PyImport_GetImportlibExternalLoader(PyInterpreterState *interp,
const char *loader_name)
{
PyObject *bootstrap = PyObject_GetAttrString(IMPORTLIB(interp),
"_bootstrap_external");
if (bootstrap == NULL) {
return NULL;
}
PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name);
Py_DECREF(bootstrap);
return loader_type;
}
PyObject *
_PyImport_BlessMyLoader(PyInterpreterState *interp, PyObject *module_globals)
{
PyObject *external = PyObject_GetAttrString(IMPORTLIB(interp),
"_bootstrap_external");
if (external == NULL) {
return NULL;
}
PyObject *loader = PyObject_CallMethod(external, "_bless_my_loader",
"O", module_globals, NULL);
Py_DECREF(external);
return loader;
}
PyObject *
_PyImport_ImportlibModuleRepr(PyInterpreterState *interp, PyObject *m)
{
return PyObject_CallMethod(IMPORTLIB(interp), "_module_repr", "O", m);
}
possibly by fetching it from the path_importer_cache dict. If it
wasn't yet cached, traverse path_hooks until a hook is found
that can handle the path item. Return None if no hook could;
this tells our caller that the path based finder could not find
a finder for this path item. Cache the result in
path_importer_cache. */
static PyObject *
get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache,
PyObject *path_hooks, PyObject *p)
{
PyObject *importer;
Py_ssize_t j, nhooks;
if (!PyList_Check(path_hooks)) {
PyErr_SetString(PyExc_RuntimeError, "sys.path_hooks is not a list");
return NULL;
}
if (!PyDict_Check(path_importer_cache)) {
PyErr_SetString(PyExc_RuntimeError, "sys.path_importer_cache is not a dict");
return NULL;
}
nhooks = PyList_Size(path_hooks);
if (nhooks < 0)
return NULL;
if (PyDict_GetItemRef(path_importer_cache, p, &importer) != 0) {
return importer;
}
if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0)
return NULL;
for (j = 0; j < nhooks; j++) {
PyObject *hook = PyList_GetItem(path_hooks, j);
if (hook == NULL)
return NULL;
importer = PyObject_CallOneArg(hook, p);
if (importer != NULL)
break;
if (!_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) {
return NULL;
}
_PyErr_Clear(tstate);
}
if (importer == NULL) {
Py_RETURN_NONE;
}
if (PyDict_SetItem(path_importer_cache, p, importer) < 0) {
Py_DECREF(importer);
return NULL;
}
return importer;
}
PyObject *
PyImport_GetImporter(PyObject *path)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *path_importer_cache = PySys_GetAttrString("path_importer_cache");
if (path_importer_cache == NULL) {
return NULL;
}
PyObject *path_hooks = PySys_GetAttrString("path_hooks");
if (path_hooks == NULL) {
Py_DECREF(path_importer_cache);
return NULL;
}
PyObject *importer = get_path_importer(tstate, path_importer_cache, path_hooks, path);
Py_DECREF(path_hooks);
Py_DECREF(path_importer_cache);
return importer;
}
int
_PyImport_InitDefaultImportFunc(PyInterpreterState *interp)
{
PyObject *import_func;
if (PyDict_GetItemStringRef(interp->builtins, "__import__", &import_func) <= 0) {
return -1;
}
IMPORT_FUNC(interp) = import_func;
if (PyDict_GetItemStringRef(interp->builtins, "__lazy_import__",
&import_func) <= 0) {
return -1;
}
LAZY_IMPORT_FUNC(interp) = import_func;
return 0;
}
int
_PyImport_IsDefaultImportFunc(PyInterpreterState *interp, PyObject *func)
{
return func == IMPORT_FUNC(interp);
}
int
_PyImport_IsDefaultLazyImportFunc(PyInterpreterState *interp, PyObject *func)
{
return func == LAZY_IMPORT_FUNC(interp);
}
its module object WITH INCREMENTED REFERENCE COUNT */
PyObject *
PyImport_ImportModule(const char *name)
{
PyObject *pname;
PyObject *result;
pname = PyUnicode_FromString(name);
if (pname == NULL)
return NULL;
result = PyImport_Import(pname);
Py_DECREF(pname);
return result;
}
*
* At first it tries to fetch the module from sys.modules. If the module was
* never loaded before it loads it with PyImport_ImportModule() unless another
* thread holds the import lock. In the latter case the function raises an
* ImportError instead of blocking.
*
* Returns the module object with incremented ref count.
*
* Removed in 3.15, but kept for stable ABI compatibility.
*/
PyAPI_FUNC(PyObject *)
PyImport_ImportModuleNoBlock(const char *name)
{
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"PyImport_ImportModuleNoBlock() is deprecated and scheduled for "
"removal in Python 3.15. Use PyImport_ImportModule() instead.", 1))
{
return NULL;
}
return PyImport_ImportModule(name);
}
* except in Verbose mode. */
static void
remove_importlib_frames(PyThreadState *tstate)
{
const char *importlib_filename = "<frozen importlib._bootstrap>";
const char *external_filename = "<frozen importlib._bootstrap_external>";
const char *remove_frames = "_call_with_frames_removed";
int always_trim = 0;
int in_importlib = 0;
PyObject **prev_link, **outer_link = NULL;
PyObject *base_tb = NULL;
from the traceback. We always trim chunks
which end with a call to "_call_with_frames_removed". */
PyObject *exc = _PyErr_GetRaisedException(tstate);
if (exc == NULL || _PyInterpreterState_GetConfig(tstate->interp)->verbose) {
goto done;
}
if (PyType_IsSubtype(Py_TYPE(exc), (PyTypeObject *) PyExc_ImportError)) {
always_trim = 1;
}
assert(PyExceptionInstance_Check(exc));
base_tb = PyException_GetTraceback(exc);
prev_link = &base_tb;
PyObject *tb = base_tb;
while (tb != NULL) {
assert(PyTraceBack_Check(tb));
PyTracebackObject *traceback = (PyTracebackObject *)tb;
PyObject *next = (PyObject *) traceback->tb_next;
PyFrameObject *frame = traceback->tb_frame;
PyCodeObject *code = PyFrame_GetCode(frame);
int now_in_importlib;
now_in_importlib = _PyUnicode_EqualToASCIIString(code->co_filename, importlib_filename) ||
_PyUnicode_EqualToASCIIString(code->co_filename, external_filename);
if (now_in_importlib && !in_importlib) {
outer_link = prev_link;
}
in_importlib = now_in_importlib;
if (in_importlib &&
(always_trim ||
_PyUnicode_EqualToASCIIString(code->co_name, remove_frames))) {
Py_XSETREF(*outer_link, Py_XNewRef(next));
prev_link = outer_link;
}
else {
prev_link = (PyObject **) &traceback->tb_next;
}
Py_DECREF(code);
tb = next;
}
if (base_tb == NULL) {
base_tb = Py_None;
Py_INCREF(Py_None);
}
PyException_SetTraceback(exc, base_tb);
done:
Py_XDECREF(base_tb);
_PyErr_SetRaisedException(tstate, exc);
}
static PyObject *
resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level)
{
PyObject *abs_name;
PyObject *package = NULL;
PyObject *spec = NULL;
Py_ssize_t last_dot;
PyObject *base;
int level_up;
if (globals == NULL) {
_PyErr_SetString(tstate, PyExc_KeyError, "'__name__' not in globals");
goto error;
}
if (!PyAnyDict_Check(globals)) {
_PyErr_SetString(tstate, PyExc_TypeError,
"globals must be a dict or a frozendict");
goto error;
}
if (PyDict_GetItemRef(globals, &_Py_ID(__package__), &package) < 0) {
goto error;
}
if (package == Py_None) {
Py_DECREF(package);
package = NULL;
}
if (PyDict_GetItemRef(globals, &_Py_ID(__spec__), &spec) < 0) {
goto error;
}
if (package != NULL) {
if (!PyUnicode_Check(package)) {
_PyErr_SetString(tstate, PyExc_TypeError,
"package must be a string");
goto error;
}
else if (spec != NULL && spec != Py_None) {
int equal;
PyObject *parent = PyObject_GetAttr(spec, &_Py_ID(parent));
if (parent == NULL) {
goto error;
}
equal = PyObject_RichCompareBool(package, parent, Py_EQ);
Py_DECREF(parent);
if (equal < 0) {
goto error;
}
else if (equal == 0) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"__package__ != __spec__.parent", 1) < 0) {
goto error;
}
}
}
}
else if (spec != NULL && spec != Py_None) {
package = PyObject_GetAttr(spec, &_Py_ID(parent));
if (package == NULL) {
goto error;
}
else if (!PyUnicode_Check(package)) {
_PyErr_SetString(tstate, PyExc_TypeError,
"__spec__.parent must be a string");
goto error;
}
}
else {
if (PyErr_WarnEx(PyExc_ImportWarning,
"can't resolve package from __spec__ or __package__, "
"falling back on __name__ and __path__", 1) < 0) {
goto error;
}
if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &package) < 0) {
goto error;
}
if (package == NULL) {
_PyErr_SetString(tstate, PyExc_KeyError,
"'__name__' not in globals");
goto error;
}
if (!PyUnicode_Check(package)) {
_PyErr_SetString(tstate, PyExc_TypeError,
"__name__ must be a string");
goto error;
}
int haspath = PyDict_Contains(globals, &_Py_ID(__path__));
if (haspath < 0) {
goto error;
}
if (!haspath) {
Py_ssize_t dot;
dot = PyUnicode_FindChar(package, '.',
0, PyUnicode_GET_LENGTH(package), -1);
if (dot == -2) {
goto error;
}
else if (dot == -1) {
goto no_parent_error;
}
PyObject *substr = PyUnicode_Substring(package, 0, dot);
if (substr == NULL) {
goto error;
}
Py_SETREF(package, substr);
}
}
last_dot = PyUnicode_GET_LENGTH(package);
if (last_dot == 0) {
goto no_parent_error;
}
for (level_up = 1; level_up < level; level_up += 1) {
last_dot = PyUnicode_FindChar(package, '.', 0, last_dot, -1);
if (last_dot == -2) {
goto error;
}
else if (last_dot == -1) {
_PyErr_SetString(tstate, PyExc_ImportError,
"attempted relative import beyond top-level "
"package");
goto error;
}
}
Py_XDECREF(spec);
base = PyUnicode_Substring(package, 0, last_dot);
Py_DECREF(package);
if (base == NULL || PyUnicode_GET_LENGTH(name) == 0) {
return base;
}
abs_name = PyUnicode_FromFormat("%U.%U", base, name);
Py_DECREF(base);
return abs_name;
no_parent_error:
_PyErr_SetString(tstate, PyExc_ImportError,
"attempted relative import "
"with no known parent package");
error:
Py_XDECREF(spec);
Py_XDECREF(package);
return NULL;
}
PyObject *
_PyImport_ResolveName(PyThreadState *tstate, PyObject *name,
PyObject *globals, int level)
{
return resolve_name(tstate, name, globals, level);
}
PyObject *
_PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
{
PyObject *obj = NULL;
PyObject *fromlist = Py_None;
PyObject *import_func = NULL;
assert(lazy_import != NULL);
assert(PyLazyImport_CheckExact(lazy_import));
PyLazyImportObject *lz = (PyLazyImportObject *)lazy_import;
PyInterpreterState *interp = tstate->interp;
_PyImport_AcquireLock(interp);
PyObject *importing = interp->imports.lazy_importing_modules;
if (importing == NULL) {
importing = interp->imports.lazy_importing_modules = PySet_New(NULL);
if (importing == NULL) {
_PyImport_ReleaseLock(interp);
return NULL;
}
}
assert(PyAnySet_CheckExact(importing));
int is_loading = _PySet_Contains((PySetObject *)importing, lazy_import);
if (is_loading < 0) {
_PyImport_ReleaseLock(interp);
return NULL;
}
else if (is_loading == 1) {
PyObject *name = _PyLazyImport_GetName(lazy_import);
if (name == NULL) {
_PyImport_ReleaseLock(interp);
return NULL;
}
PyObject *errmsg = PyUnicode_FromFormat(
"cannot import name %R (most likely due to a circular import)",
name);
if (errmsg == NULL) {
Py_DECREF(name);
_PyImport_ReleaseLock(interp);
return NULL;
}
PyErr_SetImportErrorSubclass(PyExc_ImportCycleError, errmsg,
lz->lz_from, NULL);
Py_DECREF(errmsg);
Py_DECREF(name);
_PyImport_ReleaseLock(interp);
return NULL;
}
else if (PySet_Add(importing, lazy_import) < 0) {
goto error;
}
if (lz->lz_attr != NULL) {
if (PyUnicode_Check(lz->lz_attr)) {
fromlist = PyTuple_New(1);
if (fromlist == NULL) {
goto error;
}
Py_INCREF(lz->lz_attr);
PyTuple_SET_ITEM(fromlist, 0, lz->lz_attr);
}
else {
Py_INCREF(lz->lz_attr);
fromlist = lz->lz_attr;
}
}
PyObject *globals = PyEval_GetGlobals();
if (PyMapping_GetOptionalItem(lz->lz_builtins, &_Py_ID(__import__),
&import_func) < 0) {
goto error;
}
if (import_func == NULL) {
PyErr_SetString(PyExc_ImportError, "__import__ not found");
goto error;
}
obj = _PyEval_ImportNameWithImport(
tstate, import_func, globals, globals,
lz->lz_from, fromlist, _PyLong_GetZero()
);
if (obj == NULL) {
goto error;
}
if (lz->lz_attr != NULL && PyUnicode_Check(lz->lz_attr)) {
PyObject *from = obj;
obj = _PyEval_ImportFrom(tstate, from, lz->lz_attr);
Py_DECREF(from);
if (obj == NULL) {
goto error;
}
}
assert(!PyLazyImport_CheckExact(obj));
goto ok;
error:
Py_CLEAR(obj);
if (PyErr_Occurred() && lz->lz_code != NULL && lz->lz_instr_offset >= 0) {
PyObject *exc = _PyErr_GetRaisedException(tstate);
PyObject *import_name = _PyLazyImport_GetName(lazy_import);
if (!import_name) {
_PyErr_SetRaisedException(tstate, exc);
goto ok;
}
int lineno = PyCode_Addr2Line((PyCodeObject *)lz->lz_code,
lz->lz_instr_offset*2);
const char *filename_str = PyUnicode_AsUTF8(lz->lz_code->co_filename);
if (!filename_str) {
PyErr_Clear();
Py_DECREF(import_name);
_PyErr_SetRaisedException(tstate, exc);
goto ok;
}
const char *funcname_str = PyUnicode_AsUTF8(lz->lz_code->co_name);
if (!funcname_str) {
PyErr_Clear();
Py_DECREF(import_name);
_PyErr_SetRaisedException(tstate, exc);
goto ok;
}
PyObject *msg = PyUnicode_FromFormat(
"lazy import of '%U' raised an exception during resolution",
import_name
);
Py_DECREF(import_name);
if (!msg) {
_PyErr_SetRaisedException(tstate, exc);
goto ok;
}
PyObject *cause_exc = PyObject_CallOneArg(PyExc_ImportError, msg);
Py_DECREF(msg);
if (!cause_exc) {
_PyErr_SetRaisedException(tstate, exc);
goto ok;
}
_PyErr_SetRaisedException(tstate, cause_exc);
_PyTraceback_Add(funcname_str, filename_str, lineno);
PyObject *cause_with_tb = _PyErr_GetRaisedException(tstate);
PyException_SetCause(exc, cause_with_tb);
_PyErr_SetRaisedException(tstate, exc);
}
ok:
if (PySet_Discard(importing, lazy_import) < 0) {
Py_CLEAR(obj);
}
_PyImport_ReleaseLock(interp);
Py_XDECREF(fromlist);
Py_XDECREF(import_func);
return obj;
}
static PyObject *
import_find_and_load_with_name(PyThreadState *tstate, PyObject *abs_name,
PyObject *find_and_load,
PyObject *not_found)
{
PyObject *mod = NULL;
PyInterpreterState *interp = tstate->interp;
int import_time = _PyInterpreterState_GetConfig(interp)->import_time;
#define import_level FIND_AND_LOAD(interp).import_level
#define accumulated FIND_AND_LOAD(interp).accumulated
PyTime_t t1 = 0, accumulated_copy = accumulated;
* So we can't have negative cache before completed initialization.
* Anyway, importlib._find_and_load is much slower than
* _PyDict_GetItemIdWithError().
*/
if (import_time) {
_IMPORT_TIME_HEADER(interp);
import_level++;
(void)PyTime_PerfCounterRaw(&t1);
accumulated = 0;
}
if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED())
PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name));
mod = PyObject_CallMethodObjArgs(IMPORTLIB(interp), find_and_load,
abs_name, IMPORT_FUNC(interp), NULL);
if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED()) {
int found = mod != NULL && mod != not_found;
PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
found);
}
if (import_time) {
PyTime_t t2;
(void)PyTime_PerfCounterRaw(&t2);
PyTime_t cum = t2 - t1;
import_level--;
PyObject *encoded_name = get_importtime_name(abs_name);
fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
(long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING),
(long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
import_level*2, "",
encoded_name != NULL ? PyBytes_AS_STRING(encoded_name) : "?");
Py_XDECREF(encoded_name);
accumulated = accumulated_copy + cum;
}
return mod;
#undef import_level
#undef accumulated
}
static PyObject *
import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
{
return import_find_and_load_with_name(
tstate, abs_name, &_Py_ID(_find_and_load), NULL);
}
static PyObject *
get_abs_name(PyThreadState *tstate, PyObject *name, PyObject *globals,
int level)
{
if (level > 0) {
return resolve_name(tstate, name, globals, level);
}
if (PyUnicode_GET_LENGTH(name) == 0) {
_PyErr_SetString(tstate, PyExc_ValueError, "Empty module name");
return NULL;
}
return Py_NewRef(name);
}
PyObject *
_PyImport_GetAbsName(PyThreadState *tstate, PyObject *name,
PyObject *globals, int level)
{
return get_abs_name(tstate, name, globals, level);
}
PyObject *
PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
PyObject *locals, PyObject *fromlist,
int level)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *abs_name = NULL;
PyObject *final_mod = NULL;
PyObject *mod = NULL;
PyInterpreterState *interp = tstate->interp;
int has_from;
if (name == NULL) {
_PyErr_SetString(tstate, PyExc_ValueError, "Empty module name");
goto error;
}
for added performance. */
if (!PyUnicode_Check(name)) {
_PyErr_SetString(tstate, PyExc_TypeError,
"module name must be a string");
goto error;
}
if (level < 0) {
_PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0");
goto error;
}
abs_name = get_abs_name(tstate, name, globals, level);
if (abs_name == NULL) {
goto error;
}
mod = import_get_module(tstate, abs_name);
if (mod == NULL && _PyErr_Occurred(tstate)) {
goto error;
}
if (mod != NULL && mod != Py_None) {
if (import_ensure_initialized(tstate->interp, mod, abs_name) < 0) {
goto error;
}
removed it (due to import failure) between our import_get_module()
call and the _initializing check in import_ensure_initialized().
If removed, we retry the import to preserve normal semantics: the
caller gets the exception from the actual import failure rather
than a synthetic error. */
PyObject *mod_check = import_get_module(tstate, abs_name);
if (mod_check != mod) {
Py_XDECREF(mod_check);
if (_PyErr_Occurred(tstate)) {
goto error;
}
Py_DECREF(mod);
mod = import_find_and_load(tstate, abs_name);
if (mod == NULL) {
goto error;
}
}
else {
Py_DECREF(mod_check);
}
}
else {
Py_XDECREF(mod);
mod = import_find_and_load(tstate, abs_name);
if (mod == NULL) {
goto error;
}
}
has_from = 0;
if (fromlist != NULL && fromlist != Py_None) {
has_from = PyObject_IsTrue(fromlist);
if (has_from < 0)
goto error;
}
if (!has_from) {
Py_ssize_t len = PyUnicode_GET_LENGTH(name);
if (level == 0 || len > 0) {
Py_ssize_t dot;
dot = PyUnicode_FindChar(name, '.', 0, len, 1);
if (dot == -2) {
goto error;
}
if (dot == -1) {
final_mod = Py_NewRef(mod);
goto error;
}
if (level == 0) {
PyObject *front = PyUnicode_Substring(name, 0, dot);
if (front == NULL) {
goto error;
}
final_mod = PyImport_ImportModuleLevelObject(front, NULL, NULL, NULL, 0);
Py_DECREF(front);
}
else {
Py_ssize_t cut_off = len - dot;
Py_ssize_t abs_name_len = PyUnicode_GET_LENGTH(abs_name);
PyObject *to_return = PyUnicode_Substring(abs_name, 0,
abs_name_len - cut_off);
if (to_return == NULL) {
goto error;
}
final_mod = import_get_module(tstate, to_return);
if (final_mod == NULL) {
if (!_PyErr_Occurred(tstate)) {
_PyErr_Format(tstate, PyExc_KeyError,
"%R not in sys.modules as expected",
to_return);
}
Py_DECREF(to_return);
goto error;
}
Py_DECREF(to_return);
}
}
else {
final_mod = Py_NewRef(mod);
}
}
else {
int has_path = PyObject_HasAttrWithError(mod, &_Py_ID(__path__));
if (has_path < 0) {
goto error;
}
if (has_path) {
final_mod = PyObject_CallMethodObjArgs(
IMPORTLIB(interp), &_Py_ID(_handle_fromlist),
mod, fromlist, IMPORT_FUNC(interp), NULL);
}
else {
final_mod = Py_NewRef(mod);
}
}
error:
Py_XDECREF(abs_name);
Py_XDECREF(mod);
if (final_mod == NULL) {
remove_importlib_frames(tstate);
}
return final_mod;
}
static PyObject *
ensure_lazy_pending_submodules(PyDictObject *lazy_modules, PyObject *parent)
{
PyObject *lazy_submodules;
Py_BEGIN_CRITICAL_SECTION(lazy_modules);
int err = _PyDict_GetItemRef_Unicode_LockHeld(lazy_modules, parent,
&lazy_submodules);
if (err == 0) {
lazy_submodules = PySet_New(NULL);
if (lazy_submodules != NULL &&
_PyDict_SetItem_LockHeld(lazy_modules, parent,
lazy_submodules) < 0) {
Py_CLEAR(lazy_submodules);
}
}
Py_END_CRITICAL_SECTION();
return lazy_submodules;
}
static int
register_lazy_on_parent(PyThreadState *tstate, PyObject *name)
{
int ret = -1;
PyObject *parent = NULL;
PyObject *child = NULL;
PyInterpreterState *interp = tstate->interp;
PyObject *lazy_pending_submodules = LAZY_PENDING_SUBMODULES(interp);
assert(lazy_pending_submodules != NULL);
Py_INCREF(name);
while (true) {
Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0,
PyUnicode_GET_LENGTH(name), -1);
if (dot < 0) {
PyObject *lazy_submodules = ensure_lazy_pending_submodules(
(PyDictObject *)lazy_pending_submodules, name);
if (lazy_submodules == NULL) {
goto done;
}
Py_DECREF(lazy_submodules);
ret = 0;
goto done;
}
parent = PyUnicode_Substring(name, 0, dot);
if (parent == NULL) {
goto done;
}
Py_XDECREF(child);
child = PyUnicode_Substring(name, dot + 1, PyUnicode_GET_LENGTH(name));
if (child == NULL) {
goto done;
}
PyObject *lazy_submodules = ensure_lazy_pending_submodules(
(PyDictObject *)lazy_pending_submodules, parent);
if (lazy_submodules == NULL) {
goto done;
}
if (PySet_Add(lazy_submodules, child) < 0) {
Py_DECREF(lazy_submodules);
goto done;
}
Py_DECREF(lazy_submodules);
Py_SETREF(name, parent);
parent = NULL;
}
done:
Py_XDECREF(child);
Py_XDECREF(parent);
Py_XDECREF(name);
return ret;
}
static int
register_from_lazy_on_parent(PyThreadState *tstate, PyObject *abs_name,
PyObject *from)
{
PyObject *fromname = PyUnicode_FromFormat("%U.%U", abs_name, from);
if (fromname == NULL) {
return -1;
}
PyObject *lazy_modules = LAZY_MODULES(tstate->interp);
if (PySet_Add(lazy_modules, fromname) < 0) {
Py_DECREF(fromname);
return -1;
}
int res = register_lazy_on_parent(tstate, fromname);
Py_DECREF(fromname);
return res;
}
_PyLazySubmoduleImportResult
_PyImport_TryLoadLazySubmodule(PyObject *mod_name, PyObject *attr_name,
PyObject **result)
{
assert(result != NULL);
*result = NULL;
PyThreadState *tstate = _PyThreadState_GET();
PyInterpreterState *interp = tstate->interp;
PyObject *lazy_pending = LAZY_PENDING_SUBMODULES(interp);
if (lazy_pending == NULL) {
return _Py_LAZY_SUBMODULE_NOT_FOUND;
}
PyObject *pending_set;
int rc = PyDict_GetItemRef(lazy_pending, mod_name, &pending_set);
if (rc < 0) {
return _Py_LAZY_SUBMODULE_ERROR;
}
if (rc == 0) {
return _Py_LAZY_SUBMODULE_NOT_FOUND;
}
int contains = PySet_Contains(pending_set, attr_name);
if (contains < 0) {
Py_DECREF(pending_set);
return _Py_LAZY_SUBMODULE_ERROR;
}
if (contains == 0) {
Py_DECREF(pending_set);
return _Py_LAZY_SUBMODULE_NOT_FOUND;
}
PyObject *full_name = PyUnicode_FromFormat("%U.%U", mod_name, attr_name);
if (full_name == NULL) {
Py_DECREF(pending_set);
return _Py_LAZY_SUBMODULE_ERROR;
}
PyObject *mod = import_find_and_load_with_name(
tstate, full_name, &_Py_ID(_find_and_load_lazy_submodule), Py_None);
if (mod == NULL) {
Py_DECREF(pending_set);
Py_DECREF(full_name);
remove_importlib_frames(tstate);
return _Py_LAZY_SUBMODULE_ERROR;
}
if (mod == Py_None) {
Py_DECREF(mod);
Py_DECREF(pending_set);
Py_DECREF(full_name);
return _Py_LAZY_SUBMODULE_NOT_FOUND;
}
if (PySet_Discard(pending_set, attr_name) < 0) {
Py_DECREF(mod);
Py_DECREF(pending_set);
Py_DECREF(full_name);
return _Py_LAZY_SUBMODULE_ERROR;
}
Py_DECREF(pending_set);
Py_DECREF(full_name);
*result = mod;
return _Py_LAZY_SUBMODULE_LOADED;
}
PyObject *
_PyImport_LazyImportModuleLevelObject(PyThreadState *tstate,
PyObject *name, PyObject *builtins,
PyObject *globals, PyObject *locals,
PyObject *fromlist, int level)
{
assert(name != NULL);
if (!PyUnicode_Check(name)) {
_PyErr_Format(tstate, PyExc_TypeError,
"module name must be a string, got %T", name);
return NULL;
}
if (level < 0) {
_PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0");
return NULL;
}
PyObject *abs_name = get_abs_name(tstate, name, globals, level);
if (abs_name == NULL) {
return NULL;
}
PyInterpreterState *interp = tstate->interp;
_PyInterpreterFrame *frame = _PyEval_GetFrame();
if (frame == NULL || frame->f_globals != frame->f_locals) {
Py_DECREF(abs_name);
PyErr_SetString(PyExc_SyntaxError,
"'lazy import' is only allowed at module level");
return NULL;
}
LAZY_IMPORTS_LOCK(interp);
PyObject *filter = Py_XNewRef(LAZY_IMPORTS_FILTER(interp));
LAZY_IMPORTS_UNLOCK(interp);
if (filter != NULL) {
PyObject *modname;
if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &modname) < 0) {
Py_DECREF(filter);
Py_DECREF(abs_name);
return NULL;
}
if (modname == NULL) {
assert(!PyErr_Occurred());
modname = Py_NewRef(Py_None);
}
if (fromlist == NULL) {
assert(!PyErr_Occurred());
fromlist = Py_None;
}
PyObject *args[] = {modname, abs_name, fromlist};
PyObject *res = PyObject_Vectorcall(filter, args, 3, NULL);
Py_DECREF(modname);
Py_DECREF(filter);
if (res == NULL) {
Py_DECREF(abs_name);
return NULL;
}
int is_true = PyObject_IsTrue(res);
Py_DECREF(res);
if (is_true < 0) {
Py_DECREF(abs_name);
return NULL;
}
if (!is_true) {
Py_DECREF(abs_name);
return PyImport_ImportModuleLevelObject(
name, globals, locals, fromlist, level
);
}
}
if (fromlist && PyUnicode_Check(fromlist)) {
fromlist = PyTuple_Pack(1, fromlist);
if (fromlist == NULL) {
Py_DECREF(abs_name);
return NULL;
}
}
else {
Py_XINCREF(fromlist);
}
PyObject *res = _PyLazyImport_New(frame, builtins, abs_name, fromlist);
if (res == NULL) {
Py_XDECREF(fromlist);
Py_DECREF(abs_name);
return NULL;
}
PyObject *lazy_modules = LAZY_MODULES(tstate->interp);
if (PySet_Add(lazy_modules, abs_name) < 0) {
goto error;
}
if (fromlist && PyTuple_Check(fromlist) && PyTuple_GET_SIZE(fromlist)) {
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(fromlist); i++) {
if (register_from_lazy_on_parent(tstate, abs_name,
PyTuple_GET_ITEM(fromlist, i)) < 0)
{
goto error;
}
}
}
else if (register_lazy_on_parent(tstate, abs_name) < 0) {
goto error;
}
Py_XDECREF(fromlist);
Py_DECREF(abs_name);
return res;
error:
Py_XDECREF(fromlist);
Py_DECREF(abs_name);
Py_DECREF(res);
return NULL;
}
PyObject *
PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals,
PyObject *fromlist, int level)
{
PyObject *nameobj, *mod;
nameobj = PyUnicode_FromString(name);
if (nameobj == NULL)
return NULL;
mod = PyImport_ImportModuleLevelObject(nameobj, globals, locals,
fromlist, level);
Py_DECREF(nameobj);
return mod;
}
INCREMENTED REFERENCE COUNT */
PyObject *
PyImport_ReloadModule(PyObject *m)
{
PyObject *reloaded_module = NULL;
PyObject *importlib = PyImport_GetModule(&_Py_ID(importlib));
if (importlib == NULL) {
if (PyErr_Occurred()) {
return NULL;
}
importlib = PyImport_ImportModule("importlib");
if (importlib == NULL) {
return NULL;
}
}
reloaded_module = PyObject_CallMethodOneArg(importlib, &_Py_ID(reload), m);
Py_DECREF(importlib);
return reloaded_module;
}
more accurately -- it invokes the __import__() function from the
builtins of the current globals. This means that the import is
done using whatever import hooks are installed in the current
environment.
A dummy list ["__doc__"] is passed as the 4th argument so that
e.g. PyImport_Import(PyUnicode_FromString("win32com.client.gencache"))
will return <module "gencache"> instead of <module "win32com">. */
PyObject *
PyImport_Import(PyObject *module_name)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *globals = NULL;
PyObject *import = NULL;
PyObject *builtins = NULL;
PyObject *r = NULL;
PyObject *from_list = PyList_New(0);
if (from_list == NULL) {
goto err;
}
globals = PyEval_GetGlobals();
if (globals != NULL) {
Py_INCREF(globals);
builtins = PyObject_GetItem(globals, &_Py_ID(__builtins__));
if (builtins == NULL) {
goto err;
}
}
else if (_PyErr_Occurred(tstate)) {
goto err;
}
else {
globals = PyDict_New();
if (globals == NULL) {
goto err;
}
if (_PyEval_EnsureBuiltinsWithModule(tstate, globals, &builtins) < 0) {
goto err;
}
}
if (PyDict_Check(builtins)) {
import = PyObject_GetItem(builtins, &_Py_ID(__import__));
if (import == NULL) {
_PyErr_SetObject(tstate, PyExc_KeyError, &_Py_ID(__import__));
}
}
else
import = PyObject_GetAttr(builtins, &_Py_ID(__import__));
if (import == NULL)
goto err;
Always use absolute import here.
Calling for side-effect of import. */
r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
globals, from_list, 0, NULL);
if (r == NULL)
goto err;
Py_DECREF(r);
r = import_get_module(tstate, module_name);
if (r == NULL && !_PyErr_Occurred(tstate)) {
_PyErr_SetObject(tstate, PyExc_KeyError, module_name);
}
err:
Py_XDECREF(globals);
Py_XDECREF(builtins);
Py_XDECREF(import);
Py_XDECREF(from_list);
return r;
}
PyStatus
_PyImport_Init(void)
{
if (INITTAB != NULL) {
return _PyStatus_ERR("global import state already initialized");
}
if (init_builtin_modules_table() != 0) {
return PyStatus_NoMemory();
}
return _PyStatus_OK();
}
void
_PyImport_Fini(void)
{
_extensions_cache_clear_all();
fini_builtin_modules_table();
}
void
_PyImport_Fini2(void)
{
PyImport_Inittab = _PyImport_Inittab;
_PyMem_DefaultRawFree(inittab_copy);
inittab_copy = NULL;
}
PyStatus
_PyImport_InitCore(PyThreadState *tstate, PyObject *sysmod, int importlib)
{
if (importlib) {
if (init_importlib(tstate, sysmod) < 0) {
return _PyStatus_ERR("failed to initialize importlib");
}
}
return _PyStatus_OK();
}
machinery has been initialized (or not cleaned up yet). For
example, see issue #4236 and PyModule_Create2(). */
int
_PyImport_IsInitialized(PyInterpreterState *interp)
{
if (MODULES(interp) == NULL)
return 0;
return 1;
}
void
_PyImport_ClearCore(PyInterpreterState *interp)
{
by _PyImport_FiniCore(). */
Py_CLEAR(MODULES(interp));
Py_CLEAR(MODULES_BY_INDEX(interp));
Py_CLEAR(IMPORTLIB(interp));
Py_CLEAR(IMPORT_FUNC(interp));
Py_CLEAR(LAZY_IMPORT_FUNC(interp));
Py_CLEAR(interp->imports.lazy_pending_submodules);
Py_CLEAR(interp->imports.lazy_modules);
Py_CLEAR(interp->imports.lazy_importing_modules);
Py_CLEAR(interp->imports.lazy_imports_filter);
}
void
_PyImport_FiniCore(PyInterpreterState *interp)
{
int verbose = _PyInterpreterState_GetConfig(interp)->verbose;
if (_PySys_ClearAttrString(interp, "meta_path", verbose) < 0) {
PyErr_FormatUnraisable("Exception ignored while "
"clearing sys.meta_path");
}
if (_PySys_ClearAttrString(interp, "modules", verbose) < 0) {
PyErr_FormatUnraisable("Exception ignored while "
"clearing sys.modules");
}
_PyImport_ClearCore(interp);
}
static int
init_zipimport(PyThreadState *tstate, int verbose)
{
PyObject *path_hooks = PySys_GetAttrString("path_hooks");
if (path_hooks == NULL) {
return -1;
}
if (verbose) {
PySys_WriteStderr("# installing zipimport hook\n");
}
PyObject *zipimporter = PyImport_ImportModuleAttrString("zipimport", "zipimporter");
if (zipimporter == NULL) {
_PyErr_Clear(tstate);
if (verbose) {
PySys_WriteStderr("# can't import zipimport.zipimporter\n");
}
}
else {
int err = PyList_Insert(path_hooks, 0, zipimporter);
Py_DECREF(zipimporter);
if (err < 0) {
Py_DECREF(path_hooks);
return -1;
}
if (verbose) {
PySys_WriteStderr("# installed zipimport hook\n");
}
}
Py_DECREF(path_hooks);
return 0;
}
PyStatus
_PyImport_InitExternal(PyThreadState *tstate)
{
int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
if (init_importlib_external(tstate->interp) != 0) {
_PyErr_Print(tstate);
return _PyStatus_ERR("external importer setup failed");
}
if (init_zipimport(tstate, verbose) != 0) {
PyErr_Print();
return _PyStatus_ERR("initializing zipimport failed");
}
return _PyStatus_OK();
}
void
_PyImport_FiniExternal(PyInterpreterState *interp)
{
int verbose = _PyInterpreterState_GetConfig(interp)->verbose;
if (_PySys_ClearAttrString(interp, "path_importer_cache", verbose) < 0) {
PyErr_FormatUnraisable("Exception ignored while "
"clearing sys.path_importer_cache");
}
if (_PySys_ClearAttrString(interp, "path_hooks", verbose) < 0) {
PyErr_FormatUnraisable("Exception ignored while "
"clearing sys.path_hooks");
}
}
PyObject *
PyImport_ImportModuleAttr(PyObject *modname, PyObject *attrname)
{
PyObject *mod = PyImport_Import(modname);
if (mod == NULL) {
return NULL;
}
PyObject *result = PyObject_GetAttr(mod, attrname);
Py_DECREF(mod);
return result;
}
PyObject *
PyImport_ImportModuleAttrString(const char *modname, const char *attrname)
{
PyObject *pmodname = PyUnicode_FromString(modname);
if (pmodname == NULL) {
return NULL;
}
PyObject *pattrname = PyUnicode_FromString(attrname);
if (pattrname == NULL) {
Py_DECREF(pmodname);
return NULL;
}
PyObject *result = PyImport_ImportModuleAttr(pmodname, pattrname);
Py_DECREF(pattrname);
Py_DECREF(pmodname);
return result;
}
int
PyImport_SetLazyImportsFilter(PyObject *filter)
{
if (filter == Py_None) {
filter = NULL;
}
if (filter != NULL && !PyCallable_Check(filter)) {
PyErr_SetString(PyExc_ValueError,
"filter provided but is not callable");
return -1;
}
PyInterpreterState *interp = _PyInterpreterState_GET();
LAZY_IMPORTS_LOCK(interp);
PyObject *old = LAZY_IMPORTS_FILTER(interp);
LAZY_IMPORTS_FILTER(interp) = Py_XNewRef(filter);
LAZY_IMPORTS_UNLOCK(interp);
Py_XDECREF(old);
return 0;
}
* or NULL if none exists. This function always succeeds.
*/
PyObject *
PyImport_GetLazyImportsFilter(void)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
LAZY_IMPORTS_LOCK(interp);
PyObject *res = Py_XNewRef(LAZY_IMPORTS_FILTER(interp));
LAZY_IMPORTS_UNLOCK(interp);
return res;
}
int
PyImport_SetLazyImportsMode(PyImport_LazyImportsMode mode)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
FT_ATOMIC_STORE_INT_RELAXED(LAZY_IMPORTS_MODE(interp), mode);
return 0;
}
* globally forced on, 0 when globally forced off, or -1 when not set.*/
PyImport_LazyImportsMode
PyImport_GetLazyImportsMode(void)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
return FT_ATOMIC_LOAD_INT_RELAXED(LAZY_IMPORTS_MODE(interp));
}
_imp.lock_held
Return True if the import lock is currently held, else False.
On platforms without threads, return False.
[clinic start generated code]*/
static PyObject *
_imp_lock_held_impl(PyObject *module)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
return PyBool_FromLong(PyMutex_IsLocked(&IMPORT_LOCK(interp).mutex));
}
_imp.acquire_lock
Acquires the interpreter's import lock for the current thread.
This lock should be used by import hooks to ensure thread-safety when
importing modules. On platforms without threads, this function does
nothing.
[clinic start generated code]*/
static PyObject *
_imp_acquire_lock_impl(PyObject *module)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
_PyImport_AcquireLock(interp);
Py_RETURN_NONE;
}
_imp.release_lock
Release the interpreter's import lock.
On platforms without threads, this function does nothing.
[clinic start generated code]*/
static PyObject *
_imp_release_lock_impl(PyObject *module)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
if (!_PyRecursiveMutex_IsLockedByCurrentThread(&IMPORT_LOCK(interp))) {
PyErr_SetString(PyExc_RuntimeError,
"not holding the import lock");
return NULL;
}
_PyImport_ReleaseLock(interp);
Py_RETURN_NONE;
}
_imp._fix_co_filename
code: object(type="PyCodeObject *", subclass_of="&PyCode_Type")
Code object to change.
path: unicode
File path to use.
/
Changes code.co_filename to specify the passed-in file path.
[clinic start generated code]*/
static PyObject *
_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code,
PyObject *path)
{
update_compiled_module(code, path);
Py_RETURN_NONE;
}
_imp.create_builtin
spec: object
/
Create an extension module.
[clinic start generated code]*/
static PyObject *
_imp_create_builtin(PyObject *module, PyObject *spec)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *name = PyObject_GetAttrString(spec, "name");
if (name == NULL) {
return NULL;
}
if (!PyUnicode_Check(name)) {
PyErr_Format(PyExc_TypeError,
"name must be string, not %.200s",
Py_TYPE(name)->tp_name);
Py_DECREF(name);
return NULL;
}
if (PyUnicode_GetLength(name) == 0) {
PyErr_Format(PyExc_ValueError, "name must not be empty");
Py_DECREF(name);
return NULL;
}
PyObject *mod = create_builtin(tstate, name, spec, NULL);
Py_DECREF(name);
return mod;
}
_imp.extension_suffixes
Returns the list of file suffixes used to identify extension modules.
[clinic start generated code]*/
static PyObject *
_imp_extension_suffixes_impl(PyObject *module)
{
PyObject *list;
list = PyList_New(0);
if (list == NULL)
return NULL;
#ifdef HAVE_DYNAMIC_LOADING
const char *suffix;
unsigned int index = 0;
while ((suffix = _PyImport_DynLoadFiletab[index])) {
PyObject *item = PyUnicode_FromString(suffix);
if (item == NULL) {
Py_DECREF(list);
return NULL;
}
if (PyList_Append(list, item) < 0) {
Py_DECREF(list);
Py_DECREF(item);
return NULL;
}
Py_DECREF(item);
index += 1;
}
#endif
return list;
}
_imp.init_frozen
name: unicode
/
Initializes a frozen module.
[clinic start generated code]*/
static PyObject *
_imp_init_frozen_impl(PyObject *module, PyObject *name)
{
PyThreadState *tstate = _PyThreadState_GET();
int ret;
ret = PyImport_ImportFrozenModuleObject(name);
if (ret < 0)
return NULL;
if (ret == 0) {
Py_RETURN_NONE;
}
return import_add_module(tstate, name);
}
@permit_long_summary
_imp.find_frozen
name: unicode
/
*
withdata: bool = False
Return info about the corresponding frozen module (if there is one) or None.
The returned info (a 2-tuple):
* data the raw marshalled bytes
* is_package whether or not it is a package
* origname the originally frozen module's name, or None if not
a stdlib module (this will usually be the same as
the module's current name)
[clinic start generated code]*/
static PyObject *
_imp_find_frozen_impl(PyObject *module, PyObject *name, int withdata)
{
struct frozen_info info;
frozen_status status = find_frozen(name, &info);
if (status == FROZEN_NOT_FOUND || status == FROZEN_DISABLED) {
Py_RETURN_NONE;
}
else if (status == FROZEN_BAD_NAME) {
Py_RETURN_NONE;
}
else if (status != FROZEN_OKAY) {
set_frozen_error(status, name);
return NULL;
}
PyObject *data = NULL;
if (withdata) {
data = PyMemoryView_FromMemory((char *)info.data, info.size, PyBUF_READ);
if (data == NULL) {
return NULL;
}
}
PyObject *origname = NULL;
if (info.origname != NULL && info.origname[0] != '\0') {
origname = PyUnicode_FromString(info.origname);
if (origname == NULL) {
Py_XDECREF(data);
return NULL;
}
}
PyObject *result = PyTuple_Pack(3, data ? data : Py_None,
info.is_package ? Py_True : Py_False,
origname ? origname : Py_None);
Py_XDECREF(origname);
Py_XDECREF(data);
return result;
}
_imp.get_frozen_object
name: unicode
data as dataobj: object = None
/
Create a code object for a frozen module.
[clinic start generated code]*/
static PyObject *
_imp_get_frozen_object_impl(PyObject *module, PyObject *name,
PyObject *dataobj)
{
struct frozen_info info = {0};
Py_buffer buf = {0};
if (PyObject_CheckBuffer(dataobj)) {
if (PyObject_GetBuffer(dataobj, &buf, PyBUF_SIMPLE) != 0) {
return NULL;
}
info.data = (const char *)buf.buf;
info.size = buf.len;
}
else if (dataobj != Py_None) {
_PyArg_BadArgument("get_frozen_object", "argument 2", "bytes", dataobj);
return NULL;
}
else {
frozen_status status = find_frozen(name, &info);
if (status != FROZEN_OKAY) {
set_frozen_error(status, name);
return NULL;
}
}
if (info.nameobj == NULL) {
info.nameobj = name;
}
if (info.size == 0) {
set_frozen_error(FROZEN_INVALID, name);
return NULL;
}
PyInterpreterState *interp = _PyInterpreterState_GET();
PyObject *codeobj = unmarshal_frozen_code(interp, &info);
if (dataobj != Py_None) {
PyBuffer_Release(&buf);
}
return codeobj;
}
_imp.is_frozen_package
name: unicode
/
Returns True if the module name is of a frozen package.
[clinic start generated code]*/
static PyObject *
_imp_is_frozen_package_impl(PyObject *module, PyObject *name)
{
struct frozen_info info;
frozen_status status = find_frozen(name, &info);
if (status != FROZEN_OKAY && status != FROZEN_EXCLUDED) {
set_frozen_error(status, name);
return NULL;
}
return PyBool_FromLong(info.is_package);
}
_imp.is_builtin
name: unicode
/
Returns True if the module name corresponds to a built-in module.
[clinic start generated code]*/
static PyObject *
_imp_is_builtin_impl(PyObject *module, PyObject *name)
{
return PyLong_FromLong(is_builtin(name));
}
_imp.is_frozen
name: unicode
/
Returns True if the module name corresponds to a frozen module.
[clinic start generated code]*/
static PyObject *
_imp_is_frozen_impl(PyObject *module, PyObject *name)
{
struct frozen_info info;
frozen_status status = find_frozen(name, &info);
if (status != FROZEN_OKAY) {
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
}
_imp._frozen_module_names
Returns the list of available frozen modules.
[clinic start generated code]*/
static PyObject *
_imp__frozen_module_names_impl(PyObject *module)
{
return list_frozen_module_names();
}
_imp._override_frozen_modules_for_tests
override: int
/
(internal-only) Override PyConfig.use_frozen_modules.
(-1: "off", 1: "on", 0: no override)
See frozen_modules() in Lib/test/support/import_helper.py.
[clinic start generated code]*/
static PyObject *
_imp__override_frozen_modules_for_tests_impl(PyObject *module, int override)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
OVERRIDE_FROZEN_MODULES(interp) = override;
Py_RETURN_NONE;
}
@permit_long_summary
_imp._override_multi_interp_extensions_check
override: int
/
(internal-only) Override PyInterpreterConfig.check_multi_interp_extensions.
(-1: "never", 1: "always", 0: no override)
[clinic start generated code]*/
static PyObject *
_imp__override_multi_interp_extensions_check_impl(PyObject *module,
int override)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
if (_Py_IsMainInterpreter(interp)) {
PyErr_SetString(PyExc_RuntimeError,
"_imp._override_multi_interp_extensions_check() "
"cannot be used in the main interpreter");
return NULL;
}
#ifdef Py_GIL_DISABLED
PyErr_SetString(PyExc_RuntimeError,
"_imp._override_multi_interp_extensions_check() "
"cannot be used in the free-threaded build");
return NULL;
#else
int oldvalue = OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp);
OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp) = override;
return PyLong_FromLong(oldvalue);
#endif
}
#ifdef HAVE_DYNAMIC_LOADING
_imp.create_dynamic
spec: object
file: object = NULL
/
Create an extension module.
[clinic start generated code]*/
static PyObject *
_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
{
FILE *fp = NULL;
PyObject *mod = NULL;
PyThreadState *tstate = _PyThreadState_GET();
struct _Py_ext_module_loader_info info;
if (_Py_ext_module_loader_info_init_from_spec(&info, spec) < 0) {
return NULL;
}
struct extensions_cache_value *cached = NULL;
mod = import_find_extension(tstate, &info, &cached);
if (mod != NULL) {
assert(!_PyErr_Occurred(tstate));
assert(cached != NULL);
assert(_PyModule_GetDefOrNull(mod) == NULL
|| cached->def == _PyModule_GetDefOrNull(mod));
assert_singlephase(cached);
goto finally;
}
else if (_PyErr_Occurred(tstate)) {
goto finally;
}
* but def->m_base.m_copy was cleared (e.g. subinterp fini)
* then we have to do a little dance here. */
if (cached != NULL) {
assert(cached->def->m_base.m_copy == NULL);
_extensions_cache_delete(info.path, info.name);
}
if (PySys_Audit("import", "OOOOO", info.name, info.filename,
Py_None, Py_None, Py_None) < 0)
{
goto finally;
}
* _PyImport_GetModuleExportHooks(), but it isn't clear if the intervening
* code relies on fp still being open. */
if (file != NULL) {
fp = Py_fopen(info.filename, "r");
if (fp == NULL) {
goto finally;
}
}
PyModInitFunction p0 = NULL;
PyModExportFunction ex0 = NULL;
_PyImport_GetModuleExportHooks(&info, fp, &p0, &ex0);
if (ex0) {
mod = import_run_modexport(tstate, ex0, &info, spec);
goto finally;
}
if (p0 == NULL) {
goto finally;
}
#ifdef Py_GIL_DISABLED
_PyEval_EnableGILTransient(tstate);
#endif
mod = import_run_extension(
tstate, p0, &info, spec, get_modules_dict(tstate, true));
#ifdef Py_GIL_DISABLED
if (_PyImport_CheckGILForModule(mod, info.name) < 0) {
Py_CLEAR(mod);
goto finally;
}
#endif
finally:
if (fp != NULL) {
fclose(fp);
}
_Py_ext_module_loader_info_clear(&info);
return mod;
}
_imp.exec_dynamic -> int
mod: object
/
Initialize an extension module.
[clinic start generated code]*/
static int
_imp_exec_dynamic_impl(PyObject *module, PyObject *mod)
{
return exec_builtin_or_dynamic(mod);
}
#endif
_imp.exec_builtin -> int
mod: object
/
Initialize a built-in module.
[clinic start generated code]*/
static int
_imp_exec_builtin_impl(PyObject *module, PyObject *mod)
{
return exec_builtin_or_dynamic(mod);
}
_imp.source_hash
key: long
source: Py_buffer
[clinic start generated code]*/
static PyObject *
_imp_source_hash_impl(PyObject *module, long key, Py_buffer *source)
{
union {
uint64_t x;
char data[sizeof(uint64_t)];
} hash;
hash.x = _Py_KeyedHash((uint64_t)key, source->buf, source->len);
#if !PY_LITTLE_ENDIAN
for (size_t i = 0; i < sizeof(hash.data)/2; i++) {
char tmp = hash.data[i];
hash.data[i] = hash.data[sizeof(hash.data) - i - 1];
hash.data[sizeof(hash.data) - i - 1] = tmp;
}
#endif
return PyBytes_FromStringAndSize(hash.data, sizeof(hash.data));
}
_imp._set_lazy_attributes
modobj: object
name: unicode
/
Sets attributes to lazy submodules on the module, as side effects.
[clinic start generated code]*/
static PyObject *
_imp__set_lazy_attributes_impl(PyObject *module, PyObject *modobj,
PyObject *name)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
if (PySet_Discard(LAZY_MODULES(interp), name) < 0) {
return NULL;
}
Py_RETURN_NONE;
}
PyDoc_STRVAR(doc_imp,
"(Extremely) low-level import machinery bits as used by importlib.");
static PyMethodDef imp_methods[] = {
_IMP_EXTENSION_SUFFIXES_METHODDEF
_IMP_LOCK_HELD_METHODDEF
_IMP_ACQUIRE_LOCK_METHODDEF
_IMP_RELEASE_LOCK_METHODDEF
_IMP_FIND_FROZEN_METHODDEF
_IMP_GET_FROZEN_OBJECT_METHODDEF
_IMP_IS_FROZEN_PACKAGE_METHODDEF
_IMP_CREATE_BUILTIN_METHODDEF
_IMP_INIT_FROZEN_METHODDEF
_IMP_IS_BUILTIN_METHODDEF
_IMP_IS_FROZEN_METHODDEF
_IMP__FROZEN_MODULE_NAMES_METHODDEF
_IMP__OVERRIDE_FROZEN_MODULES_FOR_TESTS_METHODDEF
_IMP__OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK_METHODDEF
_IMP_CREATE_DYNAMIC_METHODDEF
_IMP_EXEC_DYNAMIC_METHODDEF
_IMP_EXEC_BUILTIN_METHODDEF
_IMP__FIX_CO_FILENAME_METHODDEF
_IMP_SOURCE_HASH_METHODDEF
_IMP__SET_LAZY_ATTRIBUTES_METHODDEF
{NULL, NULL}
};
static int
imp_module_exec(PyObject *module)
{
const wchar_t *mode = _Py_GetConfig()->check_hash_pycs_mode;
PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1);
if (PyModule_Add(module, "check_hash_based_pycs", pyc_mode) < 0) {
return -1;
}
if (PyModule_AddIntConstant(
module, "pyc_magic_number_token", PYC_MAGIC_NUMBER_TOKEN) < 0)
{
return -1;
}
return 0;
}
static PyModuleDef_Slot imp_slots[] = {
_Py_ABI_SLOT,
{Py_mod_exec, imp_module_exec},
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
{0, NULL}
};
static struct PyModuleDef imp_module = {
PyModuleDef_HEAD_INIT,
.m_name = "_imp",
.m_doc = doc_imp,
.m_size = 0,
.m_methods = imp_methods,
.m_slots = imp_slots,
};
PyMODINIT_FUNC
PyInit__imp(void)
{
return PyModuleDef_Init(&imp_module);
}