Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4433124
Group code in import.c.
ericsnowcurrently Feb 14, 2023
7626bab
Move PyState_*() to import.c.
ericsnowcurrently Feb 14, 2023
5836e93
Add _PyImport_GetNextModuleIndex().
ericsnowcurrently Feb 14, 2023
bc031c1
Add _PyImport_SwapPackageContext() and _PyImport_ResolveNameWithPacka…
ericsnowcurrently Feb 14, 2023
f67c299
Add _PyImport_GetBuiltinModuleNames().
ericsnowcurrently Feb 14, 2023
9b312e1
Add an "extension modules" section.
ericsnowcurrently Feb 14, 2023
24ec4de
Move the "extension modules" section down.
ericsnowcurrently Feb 14, 2023
b2043e4
Add _PyImport_GetDLOpenFlags() and _PyImport_SetDLOpenFlags().
ericsnowcurrently Feb 14, 2023
43d8de7
Hide sys.modules.
ericsnowcurrently Feb 14, 2023
b7cabeb
_PyInterpreterState_ClearModules() -> _PyImport_ClearModulesByIndex().
ericsnowcurrently Feb 14, 2023
d4693ea
Hide interp->import_func.
ericsnowcurrently Feb 14, 2023
7120be2
Hide interp->importlib.
ericsnowcurrently Feb 14, 2023
1935ee5
Add _PyImport_InitCore() and _PyImport_InitExternal().
ericsnowcurrently Feb 14, 2023
7e29b7c
Re-order import.c sections.
ericsnowcurrently Feb 14, 2023
66de41d
Add _PyImport_FiniExternal() and _PyImport_FiniCore().
ericsnowcurrently Feb 14, 2023
384bd69
Factor out init_builtin_modules_table() and fini_builtin_builtins_tab…
ericsnowcurrently Feb 14, 2023
e4777b7
Add PyInterpreterState.imports.
ericsnowcurrently Feb 14, 2023
48fb47c
Move the lifecycle sections to the bottom.
ericsnowcurrently Feb 14, 2023
e8930c8
Add macros for runtime-global import state.
ericsnowcurrently Feb 14, 2023
79a72c4
minor fixes
ericsnowcurrently Feb 14, 2023
0527913
Drop _PyState_AddModule().
ericsnowcurrently Feb 15, 2023
a4deb8a
Drop a wrong assert.
ericsnowcurrently Feb 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add _PyImport_InitCore() and _PyImport_InitExternal().
  • Loading branch information
ericsnowcurrently committed Feb 14, 2023
commit 1935ee5f7d61fe790d70f9757fe5ed1a1a91f4bc
13 changes: 10 additions & 3 deletions Include/internal/pycore_import.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ extern void _PyImport_ClearModules(PyInterpreterState *interp);
extern void _PyImport_ClearModulesByIndex(PyInterpreterState *interp);

extern int _PyImport_InitDefaultImportFunc(PyInterpreterState *interp);
extern int _PyImport_IsDefaultImportFunc(PyInterpreterState *interp,
PyObject *func);
extern int _PyImport_IsDefaultImportFunc(
PyInterpreterState *interp,
PyObject *func);

extern PyObject * _PyImport_GetImportlibLoader(
PyInterpreterState *interp,
Expand All @@ -69,10 +70,16 @@ extern PyObject * _PyImport_ImportlibModuleRepr(
PyObject *module);


extern PyStatus _PyImport_InitCore(
PyThreadState *tstate,
PyObject *sysmod,
int importlib);
extern PyStatus _PyImport_InitExternal(PyThreadState *tstate);

#ifdef HAVE_FORK
extern PyStatus _PyImport_ReInitLock(void);
#endif
extern PyObject* _PyImport_BootstrapImp(PyThreadState *tstate);


extern PyObject* _PyImport_GetBuiltinModuleNames(void);

Expand Down
1 change: 0 additions & 1 deletion Include/internal/pycore_pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);

extern PyStatus _PyTime_Init(void);
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
extern PyStatus _PyGC_Init(PyInterpreterState *interp);
extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
extern int _Py_Deepfreeze_Init(void);
Expand Down
273 changes: 186 additions & 87 deletions Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,21 @@ _PyImport_Fini2(void)
/* interpreter lifecycle */
/*************************/

static int init_importlib(PyThreadState *tstate, PyObject *sysmod);

PyStatus
_PyImport_InitCore(PyThreadState *tstate, PyObject *sysmod, int importlib)
{
if (importlib) {
/* This call sets up builtin and frozen import support */
if (init_importlib(tstate, sysmod) < 0) {
return _PyStatus_ERR("failed to initialize importlib");
}
}

return _PyStatus_OK();
}

/* In some corner cases it is important to be sure that the import
machinery has been initialized (or not cleaned up yet). For
example, see issue #4236 and PyModule_Create2(). */
Expand All @@ -161,71 +176,19 @@ _PyImport_ClearCore(PyInterpreterState *interp)
Py_CLEAR(interp->import_func);
}

static PyObject* create_builtin(PyThreadState *tstate,
PyObject *name, PyObject *spec);
static int exec_builtin_or_dynamic(PyObject *mod);

