mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-123880: Allow recursive import of single-phase-init modules (GH-123950)
Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: Brett Cannon <brett@python.org>
This commit is contained in:
parent
3e36e5aef1
commit
aee219f455
6 changed files with 141 additions and 25 deletions
|
@ -1,7 +1,7 @@
|
|||
|
||||
/* Testing module for single-phase initialization of extension modules
|
||||
|
||||
This file contains 8 distinct modules, meaning each as its own name
|
||||
This file contains several distinct modules, meaning each as its own name
|
||||
and its own init function (PyInit_...). The default import system will
|
||||
only find the one matching the filename: _testsinglephase. To load the
|
||||
others you must do so manually. For example:
|
||||
|
@ -12,9 +12,13 @@ filename = _testsinglephase.__file__
|
|||
loader = importlib.machinery.ExtensionFileLoader(name, filename)
|
||||
spec = importlib.util.spec_from_file_location(name, filename, loader=loader)
|
||||
mod = importlib._bootstrap._load(spec)
|
||||
loader.exec_module(module)
|
||||
sys.modules[modname] = module
|
||||
```
|
||||
|
||||
Here are the 8 modules:
|
||||
(The last two lines are just for completeness.)
|
||||
|
||||
Here are the modules:
|
||||
|
||||
* _testsinglephase
|
||||
* def: _testsinglephase_basic,
|
||||
|
@ -163,6 +167,11 @@ Here are the 8 modules:
|
|||
* functions: none
|
||||
* import system: same as _testsinglephase_with_state
|
||||
|
||||
* _testsinglephase_circular
|
||||
Regression test for gh-123880.
|
||||
Does not have the common attributes & methods.
|
||||
See test_singlephase_circular test.test_import.SinglephaseInitTests.
|
||||
|
||||
Module state:
|
||||
|
||||
* fields
|
||||
|
@ -740,3 +749,53 @@ PyInit__testsinglephase_with_state_check_cache_first(void)
|
|||
}
|
||||
return PyModule_Create(&_testsinglephase_with_state_check_cache_first);
|
||||
}
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* the _testsinglephase_circular module */
|
||||
/****************************************/
|
||||
|
||||
static PyObject *static_module_circular;
|
||||
|
||||
static PyObject *
|
||||
circularmod_clear_static_var(PyObject *self, PyObject *arg)
|
||||
{
|
||||
PyObject *result = static_module_circular;
|
||||
static_module_circular = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct PyModuleDef _testsinglephase_circular = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "_testsinglephase_circular",
|
||||
.m_doc = PyDoc_STR("Test module _testsinglephase_circular"),
|
||||
.m_methods = (PyMethodDef[]) {
|
||||
{"clear_static_var", circularmod_clear_static_var, METH_NOARGS,
|
||||
"Clear the static variable and return its previous value."},
|
||||
{NULL, NULL} /* sentinel */
|
||||
}
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit__testsinglephase_circular(void)
|
||||
{
|
||||
if (!static_module_circular) {
|
||||
static_module_circular = PyModule_Create(&_testsinglephase_circular);
|
||||
if (!static_module_circular) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
static const char helper_mod_name[] = (
|
||||
"test.test_import.data.circular_imports.singlephase");
|
||||
PyObject *helper_mod = PyImport_ImportModule(helper_mod_name);
|
||||
Py_XDECREF(helper_mod);
|
||||
if (!helper_mod) {
|
||||
return NULL;
|
||||
}
|
||||
if(PyModule_AddStringConstant(static_module_circular,
|
||||
"helper_mod_name",
|
||||
helper_mod_name) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return Py_NewRef(static_module_circular);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue