summaryrefslogtreecommitdiffstats
path: root/Modules/_testsinglephase.c
diff options
context:
space:
mode:
authorPetr Viktorin <encukou@gmail.com>2024-09-20 08:27:34 (GMT)
committerGitHub <noreply@github.com>2024-09-20 08:27:34 (GMT)
commitaee219f4558dda619bd86e4b0e028ce47a5e4b77 (patch)
treee5dce2eb3fb98831d5367f556e2e8c83408b0617 /Modules/_testsinglephase.c
parent3e36e5aef18e326f5d1081d73ee8d8fefa1d82f8 (diff)
downloadcpython-aee219f4558dda619bd86e4b0e028ce47a5e4b77.zip
cpython-aee219f4558dda619bd86e4b0e028ce47a5e4b77.tar.gz
cpython-aee219f4558dda619bd86e4b0e028ce47a5e4b77.tar.bz2
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>
Diffstat (limited to 'Modules/_testsinglephase.c')
-rw-r--r--Modules/_testsinglephase.c63
1 files changed, 61 insertions, 2 deletions
diff --git a/Modules/_testsinglephase.c b/Modules/_testsinglephase.c
index 066e0db..2c59085 100644
--- a/Modules/_testsinglephase.c
+++ b/Modules/_testsinglephase.c
@@ -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);
+}