summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2023-02-15 22:32:31 (GMT)
committerGitHub <noreply@github.com>2023-02-15 22:32:31 (GMT)
commitb2fc5492789623d656953d458f3eeaac03c1ef56 (patch)
treeef2614bd53b935d48170ae2d936ca873ffc92cfc /Include
parentc1ce0d178fe57b50f37578b285a343d77485ac02 (diff)
downloadcpython-b2fc5492789623d656953d458f3eeaac03c1ef56.zip
cpython-b2fc5492789623d656953d458f3eeaac03c1ef56.tar.gz
cpython-b2fc5492789623d656953d458f3eeaac03c1ef56.tar.bz2
gh-101758: Clean Up Uses of Import State (gh-101919)
This change is almost entirely moving code around and hiding import state behind internal API. We introduce no changes to behavior, nor to non-internal API. (Since there was already going to be a lot of churn, I took this as an opportunity to re-organize import.c into topically-grouped sections of code.) The motivation is to simplify a number of upcoming changes. Specific changes: * move existing import-related code to import.c, wherever possible * add internal API for interacting with import state (both global and per-interpreter) * use only API outside of import.c (to limit churn there when changing the location, etc.) * consolidate the import-related state of PyInterpreterState into a single struct field (this changes layout slightly) * add macros for import state in import.c (to simplify changing the location) * group code in import.c into sections *remove _PyState_AddModule() https://github.com/python/cpython/issues/101758
Diffstat (limited to 'Include')
-rw-r--r--Include/internal/pycore_import.h103
-rw-r--r--Include/internal/pycore_interp.h35
-rw-r--r--Include/internal/pycore_pylifecycle.h4
-rw-r--r--Include/internal/pycore_pystate.h6
-rw-r--r--Include/internal/pycore_runtime_init.h15
-rw-r--r--Include/internal/pycore_sysmodule.h3
6 files changed, 109 insertions, 57 deletions
diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h
index 9036dff..da76625 100644
--- a/Include/internal/pycore_import.h
+++ b/Include/internal/pycore_import.h
@@ -36,11 +36,112 @@ struct _import_runtime_state {
const char * pkgcontext;
};
+struct _import_state {
+ /* cached sys.modules dictionary */
+ PyObject *modules;
+ /* This is the list of module objects for all legacy (single-phase init)
+ extension modules ever loaded in this process (i.e. imported
+ in this interpreter or in any other). Py_None stands in for
+ modules that haven't actually been imported in this interpreter.
+
+ A module's index (PyModuleDef.m_base.m_index) is used to look up
+ the corresponding module object for this interpreter, if any.
+ (See PyState_FindModule().) When any extension module
+ is initialized during import, its moduledef gets initialized by
+ PyModuleDef_Init(), and the first time that happens for each
+ PyModuleDef, its index gets set to the current value of
+ a global counter (see _PyRuntimeState.imports.last_module_index).
+ The entry for that index in this interpreter remains unset until
+ the module is actually imported here. (Py_None is used as
+ a placeholder.) Note that multi-phase init modules always get
+ an index for which there will never be a module set.
+
+ This is initialized lazily in PyState_AddModule(), which is also
+ where modules get added. */
+ PyObject *modules_by_index;
+ /* importlib module._bootstrap */
+ PyObject *importlib;
+ /* override for config->use_frozen_modules (for tests)
+ (-1: "off", 1: "on", 0: no override) */
+ int override_frozen_modules;
+#ifdef HAVE_DLOPEN
+ int dlopenflags;
+#endif
+ PyObject *import_func;
+};
+
+#ifdef HAVE_DLOPEN
+# include <dlfcn.h>
+# if HAVE_DECL_RTLD_NOW
+# define _Py_DLOPEN_FLAGS RTLD_NOW
+# else
+# define _Py_DLOPEN_FLAGS RTLD_LAZY
+# endif
+# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS,
+#else
+# define _Py_DLOPEN_FLAGS 0
+# define DLOPENFLAGS_INIT
+#endif
+
+#define IMPORTS_INIT \
+ { \
+ .override_frozen_modules = 0, \
+ DLOPENFLAGS_INIT \
+ }
+
+extern void _PyImport_ClearCore(PyInterpreterState *interp);
+
+extern Py_ssize_t _PyImport_GetNextModuleIndex(void);
+extern const char * _PyImport_ResolveNameWithPackageContext(const char *name);
+extern const char * _PyImport_SwapPackageContext(const char *newcontext);
+
+extern int _PyImport_GetDLOpenFlags(PyInterpreterState *interp);
+extern void _PyImport_SetDLOpenFlags(PyInterpreterState *interp, int new_val);
+
+extern PyObject * _PyImport_InitModules(PyInterpreterState *interp);
+extern PyObject * _PyImport_GetModules(PyInterpreterState *interp);
+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 PyObject * _PyImport_GetImportlibLoader(
+ PyInterpreterState *interp,
+ const char *loader_name);
+extern PyObject * _PyImport_GetImportlibExternalLoader(
+ PyInterpreterState *interp,
+ const char *loader_name);
+extern PyObject * _PyImport_BlessMyLoader(
+ PyInterpreterState *interp,
+ PyObject *module_globals);
+extern PyObject * _PyImport_ImportlibModuleRepr(
+ PyInterpreterState *interp,
+ PyObject *module);
+
+
+extern PyStatus _PyImport_Init(void);
+extern void _PyImport_Fini(void);
+extern void _PyImport_Fini2(void);
+
+extern PyStatus _PyImport_InitCore(
+ PyThreadState *tstate,
+ PyObject *sysmod,
+ int importlib);
+extern PyStatus _PyImport_InitExternal(PyThreadState *tstate);
+extern void _PyImport_FiniCore(PyInterpreterState *interp);
+extern void _PyImport_FiniExternal(PyInterpreterState *interp);
+
#ifdef HAVE_FORK
extern PyStatus _PyImport_ReInitLock(void);
#endif
-extern PyObject* _PyImport_BootstrapImp(PyThreadState *tstate);
+
+
+extern PyObject* _PyImport_GetBuiltinModuleNames(void);
struct _module_alias {
const char *name; /* ASCII encoded string */
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 0e3d468..60de31b 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -21,6 +21,7 @@ extern "C" {
#include "pycore_function.h" // FUNC_MAX_WATCHERS
#include "pycore_genobject.h" // struct _Py_async_gen_state
#include "pycore_gc.h" // struct _gc_runtime_state
+#include "pycore_import.h" // struct _import_state
#include "pycore_list.h" // struct _Py_list_state
#include "pycore_global_objects.h" // struct _Py_interp_static_objects
#include "pycore_tuple.h" // struct _Py_tuple_state
@@ -92,37 +93,12 @@ struct _is {
struct _ceval_state ceval;
struct _gc_runtime_state gc;
- // sys.modules dictionary
- PyObject *modules;
- /* This is the list of module objects for all legacy (single-phase init)
- extension modules ever loaded in this process (i.e. imported
- in this interpreter or in any other). Py_None stands in for
- modules that haven't actually been imported in this interpreter.
-
- A module's index (PyModuleDef.m_base.m_index) is used to look up
- the corresponding module object for this interpreter, if any.
- (See PyState_FindModule().) When any extension module
- is initialized during import, its moduledef gets initialized by
- PyModuleDef_Init(), and the first time that happens for each
- PyModuleDef, its index gets set to the current value of
- a global counter (see _PyRuntimeState.imports.last_module_index).
- The entry for that index in this interpreter remains unset until
- the module is actually imported here. (Py_None is used as
- a placeholder.) Note that multi-phase init modules always get
- an index for which there will never be a module set.
-
- This is initialized lazily in _PyState_AddModule(), which is also
- where modules get added. */
- PyObject *modules_by_index;
+ struct _import_state imports;
+
// Dictionary of the sys module
PyObject *sysdict;
// Dictionary of the builtins module
PyObject *builtins;
- // importlib module
- PyObject *importlib;
- // override for config->use_frozen_modules (for tests)
- // (-1: "off", 1: "on", 0: no override)
- int override_frozen_modules;
PyObject *codec_search_path;
PyObject *codec_search_cache;
@@ -130,15 +106,11 @@ struct _is {
int codecs_initialized;
PyConfig config;
-#ifdef HAVE_DLOPEN
- int dlopenflags;
-#endif
unsigned long feature_flags;
PyObject *dict; /* Stores per-interpreter state */
PyObject *builtins_copy;
- PyObject *import_func;
// Initialized to _PyEval_EvalFrameDefault().
_PyFrameEvalFunction eval_frame;
@@ -205,7 +177,6 @@ struct _is {
/* other API */
-extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);
extern void _PyInterpreterState_Clear(PyThreadState *tstate);
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 2d431be..e7a3180 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -30,7 +30,6 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
/* Various one-time initializers */
extern void _Py_InitVersion(void);
-extern PyStatus _PyImport_Init(void);
extern PyStatus _PyFaulthandler_Init(int enable);
extern int _PyTraceMalloc_Init(int enable);
extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp);
@@ -45,7 +44,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);
@@ -55,8 +53,6 @@ extern int _Py_Deepfreeze_Init(void);
extern int _PySignal_Init(int install_signal_handlers);
extern void _PySignal_Fini(void);
-extern void _PyImport_Fini(void);
-extern void _PyImport_Fini2(void);
extern void _PyGC_Fini(PyInterpreterState *interp);
extern void _Py_HashRandomization_Fini(void);
extern void _PyFaulthandler_Fini(void);
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index 7046ec8..638b862 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -152,12 +152,6 @@ extern void _PySignal_AfterFork(void);
#endif
-PyAPI_FUNC(int) _PyState_AddModule(
- PyThreadState *tstate,
- PyObject* module,
- PyModuleDef* def);
-
-
PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate);
#define HEAD_LOCK(runtime) \
diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h
index c6a27d0..a8d5953 100644
--- a/Include/internal/pycore_runtime_init.h
+++ b/Include/internal/pycore_runtime_init.h
@@ -97,23 +97,10 @@ extern "C" {
._main_interpreter = _PyInterpreterState_INIT, \
}
-#ifdef HAVE_DLOPEN
-# include <dlfcn.h>
-# if HAVE_DECL_RTLD_NOW
-# define _Py_DLOPEN_FLAGS RTLD_NOW
-# else
-# define _Py_DLOPEN_FLAGS RTLD_LAZY
-# endif
-# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS,
-#else
-# define _Py_DLOPEN_FLAGS 0
-# define DLOPENFLAGS_INIT
-#endif
-
#define _PyInterpreterState_INIT \
{ \
.id_refcount = -1, \
- DLOPENFLAGS_INIT \
+ .imports = IMPORTS_INIT, \
.ceval = { \
.recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \
}, \
diff --git a/Include/internal/pycore_sysmodule.h b/Include/internal/pycore_sysmodule.h
index 10d092c..b4b1feb 100644
--- a/Include/internal/pycore_sysmodule.h
+++ b/Include/internal/pycore_sysmodule.h
@@ -20,6 +20,9 @@ extern void _PySys_ClearAuditHooks(PyThreadState *tstate);
PyAPI_FUNC(int) _PySys_SetAttr(PyObject *, PyObject *);
+extern int _PySys_ClearAttrString(PyInterpreterState *interp,
+ const char *name, int verbose);
+
#ifdef __cplusplus
}
#endif