[Python-checkins] gh-104310: Rename the New Function in importlib.util (gh-105255)

ericsnowcurrently webhook-mailer at python.org
Thu Jun 8 14:20:06 EDT 2023


https://github.com/python/cpython/commit/34c63b86d3c33a85acf55a0c5c118304754e145d
commit: 34c63b86d3c33a85acf55a0c5c118304754e145d
branch: main
author: Eric Snow <ericsnowcurrently at gmail.com>
committer: ericsnowcurrently <ericsnowcurrently at gmail.com>
date: 2023-06-08T18:19:58Z
summary:

gh-104310: Rename the New Function in importlib.util (gh-105255)

The original name wasn't as clear as it could have been. This change includes the following:

* rename the function
* change the default value for "disable_check" to False
* add clues to the docstring that folks should probably not use the function

---------

Co-authored-by: Kirill Podoprigora <kirill.bast9 at mail.ru>

files:
A Misc/NEWS.d/next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst
M Lib/importlib/util.py
M Lib/test/test_importlib/test_util.py

diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py
index b1d9271f8e47..f4d6e8233151 100644
--- a/Lib/importlib/util.py
+++ b/Lib/importlib/util.py
@@ -116,12 +116,24 @@ def find_spec(name, package=None):
 # is imported by runpy, which means we want to avoid any unnecessary
 # dependencies.  Thus we use a class.
 
-class allowing_all_extensions:
-    """A context manager that lets users skip the compatibility check.
+class _incompatible_extension_module_restrictions:
+    """A context manager that can temporarily skip the compatibility check.
+
+    NOTE: This function is meant to accommodate an unusual case; one
+    which is likely to eventually go away.  There's is a pretty good
+    chance this is not what you were looking for.
+
+    WARNING: Using this function to disable the check can lead to
+    unexpected behavior and even crashes.  It should only be used during
+    extension module development.
+
+    If "disable_check" is True then the compatibility check will not
+    happen while the context manager is active.  Otherwise the check
+    *will* happen.
 
     Normally, extensions that do not support multiple interpreters
     may not be imported in a subinterpreter.  That implies modules
-    that do not implement multi-phase init.
+    that do not implement multi-phase init or that explicitly of out.
 
     Likewise for modules import in a subinterpeter with its own GIL
     when the extension does not support a per-interpreter GIL.  This
@@ -130,10 +142,14 @@ class allowing_all_extensions:
 
     In both cases, this context manager may be used to temporarily
     disable the check for compatible extension modules.
+
+    You can get the same effect as this function by implementing the
+    basic interface of multi-phase init (PEP 489) and lying about
+    support for mulitple interpreters (or per-interpreter GIL).
     """
 
-    def __init__(self, disable_check=True):
-        self.disable_check = disable_check
+    def __init__(self, *, disable_check):
+        self.disable_check = bool(disable_check)
 
     def __enter__(self):
         self.old = _imp._override_multi_interp_extensions_check(self.override)
diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py
index 0be504925ecc..e967adc9451c 100644
--- a/Lib/test/test_importlib/test_util.py
+++ b/Lib/test/test_importlib/test_util.py
@@ -653,7 +653,7 @@ def test_magic_number(self):
 
 
 @unittest.skipIf(_interpreters is None, 'subinterpreters required')
-class AllowingAllExtensionsTests(unittest.TestCase):
+class IncompatibleExtensionModuleRestrictionsTests(unittest.TestCase):
 
     ERROR = re.compile("^<class 'ImportError'>: module (.*) does not support loading in subinterpreters")
 
@@ -678,8 +678,8 @@ def run_with_shared_gil(self, script):
     @unittest.skipIf(_testsinglephase is None, "test requires _testsinglephase module")
     def test_single_phase_init_module(self):
         script = textwrap.dedent('''
-            import importlib.util
-            with importlib.util.allowing_all_extensions():
+            from importlib.util import _incompatible_extension_module_restrictions
+            with _incompatible_extension_module_restrictions(disable_check=True):
                 import _testsinglephase
             ''')
         with self.subTest('check disabled, shared GIL'):
@@ -688,8 +688,8 @@ def test_single_phase_init_module(self):
             self.run_with_own_gil(script)
 
         script = textwrap.dedent(f'''
-            import importlib.util
-            with importlib.util.allowing_all_extensions(False):
+            from importlib.util import _incompatible_extension_module_restrictions
+            with _incompatible_extension_module_restrictions(disable_check=False):
                 import _testsinglephase
             ''')
         with self.subTest('check enabled, shared GIL'):
@@ -713,8 +713,8 @@ def test_incomplete_multi_phase_init_module(self):
             ''')
 
         script = prescript + textwrap.dedent('''
-            import importlib.util
-            with importlib.util.allowing_all_extensions():
+            from importlib.util import _incompatible_extension_module_restrictions
+            with _incompatible_extension_module_restrictions(disable_check=True):
                 module = module_from_spec(spec)
                 loader.exec_module(module)
             ''')
@@ -724,8 +724,8 @@ def test_incomplete_multi_phase_init_module(self):
             self.run_with_own_gil(script)
 
         script = prescript + textwrap.dedent('''
-            import importlib.util
-            with importlib.util.allowing_all_extensions(False):
+            from importlib.util import _incompatible_extension_module_restrictions
+            with _incompatible_extension_module_restrictions(disable_check=False):
                 module = module_from_spec(spec)
                 loader.exec_module(module)
             ''')
@@ -738,8 +738,8 @@ def test_incomplete_multi_phase_init_module(self):
     @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module")
     def test_complete_multi_phase_init_module(self):
         script = textwrap.dedent('''
-            import importlib.util
-            with importlib.util.allowing_all_extensions():
+            from importlib.util import _incompatible_extension_module_restrictions
+            with _incompatible_extension_module_restrictions(disable_check=True):
                 import _testmultiphase
             ''')
         with self.subTest('check disabled, shared GIL'):
@@ -748,8 +748,8 @@ def test_complete_multi_phase_init_module(self):
             self.run_with_own_gil(script)
 
         script = textwrap.dedent(f'''
-            import importlib.util
-            with importlib.util.allowing_all_extensions(False):
+            from importlib.util import _incompatible_extension_module_restrictions
+            with _incompatible_extension_module_restrictions(disable_check=False):
                 import _testmultiphase
             ''')
         with self.subTest('check enabled, shared GIL'):
diff --git a/Misc/NEWS.d/next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst b/Misc/NEWS.d/next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst
new file mode 100644
index 000000000000..461a3a25fe1b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst
@@ -0,0 +1,7 @@
+In the beta 1 release we added a utility function for extension module
+authors, to use when testing their module for support in multiple
+interpreters or under a per-interpreter GIL.  The name of that function has
+changed from ``allowing_all_extensions`` to
+``_incompatible_extension_module_restrictions``.  The default for the
+"disable_check" argument has change from ``True`` to ``False``, to better
+match the new function name.



More information about the Python-checkins mailing list