# 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
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)
@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")
@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'):
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'):
''')
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)
''')
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)
''')
@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'):
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'):