// Import the _imp extension by calling manually _imp.create_builtin() and
// _imp.exec_builtin() since importlib is not initialized yet. Initializing
// importlib requires the _imp module: this function fix the bootstrap issue.
PyObject*
_PyImport_BootstrapImp(PyThreadState *tstate)
{
PyObject *name = PyUnicode_FromString("_imp");
if (name == NULL) {
return NULL;
}

// Mock a ModuleSpec object just good enough for PyModule_FromDefAndSpec():
// an object with just a name attribute.
//
// _imp.__spec__ is overridden by importlib._bootstrap._instal() anyway.
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;
}

// Create the _imp module from its definition.
PyObject *mod = create_builtin(tstate, name, spec);
Py_CLEAR(name);
Py_DECREF(spec);
if (mod == NULL) {
goto error;
}
assert(mod != Py_None); // not found

// Execute the _imp module: call imp_module_exec().
if (exec_builtin_or_dynamic(mod) < 0) {
Py_DECREF(mod);
goto error;
}
return mod;

error:
Py_XDECREF(name);
return NULL;
}

/* "external" imports */

PyStatus
_PyImportZip_Init(PyThreadState *tstate)
static int
init_zipimport(PyThreadState *tstate, int verbose)
{
PyObject *path_hooks;
int err = 0;

path_hooks = PySys_GetObject("path_hooks");
PyObject *path_hooks = PySys_GetObject("path_hooks");
if (path_hooks == NULL) {
_PyErr_SetString(tstate, PyExc_RuntimeError,
"unable to get sys.path_hooks");
goto error;
return -1;
}

int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
if (verbose) {
PySys_WriteStderr("# installing zipimport hook\n");
}
Expand All @@ -239,21 +202,37 @@ _PyImportZip_Init(PyThreadState *tstate)
}
else {
/* sys.path_hooks.insert(0, zipimporter) */
err = PyList_Insert(path_hooks, 0, zipimporter);
int err = PyList_Insert(path_hooks, 0, zipimporter);
Py_DECREF(zipimporter);
if (err < 0) {
goto error;
return -1;
}
if (verbose) {
PySys_WriteStderr("# installed zipimport hook\n");
}
}

return _PyStatus_OK();
return 0;
}

error:
PyErr_Print();
return _PyStatus_ERR("initializing zipimport failed");
static int init_importlib_external(PyInterpreterState *interp);

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();
}


Expand Down Expand Up @@ -1368,6 +1347,31 @@ _PyImport_SetDLOpenFlags(PyInterpreterState *interp, int new_val)
#endif // HAVE_DLOPEN


/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */
static int
exec_builtin_or_dynamic(PyObject *mod) {
PyModuleDef *def;
void *state;

if (!PyModule_Check(mod)) {
return 0;
}

def = PyModule_GetDef(mod);
if (def == NULL) {
return 0;
}

state = PyModule_GetState(mod);
if (state) {
/* Already initialized; skip reload */
return 0;
}

return PyModule_ExecDef(mod, def);
}


/*******************/

#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
Expand Down Expand Up @@ -1865,6 +1869,125 @@ PyImport_GetMagicTag(void)
/* importlib */
/*************/

/* Import the _imp extension by calling manually _imp.create_builtin() and
_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;
}

// Mock a ModuleSpec object just good enough for PyModule_FromDefAndSpec():
// an object with just a name attribute.
//
// _imp.__spec__ is overridden by importlib._bootstrap._instal() anyway.
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;
}

// Create the _imp module from its definition.
PyObject *mod = create_builtin(tstate, name, spec);
Py_CLEAR(name);
Py_DECREF(spec);
if (mod == NULL) {
goto error;
}
assert(mod != Py_None); // not found

// Execute the _imp module: call imp_module_exec().
if (exec_builtin_or_dynamic(mod) < 0) {
Py_DECREF(mod);
goto error;
}
return mod;

error:
Py_XDECREF(name);
return NULL;
}

/* Global initializations. Can be undone by Py_FinalizeEx(). Don't
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;

// Import _importlib through its frozen version, _frozen_importlib.
if (verbose) {
PySys_FormatStderr("import _frozen_importlib # frozen\n");
}
if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) {
return -1;
}
PyObject *importlib = PyImport_AddModule("_frozen_importlib"); // borrowed
if (importlib == NULL) {
return -1;
}
interp->importlib = Py_NewRef(importlib);

// Import the _imp module
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;
}

// Install importlib as the implementation of import
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(interp->importlib,
"_install_external_importers", "");
if (value == NULL) {
return -1;
}
Py_DECREF(value);
return 0;
}

PyObject *
_PyImport_GetImportlibLoader(PyInterpreterState *interp,
const char *loader_name)
Expand Down Expand Up @@ -3014,30 +3137,6 @@ _imp__override_frozen_modules_for_tests_impl(PyObject *module, int override)
Py_RETURN_NONE;
}

/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */
static int
exec_builtin_or_dynamic(PyObject *mod) {
PyModuleDef *def;
void *state;

if (!PyModule_Check(mod)) {
return 0;
}

def = PyModule_GetDef(mod);
if (def == NULL) {
return 0;
}

state = PyModule_GetState(mod);
if (state) {
/* Already initialized; skip reload */
return 0;
}

return PyModule_ExecDef(mod, def);
}

#ifdef HAVE_DYNAMIC_LOADING

/*[clinic input]
Expand Down
Loading