From be559ae4530f85c9101f166fd702646353f7f064 Mon Sep 17 00:00:00 2001 From: Shahar Naveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Wed, 17 Dec 2025 00:15:25 +0100 Subject: [PATCH] Update `support/import_helper.py` from 3.13.11 (#6451) * Update `support/import_helper.py` from 3.13.11 * Unmark passing test --- Lib/test/support/import_helper.py | 43 ++++++++++++++++++++++++++++--- Lib/test/test_super.py | 1 - 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/Lib/test/support/import_helper.py b/Lib/test/support/import_helper.py index 67f18e530..2b91bdcf9 100644 --- a/Lib/test/support/import_helper.py +++ b/Lib/test/support/import_helper.py @@ -8,7 +8,7 @@ import sys import unittest import warnings -from .os_helper import unlink +from .os_helper import unlink, temp_dir @contextlib.contextmanager @@ -58,8 +58,8 @@ def make_legacy_pyc(source): :return: The file system path to the legacy pyc file. """ pyc_file = importlib.util.cache_from_source(source) - up_one = os.path.dirname(os.path.abspath(source)) - legacy_pyc = os.path.join(up_one, source + 'c') + assert source.endswith('.py') + legacy_pyc = source + 'c' shutil.move(pyc_file, legacy_pyc) return legacy_pyc @@ -114,7 +114,7 @@ def multi_interp_extensions_check(enabled=True): This only applies to modules that haven't been imported yet. It overrides the PyInterpreterConfig.check_multi_interp_extensions setting (see support.run_in_subinterp_with_config() and - _xxsubinterpreters.create()). + _interpreters.create()). Also see importlib.utils.allowing_all_extensions(). """ @@ -268,9 +268,44 @@ def modules_cleanup(oldmodules): sys.modules.update(oldmodules) +@contextlib.contextmanager +def isolated_modules(): + """ + Save modules on entry and cleanup on exit. + """ + (saved,) = modules_setup() + try: + yield + finally: + modules_cleanup(saved) + + def mock_register_at_fork(func): # bpo-30599: Mock os.register_at_fork() when importing the random module, # since this function doesn't allow to unregister callbacks and would leak # memory. from unittest import mock return mock.patch('os.register_at_fork', create=True)(func) + + +@contextlib.contextmanager +def ready_to_import(name=None, source=""): + from test.support import script_helper + + # 1. Sets up a temporary directory and removes it afterwards + # 2. Creates the module file + # 3. Temporarily clears the module from sys.modules (if any) + # 4. Reverts or removes the module when cleaning up + name = name or "spam" + with temp_dir() as tempdir: + path = script_helper.make_script(tempdir, name, source) + old_module = sys.modules.pop(name, None) + try: + sys.path.insert(0, tempdir) + yield name, path + sys.path.remove(tempdir) + finally: + if old_module is not None: + sys.modules[name] = old_module + else: + sys.modules.pop(name, None) diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index 8967dab8b..76eda799d 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -349,7 +349,6 @@ class TestSuper(unittest.TestCase): with self.assertRaisesRegex(TypeError, "argument 1 must be a type"): super(1, int) - @unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: module 'test.support.import_helper' has no attribute 'ready_to_import' def test_shadowed_global(self): source = textwrap.dedent( """