mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
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.
This commit is contained in:
parent
978fba58ae
commit
291cfa454b
3 changed files with 577 additions and 137 deletions
|
@ -22,6 +22,11 @@ typedef enum ext_module_kind {
|
||||||
_Py_ext_module_kind_INVALID = 3,
|
_Py_ext_module_kind_INVALID = 3,
|
||||||
} _Py_ext_module_kind;
|
} _Py_ext_module_kind;
|
||||||
|
|
||||||
|
typedef enum ext_module_origin {
|
||||||
|
_Py_ext_module_origin_CORE = 1,
|
||||||
|
_Py_ext_module_origin_BUILTIN = 2,
|
||||||
|
_Py_ext_module_origin_DYNAMIC = 3,
|
||||||
|
} _Py_ext_module_origin;
|
||||||
|
|
||||||
/* Input for loading an extension module. */
|
/* Input for loading an extension module. */
|
||||||
struct _Py_ext_module_loader_info {
|
struct _Py_ext_module_loader_info {
|
||||||
|
@ -34,6 +39,7 @@ struct _Py_ext_module_loader_info {
|
||||||
/* path is always a borrowed ref of name or filename,
|
/* path is always a borrowed ref of name or filename,
|
||||||
* depending on if it's builtin or not. */
|
* depending on if it's builtin or not. */
|
||||||
PyObject *path;
|
PyObject *path;
|
||||||
|
_Py_ext_module_origin origin;
|
||||||
const char *hook_prefix;
|
const char *hook_prefix;
|
||||||
const char *newcontext;
|
const char *newcontext;
|
||||||
};
|
};
|
||||||
|
@ -42,7 +48,11 @@ extern void _Py_ext_module_loader_info_clear(
|
||||||
extern int _Py_ext_module_loader_info_init(
|
extern int _Py_ext_module_loader_info_init(
|
||||||
struct _Py_ext_module_loader_info *info,
|
struct _Py_ext_module_loader_info *info,
|
||||||
PyObject *name,
|
PyObject *name,
|
||||||
PyObject *filename);
|
PyObject *filename,
|
||||||
|
_Py_ext_module_origin origin);
|
||||||
|
extern int _Py_ext_module_loader_info_init_for_core(
|
||||||
|
struct _Py_ext_module_loader_info *p_info,
|
||||||
|
PyObject *name);
|
||||||
extern int _Py_ext_module_loader_info_init_for_builtin(
|
extern int _Py_ext_module_loader_info_init_for_builtin(
|
||||||
struct _Py_ext_module_loader_info *p_info,
|
struct _Py_ext_module_loader_info *p_info,
|
||||||
PyObject *name);
|
PyObject *name);
|
||||||
|
|
678
Python/import.c
678
Python/import.c
File diff suppressed because it is too large
Load diff
|
@ -111,9 +111,12 @@ _Py_ext_module_loader_info_clear(struct _Py_ext_module_loader_info *info)
|
||||||
|
|
||||||
int
|
int
|
||||||
_Py_ext_module_loader_info_init(struct _Py_ext_module_loader_info *p_info,
|
_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);
|
assert(name != NULL);
|
||||||
if (!PyUnicode_Check(name)) {
|
if (!PyUnicode_Check(name)) {
|
||||||
|
@ -183,12 +186,25 @@ _Py_ext_module_loader_info_init_for_builtin(
|
||||||
.name_encoded=name_encoded,
|
.name_encoded=name_encoded,
|
||||||
/* We won't need filename. */
|
/* We won't need filename. */
|
||||||
.path=name,
|
.path=name,
|
||||||
|
.origin=_Py_ext_module_origin_BUILTIN,
|
||||||
.hook_prefix=ascii_only_prefix,
|
.hook_prefix=ascii_only_prefix,
|
||||||
.newcontext=NULL,
|
.newcontext=NULL,
|
||||||
};
|
};
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
int
|
||||||
_Py_ext_module_loader_info_init_from_spec(
|
_Py_ext_module_loader_info_init_from_spec(
|
||||||
struct _Py_ext_module_loader_info *p_info,
|
struct _Py_ext_module_loader_info *p_info,
|
||||||
|
@ -203,7 +219,9 @@ _Py_ext_module_loader_info_init_from_spec(
|
||||||
Py_DECREF(name);
|
Py_DECREF(name);
|
||||||
return -1;
|
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(name);
|
||||||
Py_DECREF(filename);
|
Py_DECREF(filename);
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue