diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2023-07-27 21:08:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-27 21:08:38 (GMT) |
commit | 75c974f5353685f338344618ad7344e64c2293d0 (patch) | |
tree | 60873d069c1b951fe914538626f8b6f4cbfb137b /Lib | |
parent | b72947a8d26915156323ccfd04d273199ecb870c (diff) | |
download | cpython-75c974f5353685f338344618ad7344e64c2293d0.zip cpython-75c974f5353685f338344618ad7344e64c2293d0.tar.gz cpython-75c974f5353685f338344618ad7344e64c2293d0.tar.bz2 |
gh-104621: Check for Incompatible Extensions in import_find_extension() (gh-107184)
This fixes a bug where incompatible modules could still be imported if attempted multiple times.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_capi/check_config.py | 2 | ||||
-rw-r--r-- | Lib/test/test_import/__init__.py | 42 |
2 files changed, 38 insertions, 6 deletions
diff --git a/Lib/test/test_capi/check_config.py b/Lib/test/test_capi/check_config.py index aaedd82..eb99ae1 100644 --- a/Lib/test/test_capi/check_config.py +++ b/Lib/test/test_capi/check_config.py @@ -12,7 +12,7 @@ def import_singlephase(): try: import _testsinglephase except ImportError: - sys.modules.pop('_testsinglephase') + sys.modules.pop('_testsinglephase', None) return False else: del sys.modules['_testsinglephase'] diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index ec8ccf0..7a3fcc2 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -97,7 +97,6 @@ def require_frozen(module, *, skip=True): def require_pure_python(module, *, skip=False): _require_loader(module, SourceFileLoader, skip) - def remove_files(name): for f in (name + ".py", name + ".pyc", @@ -147,19 +146,34 @@ def _ready_to_import(name=None, source=""): del sys.modules[name] -def requires_subinterpreters(meth): - """Decorator to skip a test if subinterpreters are not supported.""" - return unittest.skipIf(_interpreters is None, - 'subinterpreters required')(meth) +if _testsinglephase is not None: + def restore__testsinglephase(*, _orig=_testsinglephase): + # We started with the module imported and want to restore + # it to its nominal state. + _orig._clear_globals() + _testinternalcapi.clear_extension('_testsinglephase', _orig.__file__) + import _testsinglephase def requires_singlephase_init(meth): """Decorator to skip if single-phase init modules are not supported.""" + if not isinstance(meth, type): + def meth(self, _meth=meth): + try: + return _meth(self) + finally: + restore__testsinglephase() meth = cpython_only(meth) return unittest.skipIf(_testsinglephase is None, 'test requires _testsinglephase module')(meth) +def requires_subinterpreters(meth): + """Decorator to skip a test if subinterpreters are not supported.""" + return unittest.skipIf(_interpreters is None, + 'subinterpreters required')(meth) + + class ModuleSnapshot(types.SimpleNamespace): """A representation of a module for testing. @@ -1962,6 +1976,20 @@ class SubinterpImportTests(unittest.TestCase): with self.subTest(f'{module}: strict, fresh'): self.check_compatible_fresh(module, strict=True, isolated=True) + @requires_subinterpreters + @requires_singlephase_init + def test_disallowed_reimport(self): + # See https://github.com/python/cpython/issues/104621. + script = textwrap.dedent(''' + import _testsinglephase + print(_testsinglephase) + ''') + interpid = _interpreters.create() + with self.assertRaises(_interpreters.RunFailedError): + _interpreters.run_string(interpid, script) + with self.assertRaises(_interpreters.RunFailedError): + _interpreters.run_string(interpid, script) + class TestSinglePhaseSnapshot(ModuleSnapshot): @@ -2017,6 +2045,10 @@ class SinglephaseInitTests(unittest.TestCase): # Start fresh. cls.clean_up() + @classmethod + def tearDownClass(cls): + restore__testsinglephase() + def tearDown(self): # Clean up the module. self.clean_up() |