bpo-44050: Extension modules can share state when they don't support sub-interpreters. (GH-27794) (GH-28738)

Automerge-Triggered-By: GH:encukou
(cherry picked from commit b9bb74871b27d9226df2dd3fce9d42bda8b43c2b)

Co-authored-by: Hai Shi <shihai1992@gmail.com>
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 5f78c33..db26b9b 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -762,6 +762,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):