From 4f9521d91905f1c7673c9c1b9894490bdf438208 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 2 Jun 2023 13:48:26 -0600 Subject: [PATCH 1/7] Fix the function doc string. --- Lib/importlib/util.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index b1d9271f8e47ca..e5cc6f2d10d092 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -117,11 +117,19 @@ def find_spec(name, package=None): # dependencies. Thus we use a class. class allowing_all_extensions: - """A context manager that lets users skip the compatibility check. + """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. 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,6 +138,10 @@ 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): From 04b36cf0f3f5a0149d4e8aa0ec79685400147701 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 2 Jun 2023 14:06:49 -0600 Subject: [PATCH 2/7] Set the default for disable_check to False. --- Lib/importlib/util.py | 6 +++++- Lib/test/test_importlib/test_util.py | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index e5cc6f2d10d092..6cfaab37ff3a49 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -127,6 +127,10 @@ class allowing_all_extensions: 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 (and by + default) 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 or that explicitly of out. @@ -144,7 +148,7 @@ class allowing_all_extensions: support for mulitple interpreters (or per-interpreter GIL). """ - def __init__(self, disable_check=True): + def __init__(self, disable_check=False): self.disable_check = disable_check def __enter__(self): diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 0be504925ecc6a..deed9b5f6652a8 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -679,7 +679,7 @@ def run_with_shared_gil(self, script): def test_single_phase_init_module(self): script = textwrap.dedent(''' import importlib.util - with importlib.util.allowing_all_extensions(): + with importlib.util.allowing_all_extensions(True): import _testsinglephase ''') with self.subTest('check disabled, shared GIL'): @@ -699,6 +699,15 @@ def test_single_phase_init_module(self): with self.assertRaises(ImportError): self.run_with_own_gil(script) + script = textwrap.dedent(f''' + import importlib.util + with importlib.util.allowing_all_extensions(): + import _testsinglephase + ''') + with self.subTest('check enabled (default)'): + with self.assertRaises(ImportError): + self.run_with_shared_gil(script) + @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") def test_incomplete_multi_phase_init_module(self): prescript = textwrap.dedent(f''' @@ -714,7 +723,7 @@ def test_incomplete_multi_phase_init_module(self): script = prescript + textwrap.dedent(''' import importlib.util - with importlib.util.allowing_all_extensions(): + with importlib.util.allowing_all_extensions(True): module = module_from_spec(spec) loader.exec_module(module) ''') @@ -739,7 +748,7 @@ def test_incomplete_multi_phase_init_module(self): def test_complete_multi_phase_init_module(self): script = textwrap.dedent(''' import importlib.util - with importlib.util.allowing_all_extensions(): + with importlib.util.allowing_all_extensions(True): import _testmultiphase ''') with self.subTest('check disabled, shared GIL'): From d459defaca1ea7319cf299b7df93f4aebe001623 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 2 Jun 2023 14:08:32 -0600 Subject: [PATCH 3/7] Change the function name. --- Lib/importlib/util.py | 2 +- Lib/test/test_importlib/test_util.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index 6cfaab37ff3a49..cc4a10b1b3c330 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -116,7 +116,7 @@ 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: +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 diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index deed9b5f6652a8..be7aee61b198f4 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("^: module (.*) does not support loading in subinterpreters") @@ -679,7 +679,7 @@ def run_with_shared_gil(self, script): def test_single_phase_init_module(self): script = textwrap.dedent(''' import importlib.util - with importlib.util.allowing_all_extensions(True): + with importlib.util._incompatible_extension_module_restrictions(True): import _testsinglephase ''') with self.subTest('check disabled, shared GIL'): @@ -689,7 +689,7 @@ def test_single_phase_init_module(self): script = textwrap.dedent(f''' import importlib.util - with importlib.util.allowing_all_extensions(False): + with importlib.util._incompatible_extension_module_restrictions(False): import _testsinglephase ''') with self.subTest('check enabled, shared GIL'): @@ -701,7 +701,7 @@ def test_single_phase_init_module(self): script = textwrap.dedent(f''' import importlib.util - with importlib.util.allowing_all_extensions(): + with importlib.util._incompatible_extension_module_restrictions(): import _testsinglephase ''') with self.subTest('check enabled (default)'): @@ -723,7 +723,7 @@ def test_incomplete_multi_phase_init_module(self): script = prescript + textwrap.dedent(''' import importlib.util - with importlib.util.allowing_all_extensions(True): + with importlib.util._incompatible_extension_module_restrictions(True): module = module_from_spec(spec) loader.exec_module(module) ''') @@ -734,7 +734,7 @@ def test_incomplete_multi_phase_init_module(self): script = prescript + textwrap.dedent(''' import importlib.util - with importlib.util.allowing_all_extensions(False): + with importlib.util._incompatible_extension_module_restrictions(False): module = module_from_spec(spec) loader.exec_module(module) ''') @@ -748,7 +748,7 @@ def test_incomplete_multi_phase_init_module(self): def test_complete_multi_phase_init_module(self): script = textwrap.dedent(''' import importlib.util - with importlib.util.allowing_all_extensions(True): + with importlib.util._incompatible_extension_module_restrictions(True): import _testmultiphase ''') with self.subTest('check disabled, shared GIL'): @@ -758,7 +758,7 @@ def test_complete_multi_phase_init_module(self): script = textwrap.dedent(f''' import importlib.util - with importlib.util.allowing_all_extensions(False): + with importlib.util._incompatible_extension_module_restrictions(False): import _testmultiphase ''') with self.subTest('check enabled, shared GIL'): From 27296cb096695112c24dd6fbfaf749dc6aeb8bab Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 2 Jun 2023 14:23:48 -0600 Subject: [PATCH 4/7] Add a NEWS entry. --- .../Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst 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 00000000000000..a6cc2d999db2d2 --- /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" argment has change from ``True`` to ``False``, to better +match the new function name. From 01fdb4da32647da0b4e8df63409e481570c6799e Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 2 Jun 2023 15:25:08 -0600 Subject: [PATCH 5/7] Update Misc/NEWS.d/next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst Co-authored-by: Kirill Podoprigora --- .../next/Library/2023-06-02-14-23-41.gh-issue-104310.UamCOB.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index a6cc2d999db2d2..461a3a25fe1b43 100644 --- 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 @@ -3,5 +3,5 @@ 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" argment has change from ``True`` to ``False``, to better +"disable_check" argument has change from ``True`` to ``False``, to better match the new function name. From bec03a22a652bf4168b454b360287e5299f6eba7 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 2 Jun 2023 15:59:54 -0600 Subject: [PATCH 6/7] Get rid of the default argument. --- Lib/importlib/util.py | 8 ++++---- Lib/test/test_importlib/test_util.py | 9 --------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index cc4a10b1b3c330..7d4a26f2ed72e2 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -128,8 +128,8 @@ class _incompatible_extension_module_restrictions: extension module development. If "disable_check" is True then the compatibility check will not - happen while the context manager is active. Otherwise (and by - default) the check *will* happen. + 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 @@ -148,8 +148,8 @@ class _incompatible_extension_module_restrictions: support for mulitple interpreters (or per-interpreter GIL). """ - def __init__(self, disable_check=False): - 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 be7aee61b198f4..9e5a1b1f991100 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -699,15 +699,6 @@ def test_single_phase_init_module(self): with self.assertRaises(ImportError): self.run_with_own_gil(script) - script = textwrap.dedent(f''' - import importlib.util - with importlib.util._incompatible_extension_module_restrictions(): - import _testsinglephase - ''') - with self.subTest('check enabled (default)'): - with self.assertRaises(ImportError): - self.run_with_shared_gil(script) - @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") def test_incomplete_multi_phase_init_module(self): prescript = textwrap.dedent(f''' From 760238e0ac8de8b3895a3eac1f0e3e4d9995c25c Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 8 Jun 2023 11:49:35 -0600 Subject: [PATCH 7/7] Use a keyword-only parameter. --- Lib/importlib/util.py | 2 +- Lib/test/test_importlib/test_util.py | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index 7d4a26f2ed72e2..f4d6e82331516f 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -148,7 +148,7 @@ class _incompatible_extension_module_restrictions: support for mulitple interpreters (or per-interpreter GIL). """ - def __init__(self, disable_check): + def __init__(self, *, disable_check): self.disable_check = bool(disable_check) def __enter__(self): diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 9e5a1b1f991100..e967adc9451c81 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -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._incompatible_extension_module_restrictions(True): + 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._incompatible_extension_module_restrictions(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._incompatible_extension_module_restrictions(True): + 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._incompatible_extension_module_restrictions(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._incompatible_extension_module_restrictions(True): + 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._incompatible_extension_module_restrictions(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'): 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