Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b9bb748

Browse filesBrowse files
authored
bpo-44050: Extension modules can share state when they don't support sub-interpreters. (pythonGH-27794)
Automerge-Triggered-By: GH:encukou
1 parent 5146877 commit b9bb748
Copy full SHA for b9bb748

File tree

Expand file treeCollapse file tree

4 files changed

+59
-1
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+59
-1
lines changed

‎Lib/test/test_capi.py

Copy file name to clipboardExpand all lines: Lib/test/test_capi.py
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,37 @@ def test_mutate_exception(self):
766766

767767
self.assertFalse(hasattr(binascii.Error, "foobar"))
768768

769+
def test_module_state_shared_in_global(self):
770+
"""
771+
bpo-44050: Extension module state should be shared between interpreters
772+
when it doesn't support sub-interpreters.
773+
"""
774+
r, w = os.pipe()
775+
self.addCleanup(os.close, r)
776+
self.addCleanup(os.close, w)
777+
778+
script = textwrap.dedent(f"""
779+
import importlib.machinery
780+
import importlib.util
781+
import os
782+
783+
fullname = '_test_module_state_shared'
784+
origin = importlib.util.find_spec('_testmultiphase').origin
785+
loader = importlib.machinery.ExtensionFileLoader(fullname, origin)
786+
spec = importlib.util.spec_from_loader(fullname, loader)
787+
module = importlib.util.module_from_spec(spec)
788+
attr_id = str(id(module.Error)).encode()
789+
790+
os.write({w}, attr_id)
791+
""")
792+
exec(script)
793+
main_attr_id = os.read(r, 100)
794+
795+
ret = support.run_in_subinterp(script)
796+
self.assertEqual(ret, 0)
797+
subinterp_attr_id = os.read(r, 100)
798+
self.assertEqual(main_attr_id, subinterp_attr_id)
799+
769800

770801
class TestThreadState(unittest.TestCase):
771802

+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Extensions that indicate they use global state (by setting ``m_size`` to -1)
2+
can again be used in multiple interpreters. This reverts to behavior of
3+
Python 3.8.

‎Modules/_testmultiphase.c

Copy file name to clipboardExpand all lines: Modules/_testmultiphase.c
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,28 @@ PyInit__testmultiphase_meth_state_access(PyObject *spec)
844844
return PyModuleDef_Init(&def_meth_state_access);
845845
}
846846

847+
static PyModuleDef def_module_state_shared = {
848+
PyModuleDef_HEAD_INIT,
849+
.m_name = "_test_module_state_shared",
850+
.m_doc = PyDoc_STR("Regression Test module for single-phase init."),
851+
.m_size = -1,
852+
};
853+
854+
PyMODINIT_FUNC
855+
PyInit__test_module_state_shared(PyObject *spec)
856+
{
857+
PyObject *module = PyModule_Create(&def_module_state_shared);
858+
if (module == NULL) {
859+
return NULL;
860+
}
861+
862+
if (PyModule_AddObjectRef(module, "Error", PyExc_Exception) < 0) {
863+
Py_DECREF(module);
864+
return NULL;
865+
}
866+
return module;
867+
}
868+
847869

848870
/*** Helper for imp test ***/
849871

‎Python/import.c

Copy file name to clipboardExpand all lines: Python/import.c
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,9 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name,
442442
return -1;
443443
}
444444

445-
if (_Py_IsMainInterpreter(tstate->interp)) {
445+
// bpo-44050: Extensions and def->m_base.m_copy can be updated
446+
// when the extension module doesn't support sub-interpreters.
447+
if (_Py_IsMainInterpreter(tstate->interp) || def->m_size == -1) {
446448
if (def->m_size == -1) {
447449
if (def->m_base.m_copy) {
448450
/* Somebody already imported the module,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.