diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2023-07-27 21:51:34 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-27 21:51:34 (GMT) |
commit | abaf89d908304891c99c6a0450cf7e160c17cdd3 (patch) | |
tree | c05549d0e395f57e1a53eb47689b3e7d4ce0bb58 /Lib/test | |
parent | 5daf19d763826a977a596b6fbc035ee03c0deafc (diff) | |
download | cpython-abaf89d908304891c99c6a0450cf7e160c17cdd3.zip cpython-abaf89d908304891c99c6a0450cf7e160c17cdd3.tar.gz cpython-abaf89d908304891c99c6a0450cf7e160c17cdd3.tar.bz2 |
[3.12] gh-104621: Check for Incompatible Extensions in import_find_extension() (gh-107184) (gh-107360)
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.
(cherry picked from commit 75c974f5353685f338344618ad7344e64c2293d0)
Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
Diffstat (limited to 'Lib/test')
-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 ee9fe4d..cc6e8d4 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", @@ -128,19 +127,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. @@ -1943,6 +1957,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): @@ -2002,6 +2030,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() |