summaryrefslogtreecommitdiffstats
path: root/Python/importdl.c
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2024-05-04 21:24:02 (GMT)
committerGitHub <noreply@github.com>2024-05-04 21:24:02 (GMT)
commit291cfa454b9c5b677c955aaf53fab91f0186b6fa (patch)
tree0a0976010c9f0bd5fb77f80e00f44fa726d7c665 /Python/importdl.c
parent978fba58aef347de4a1376e525df2dacc7b2fff3 (diff)
downloadcpython-291cfa454b9c5b677c955aaf53fab91f0186b6fa.zip
cpython-291cfa454b9c5b677c955aaf53fab91f0186b6fa.tar.gz
cpython-291cfa454b9c5b677c955aaf53fab91f0186b6fa.tar.bz2
gh-117953: Track Extra Details in Global Extensions Cache (gh-118532)
We have only been tracking each module's PyModuleDef. However, there are some problems with that. For example, in some cases we load single-phase init extension modules from def->m_base.m_init or def->m_base.m_copy, but if multiple modules share a def then we can end up with unexpected behavior. With this change, we track the following: * PyModuleDef (same as before) * for some modules, its init function or a copy of its __dict__, but specific to that module * whether it is a builtin/core module or a "dynamic" extension * the interpreter (ID) that owns the cached __dict__ (only if cached) This also makes it easier to remember the module's kind (e.g. single-phase init) and if loading it previously failed, which I'm doing separately.
Diffstat (limited to 'Python/importdl.c')
-rw-r--r--Python/importdl.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/Python/importdl.c b/Python/importdl.c
index a309194..38f56db 100644
--- a/Python/importdl.c
+++ b/Python/importdl.c
@@ -111,9 +111,12 @@ _Py_ext_module_loader_info_clear(struct _Py_ext_module_loader_info *info)
int
_Py_ext_module_loader_info_init(struct _Py_ext_module_loader_info *p_info,
- PyObject *name, PyObject *filename)
+ PyObject *name, PyObject *filename,
+ _Py_ext_module_origin origin)
{
- struct _Py_ext_module_loader_info info = {0};
+ struct _Py_ext_module_loader_info info = {
+ .origin=origin,
+ };
assert(name != NULL);
if (!PyUnicode_Check(name)) {
@@ -183,6 +186,7 @@ _Py_ext_module_loader_info_init_for_builtin(
.name_encoded=name_encoded,
/* We won't need filename. */
.path=name,
+ .origin=_Py_ext_module_origin_BUILTIN,
.hook_prefix=ascii_only_prefix,
.newcontext=NULL,
};
@@ -190,6 +194,18 @@ _Py_ext_module_loader_info_init_for_builtin(
}
int
+_Py_ext_module_loader_info_init_for_core(
+ struct _Py_ext_module_loader_info *info,
+ PyObject *name)
+{
+ if (_Py_ext_module_loader_info_init_for_builtin(info, name) < 0) {
+ return -1;
+ }
+ info->origin = _Py_ext_module_origin_CORE;
+ return 0;
+}
+
+int
_Py_ext_module_loader_info_init_from_spec(
struct _Py_ext_module_loader_info *p_info,
PyObject *spec)
@@ -203,7 +219,9 @@ _Py_ext_module_loader_info_init_from_spec(
Py_DECREF(name);
return -1;
}
- int err = _Py_ext_module_loader_info_init(p_info, name, filename);
+ /* We could also accommodate builtin modules here without much trouble. */
+ _Py_ext_module_origin origin = _Py_ext_module_origin_DYNAMIC;
+ int err = _Py_ext_module_loader_info_init(p_info, name, filename, origin);
Py_DECREF(name);
Py_DECREF(filename);
return err;