diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2024-05-04 21:24:02 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-04 21:24:02 (GMT) |
commit | 291cfa454b9c5b677c955aaf53fab91f0186b6fa (patch) | |
tree | 0a0976010c9f0bd5fb77f80e00f44fa726d7c665 /Python/importdl.c | |
parent | 978fba58aef347de4a1376e525df2dacc7b2fff3 (diff) | |
download | cpython-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.c | 24 |
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; |