summaryrefslogtreecommitdiffstats
path: root/Lib/importlib/util.py
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2023-05-08 22:56:01 (GMT)
committerGitHub <noreply@github.com>2023-05-08 22:56:01 (GMT)
commit4541d1a0dba3ef0c386991cf54c4c3c411a364c0 (patch)
treec79210120e5a9ea0835a6e63fa5a63f9ff5078ad /Lib/importlib/util.py
parent5c9ee498c6f4b75e0e020f17b6860309c3b7e11e (diff)
downloadcpython-4541d1a0dba3ef0c386991cf54c4c3c411a364c0.zip
cpython-4541d1a0dba3ef0c386991cf54c4c3c411a364c0.tar.gz
cpython-4541d1a0dba3ef0c386991cf54c4c3c411a364c0.tar.bz2
gh-104310: Add importlib.util.allowing_all_extensions() (gh-104311)
(I'll be adding docs for this separately.)
Diffstat (limited to 'Lib/importlib/util.py')
-rw-r--r--Lib/importlib/util.py37
1 files changed, 37 insertions, 0 deletions
diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py
index 5294578..b1d9271 100644
--- a/Lib/importlib/util.py
+++ b/Lib/importlib/util.py
@@ -112,6 +112,43 @@ def find_spec(name, package=None):
return spec
+# Normally we would use contextlib.contextmanager. However, this module
+# 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.
+
+ 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.
+
+ Likewise for modules import in a subinterpeter with its own GIL
+ when the extension does not support a per-interpreter GIL. This
+ implies the module does not have a Py_mod_multiple_interpreters slot
+ set to Py_MOD_PER_INTERPRETER_GIL_SUPPORTED.
+
+ In both cases, this context manager may be used to temporarily
+ disable the check for compatible extension modules.
+ """
+
+ def __init__(self, disable_check=True):
+ self.disable_check = disable_check
+
+ def __enter__(self):
+ self.old = _imp._override_multi_interp_extensions_check(self.override)
+ return self
+
+ def __exit__(self, *args):
+ old = self.old
+ del self.old
+ _imp._override_multi_interp_extensions_check(old)
+
+ @property
+ def override(self):
+ return -1 if self.disable_check else 1
+
+
class _LazyModule(types.ModuleType):
"""A subclass of the module type which triggers loading upon attribute access."""