From b83a4ffa9b0a5d772e1210e83c807885e14741c5 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Tue, 5 Oct 2021 21:19:32 +0800 Subject: [PATCH 1/2] [3.9] bpo-44050: Extension modules can share state when they don't support sub-interpreters. (GH-27794) Automerge-Triggered-By: GH:encukou. (cherry picked from commit b9bb74871b27d9226df2dd3fce9d42bda8b43c2b) Co-authored-by: Hai Shi --- Lib/test/test_capi.py | 31 +++++++++++++++++++ .../2021-09-08-00-30-09.bpo-44050.mFI15u.rst | 3 ++ Modules/_testmultiphase.c | 22 +++++++++++++ Python/import.c | 4 ++- 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2021-09-08-00-30-09.bpo-44050.mFI15u.rst diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 0cbe839665e3f6..6b2fe2f1580c36 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -680,6 +680,37 @@ def test_mutate_exception(self): self.assertFalse(hasattr(binascii.Error, "foobar")) + def test_module_state_shared_in_global(self): + """ + bpo-44050: Extension module state should be shared between interpreters + when it doesn't support sub-interpreters. + """ + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + + script = textwrap.dedent(f""" + import importlib.machinery + import importlib.util + import os + + fullname = '_test_module_state_shared' + origin = importlib.util.find_spec('_testmultiphase').origin + loader = importlib.machinery.ExtensionFileLoader(fullname, origin) + spec = importlib.util.spec_from_loader(fullname, loader) + module = importlib.util.module_from_spec(spec) + attr_id = str(id(module.Error)).encode() + + os.write({w}, attr_id) + """) + exec(script) + main_attr_id = os.read(r, 100) + + ret = support.run_in_subinterp(script) + self.assertEqual(ret, 0) + subinterp_attr_id = os.read(r, 100) + self.assertEqual(main_attr_id, subinterp_attr_id) + class TestThreadState(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-09-08-00-30-09.bpo-44050.mFI15u.rst b/Misc/NEWS.d/next/Core and Builtins/2021-09-08-00-30-09.bpo-44050.mFI15u.rst new file mode 100644 index 00000000000000..d6eed9f1bcfe9d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-09-08-00-30-09.bpo-44050.mFI15u.rst @@ -0,0 +1,3 @@ +Extensions that indicate they use global state (by setting ``m_size`` to -1) +can again be used in multiple interpreters. This reverts to behavior of +Python 3.8. diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index d69ae628fa7a40..8a6569f7bc51b3 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -834,6 +834,28 @@ PyInit__testmultiphase_meth_state_access(PyObject *spec) return PyModuleDef_Init(&def_meth_state_access); } +static PyModuleDef def_module_state_shared = { + PyModuleDef_HEAD_INIT, + .m_name = "_test_module_state_shared", + .m_doc = PyDoc_STR("Regression Test module for single-phase init."), + .m_size = -1, +}; + +PyMODINIT_FUNC +PyInit__test_module_state_shared(PyObject *spec) +{ + PyObject *module = PyModule_Create(&def_module_state_shared); + if (module == NULL) { + return NULL; + } + + if (PyModule_AddObjectRef(module, "Error", PyExc_Exception) < 0) { + Py_DECREF(module); + return NULL; + } + return module; +} + /*** Helper for imp test ***/ diff --git a/Python/import.c b/Python/import.c index 1ec755393df997..8358d70f468dd9 100644 --- a/Python/import.c +++ b/Python/import.c @@ -710,7 +710,9 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, return -1; } - if (_Py_IsMainInterpreter(tstate)) { + // bpo-44050: Extensions and def->m_base.m_copy can be updated + // when the extension module doesn't support sub-interpreters. + if (_Py_IsMainInterpreter(tstate) || def->m_size == -1) { if (def->m_size == -1) { if (def->m_base.m_copy) { /* Somebody already imported the module, From f53acff6d50a5838536034e1aac226eccc27e831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 5 Oct 2021 19:22:52 +0200 Subject: [PATCH 2/2] Replace the non-existent PyModule_AddObjectRef with PyModule_AddObject --- Modules/_testmultiphase.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index 8a6569f7bc51b3..4a4dbe77acfac4 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -849,7 +849,9 @@ PyInit__test_module_state_shared(PyObject *spec) return NULL; } - if (PyModule_AddObjectRef(module, "Error", PyExc_Exception) < 0) { + Py_INCREF(PyExc_Exception); + if (PyModule_AddObject(module, "Error", PyExc_Exception) < 0) { + Py_DECREF(PyExc_Exception); Py_DECREF(module); return NULL; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy