From 4f945a43c6acd92e44cc6abeffbbf295557c8f28 Mon Sep 17 00:00:00 2001 From: Brittany Reynoso Date: Tue, 12 May 2026 13:30:58 -0400 Subject: [PATCH 1/4] Add lazy import tests ported from internal test suite Port missing test coverage from the internal lazy imports test suite, covering behaviors not previously tested in cpython: - Dict operations with lazy values (copy, |, update preserve proxies) - Submodule laziness (unaccessed imports stay lazy until touched) - Attribute side effects (submodule imports don't overwrite parent attrs) - Module/variable name collisions (submodule vs variable ordering) - Deleted module reimport (sys.modules deletion and reimport) - Circular import resolution (lazy imports breaking circular deadlocks) - Dict mutation during module loading (no crash on dict resize) Adds supporting test data modules: metasyntactic package hierarchy, versioned package, module_same_name_var_order packages, and circular_import_pkg. --- Lib/test/test_lazy_import/__init__.py | 218 ++++++++++++++++++ .../data/circular_import_pkg/__init__.py | 1 + .../data/circular_import_pkg/main.py | 2 + .../data/circular_import_pkg/x.py | 7 + .../data/circular_import_pkg/y.py | 7 + .../data/metasyntactic/__init__.py | 1 + .../data/metasyntactic/foo/__init__.py | 1 + .../data/metasyntactic/foo/ack/__init__.py | 1 + .../data/metasyntactic/foo/bar/__init__.py | 1 + .../metasyntactic/foo/bar/baz/__init__.py | 1 + .../metasyntactic/foo/bar/baz/qux/__init__.py | 1 + .../metasyntactic/foo/bar/thud/__init__.py | 1 + .../data/metasyntactic/names.py | 9 + .../data/metasyntactic/plugh/__init__.py | 1 + .../data/metasyntactic/waldo/__init__.py | 1 + .../data/metasyntactic/waldo/fred/__init__.py | 1 + .../module_same_name_var_order1/__init__.py | 3 + .../data/module_same_name_var_order1/bar.py | 1 + .../module_same_name_var_order2/__init__.py | 3 + .../data/module_same_name_var_order2/bar.py | 1 + .../data/versioned/__init__.py | 2 + .../data/versioned/__version__.py | 2 + 22 files changed, 266 insertions(+) create mode 100644 Lib/test/test_lazy_import/data/circular_import_pkg/__init__.py create mode 100644 Lib/test/test_lazy_import/data/circular_import_pkg/main.py create mode 100644 Lib/test/test_lazy_import/data/circular_import_pkg/x.py create mode 100644 Lib/test/test_lazy_import/data/circular_import_pkg/y.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/__init__.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/foo/__init__.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/foo/ack/__init__.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/foo/bar/__init__.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/foo/bar/baz/__init__.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/foo/bar/baz/qux/__init__.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/foo/bar/thud/__init__.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/names.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/plugh/__init__.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/waldo/__init__.py create mode 100644 Lib/test/test_lazy_import/data/metasyntactic/waldo/fred/__init__.py create mode 100644 Lib/test/test_lazy_import/data/module_same_name_var_order1/__init__.py create mode 100644 Lib/test/test_lazy_import/data/module_same_name_var_order1/bar.py create mode 100644 Lib/test/test_lazy_import/data/module_same_name_var_order2/__init__.py create mode 100644 Lib/test/test_lazy_import/data/module_same_name_var_order2/bar.py create mode 100644 Lib/test/test_lazy_import/data/versioned/__init__.py create mode 100644 Lib/test/test_lazy_import/data/versioned/__version__.py diff --git a/Lib/test/test_lazy_import/__init__.py b/Lib/test/test_lazy_import/__init__.py index 1d1d2e00bd733f..cffe42760ec447 100644 --- a/Lib/test/test_lazy_import/__init__.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -2018,5 +2018,223 @@ def test_set_bad_filter(self): self.assertRaises(ValueError, _testcapi.PyImport_SetLazyImportsFilter, 42) + +class DictOperationsWithLazyTests(unittest.TestCase): + """Tests for dict operations with lazy import values.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_lazy_import.data'): + del sys.modules[key] + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_dict_copy_preserves_lazy(self): + """dict.copy() should preserve lazy import proxy objects.""" + sys.set_lazy_imports("all") + from test.test_lazy_import.data.metasyntactic import names + d = names.__dict__.copy() + self.assertIsInstance(d["Foo"], types.LazyImportType) + self.assertEqual(d["Metasyntactic"], "Metasyntactic") + + def test_dict_or_preserves_lazy(self): + """dict | should keep the winning side's lazy/resolved status.""" + sys.set_lazy_imports("all") + from test.test_lazy_import.data.metasyntactic import names + lazy = names.__dict__.copy() + resolved = {"Foo": "resolved"} + self.assertEqual((lazy | resolved)["Foo"], "resolved") + self.assertIsInstance((resolved | lazy)["Foo"], types.LazyImportType) + + def test_dict_update_preserves_lazy(self): + """dict.update() should transfer lazy import proxy objects.""" + sys.set_lazy_imports("all") + from test.test_lazy_import.data.metasyntactic import names + target = {} + target.update(names.__dict__) + self.assertIsInstance(target["Foo"], types.LazyImportType) + + +class SubmoduleLazinessTests(unittest.TestCase): + """Tests that module-level lazy imports remain lazy until accessed.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_lazy_import.data'): + del sys.modules[key] + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_unaccessed_imports_stay_lazy(self): + """Imports in 'all' mode should stay lazy until accessed.""" + sys.set_lazy_imports("all") + from test.test_lazy_import.data.metasyntactic import names + self.assertIsInstance(names.__dict__["Foo"], types.LazyImportType) + self.assertNotIn( + "test.test_lazy_import.data.metasyntactic.foo", sys.modules + ) + _ = names.Foo + self.assertEqual(names.Foo, "Foo") + self.assertIn( + "test.test_lazy_import.data.metasyntactic.foo", sys.modules + ) + self.assertIsInstance(names.__dict__["Ack"], types.LazyImportType) + self.assertNotIn( + "test.test_lazy_import.data.metasyntactic.foo.ack", sys.modules + ) + + +class AttributeSideEffectTests(unittest.TestCase): + """Tests that submodule imports don't overwrite parent attributes.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_lazy_import.data'): + del sys.modules[key] + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_version_submodule_does_not_overwrite(self): + """A __version__ submodule should not overwrite the parent's + __version__ attribute imported in __init__.py.""" + import test.test_lazy_import.data.versioned as versioned + self.assertEqual(versioned.__version__, "1.0") + self.assertEqual( + versioned.__copyright__, + "Copyright (c) 2001-2022 Python Software Foundation.", + ) + + +class ModuleVariableNameCollisionTests(unittest.TestCase): + """Tests for name collision between a submodule and a variable.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_lazy_import.data'): + del sys.modules[key] + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_variable_after_import_wins(self): + """Variable assigned after import should overwrite the submodule.""" + from test.test_lazy_import.data import module_same_name_var_order1 + self.assertEqual(module_same_name_var_order1.bar, "Blah") + + def test_import_after_variable_wins(self): + """Import after variable assignment should overwrite the variable.""" + from test.test_lazy_import.data import module_same_name_var_order2 + bar_mod = sys.modules[ + "test.test_lazy_import.data.module_same_name_var_order2.bar" + ] + self.assertIs(module_same_name_var_order2.bar, bar_mod) + + +class DeletedModuleReimportTests(unittest.TestCase): + """Tests for reimporting after module deletion from sys.modules.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_lazy_import.data'): + del sys.modules[key] + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_reimport_creates_new_module(self): + """Deleting and reimporting should create a new module object.""" + import test.test_lazy_import.data.metasyntactic.foo + import test.test_lazy_import.data.metasyntactic.foo.bar.baz + + first_bar = test.test_lazy_import.data.metasyntactic.foo.bar + + del sys.modules[ + "test.test_lazy_import.data.metasyntactic.foo.bar" + ] + + import test.test_lazy_import.data.metasyntactic.foo.bar.thud + + second_bar = test.test_lazy_import.data.metasyntactic.foo.bar + + self.assertIsNot(first_bar, second_bar) + self.assertIn("baz", dir(first_bar)) + self.assertNotIn("thud", dir(first_bar)) + self.assertIn("thud", dir(second_bar)) + self.assertNotIn("baz", dir(second_bar)) + + +@support.requires_subprocess() +class CircularImportLazyTests(unittest.TestCase): + """Tests that lazy imports can break circular import patterns.""" + + def test_succeeds_with_lazy(self): + """Same-level circular imports should succeed with lazy mode.""" + proc = assert_python_ok( + "-X", "lazy_imports=all", "-c", + "import test.test_lazy_import.data.circular_import_pkg.main;" + "print('OK')", + ) + self.assertIn(b"OK", proc.out) + + def test_fails_without_lazy(self): + """Same-level circular imports should fail without lazy mode.""" + result = subprocess.run( + [sys.executable, "-X", "lazy_imports=none", "-c", + "import test.test_lazy_import.data.circular_import_pkg.main"], + capture_output=True, text=True, + ) + self.assertNotEqual(result.returncode, 0) + self.assertIn("ImportError", result.stderr) + + +@support.requires_subprocess() +class DictMutationDuringLoadTests(unittest.TestCase): + """Tests that module dict mutation during loading doesn't crash.""" + + def test_dict_mutation_during_import(self): + """Iterating a module dict while lazy imports resolve should not + crash even if the dict is mutated during iteration.""" + with tempfile.TemporaryDirectory() as tmpdir: + pkg = os.path.join(tmpdir, "dcwl_pkg") + os.makedirs(pkg) + + with open(os.path.join(pkg, "__init__.py"), "w") as f: + f.write(textwrap.dedent("""\ + from .elements import elements_function + + def __go(lcls): + global __all__ + __all__ = sorted( + name + for name, obj in lcls.items() + if not name.startswith("_") + ) + + __go(locals()) + """)) + + with open(os.path.join(pkg, "elements.py"), "w") as f: + f.write(textwrap.dedent("""\ + from .elements_sub import elements_sub_function + + def elements_function(): + pass + """)) + + with open(os.path.join(pkg, "elements_sub.py"), "w") as f: + f.write("def elements_sub_function(): pass\n") + + env = os.environ.copy() + env["PYTHONPATH"] = tmpdir + result = subprocess.run( + [sys.executable, "-X", "lazy_imports=all", + "-c", "import dcwl_pkg; print('OK')"], + capture_output=True, text=True, env=env, + ) + self.assertEqual( + result.returncode, 0, + f"stdout: {result.stdout}, stderr: {result.stderr}", + ) + self.assertIn("OK", result.stdout) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_lazy_import/data/circular_import_pkg/__init__.py b/Lib/test/test_lazy_import/data/circular_import_pkg/__init__.py new file mode 100644 index 00000000000000..8b137891791fe9 --- /dev/null +++ b/Lib/test/test_lazy_import/data/circular_import_pkg/__init__.py @@ -0,0 +1 @@ + diff --git a/Lib/test/test_lazy_import/data/circular_import_pkg/main.py b/Lib/test/test_lazy_import/data/circular_import_pkg/main.py new file mode 100644 index 00000000000000..0b897b377e28a6 --- /dev/null +++ b/Lib/test/test_lazy_import/data/circular_import_pkg/main.py @@ -0,0 +1,2 @@ +from .x import X2 +X2() diff --git a/Lib/test/test_lazy_import/data/circular_import_pkg/x.py b/Lib/test/test_lazy_import/data/circular_import_pkg/x.py new file mode 100644 index 00000000000000..b44d5185c9e70f --- /dev/null +++ b/Lib/test/test_lazy_import/data/circular_import_pkg/x.py @@ -0,0 +1,7 @@ +def X1(): + return "X" + +from .y import Y1 + +def X2(): + return Y1() diff --git a/Lib/test/test_lazy_import/data/circular_import_pkg/y.py b/Lib/test/test_lazy_import/data/circular_import_pkg/y.py new file mode 100644 index 00000000000000..d2385f7e67c01f --- /dev/null +++ b/Lib/test/test_lazy_import/data/circular_import_pkg/y.py @@ -0,0 +1,7 @@ +def Y1(): + return "Y" + +from .x import X2 + +def Y2(): + return X2() diff --git a/Lib/test/test_lazy_import/data/metasyntactic/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/__init__.py new file mode 100644 index 00000000000000..8b137891791fe9 --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/__init__.py @@ -0,0 +1 @@ + diff --git a/Lib/test/test_lazy_import/data/metasyntactic/foo/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/foo/__init__.py new file mode 100644 index 00000000000000..632a9fb87ac0fd --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/foo/__init__.py @@ -0,0 +1 @@ +Foo = "Foo" diff --git a/Lib/test/test_lazy_import/data/metasyntactic/foo/ack/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/foo/ack/__init__.py new file mode 100644 index 00000000000000..c4c249f3b65153 --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/foo/ack/__init__.py @@ -0,0 +1 @@ +Ack = "Ack" diff --git a/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/__init__.py new file mode 100644 index 00000000000000..03faa550258f97 --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/__init__.py @@ -0,0 +1 @@ +Bar = "Bar" diff --git a/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/baz/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/baz/__init__.py new file mode 100644 index 00000000000000..62d8366b4404d6 --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/baz/__init__.py @@ -0,0 +1 @@ +Baz = "Baz" diff --git a/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/baz/qux/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/baz/qux/__init__.py new file mode 100644 index 00000000000000..12389d76a28539 --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/baz/qux/__init__.py @@ -0,0 +1 @@ +Qux = "Qux" diff --git a/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/thud/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/thud/__init__.py new file mode 100644 index 00000000000000..a4dd8ab0fae17e --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/foo/bar/thud/__init__.py @@ -0,0 +1 @@ +Thud = "Thud" diff --git a/Lib/test/test_lazy_import/data/metasyntactic/names.py b/Lib/test/test_lazy_import/data/metasyntactic/names.py new file mode 100644 index 00000000000000..b2edf13e850389 --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/names.py @@ -0,0 +1,9 @@ +from .foo import Foo +from .foo.ack import Ack +from .foo.bar import Bar +from .foo.bar.baz import Baz +from .foo.bar.thud import Thud +from .waldo import Waldo +from .waldo.fred import Fred +from .plugh import Plugh +Metasyntactic = "Metasyntactic" diff --git a/Lib/test/test_lazy_import/data/metasyntactic/plugh/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/plugh/__init__.py new file mode 100644 index 00000000000000..5db053204fc17c --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/plugh/__init__.py @@ -0,0 +1 @@ +Plugh = "Plugh" diff --git a/Lib/test/test_lazy_import/data/metasyntactic/waldo/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/waldo/__init__.py new file mode 100644 index 00000000000000..39f5a1b1838573 --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/waldo/__init__.py @@ -0,0 +1 @@ +Waldo = "Waldo" diff --git a/Lib/test/test_lazy_import/data/metasyntactic/waldo/fred/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/waldo/fred/__init__.py new file mode 100644 index 00000000000000..8c9dce1b3cfb9d --- /dev/null +++ b/Lib/test/test_lazy_import/data/metasyntactic/waldo/fred/__init__.py @@ -0,0 +1 @@ +Fred = "Fred" diff --git a/Lib/test/test_lazy_import/data/module_same_name_var_order1/__init__.py b/Lib/test/test_lazy_import/data/module_same_name_var_order1/__init__.py new file mode 100644 index 00000000000000..b815b2a7d6fedf --- /dev/null +++ b/Lib/test/test_lazy_import/data/module_same_name_var_order1/__init__.py @@ -0,0 +1,3 @@ +from .bar import Bar +bar = "Blah" +Bar diff --git a/Lib/test/test_lazy_import/data/module_same_name_var_order1/bar.py b/Lib/test/test_lazy_import/data/module_same_name_var_order1/bar.py new file mode 100644 index 00000000000000..03faa550258f97 --- /dev/null +++ b/Lib/test/test_lazy_import/data/module_same_name_var_order1/bar.py @@ -0,0 +1 @@ +Bar = "Bar" diff --git a/Lib/test/test_lazy_import/data/module_same_name_var_order2/__init__.py b/Lib/test/test_lazy_import/data/module_same_name_var_order2/__init__.py new file mode 100644 index 00000000000000..008d199c73e534 --- /dev/null +++ b/Lib/test/test_lazy_import/data/module_same_name_var_order2/__init__.py @@ -0,0 +1,3 @@ +bar = "Blah" +from .bar import Bar +Bar diff --git a/Lib/test/test_lazy_import/data/module_same_name_var_order2/bar.py b/Lib/test/test_lazy_import/data/module_same_name_var_order2/bar.py new file mode 100644 index 00000000000000..03faa550258f97 --- /dev/null +++ b/Lib/test/test_lazy_import/data/module_same_name_var_order2/bar.py @@ -0,0 +1 @@ +Bar = "Bar" diff --git a/Lib/test/test_lazy_import/data/versioned/__init__.py b/Lib/test/test_lazy_import/data/versioned/__init__.py new file mode 100644 index 00000000000000..be5bb3f8e60718 --- /dev/null +++ b/Lib/test/test_lazy_import/data/versioned/__init__.py @@ -0,0 +1,2 @@ +from .__version__ import __version__ +from .__version__ import __copyright__ diff --git a/Lib/test/test_lazy_import/data/versioned/__version__.py b/Lib/test/test_lazy_import/data/versioned/__version__.py new file mode 100644 index 00000000000000..37a104387354e2 --- /dev/null +++ b/Lib/test/test_lazy_import/data/versioned/__version__.py @@ -0,0 +1,2 @@ +__version__ = "1.0" +__copyright__ = "Copyright (c) 2001-2022 Python Software Foundation." From 9aeb85b556531abc113374e652bdb66f85e1cf45 Mon Sep 17 00:00:00 2001 From: Brittany Reynoso Date: Thu, 28 May 2026 11:56:28 -0700 Subject: [PATCH 2/4] Fix CI failures: lint, invalid -X flag, and missing Makefile TESTSUBDIRS - Remove trailing newlines from empty __init__.py files to satisfy pre-commit hooks - Fix test_fails_without_lazy to not pass invalid -X lazy_imports=none flag - Add 14 new test data directories to TESTSUBDIRS in Makefile.pre.in Co-Authored-By: Claude Opus 4.6 (1M context) --- Lib/test/test_lazy_import/__init__.py | 2 +- .../data/circular_import_pkg/__init__.py | 1 - .../data/metasyntactic/__init__.py | 1 - Makefile.pre.in | 14 ++++++++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_lazy_import/__init__.py b/Lib/test/test_lazy_import/__init__.py index 34079d2802098c..1ad03e8f396486 100644 --- a/Lib/test/test_lazy_import/__init__.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -2268,7 +2268,7 @@ def test_succeeds_with_lazy(self): def test_fails_without_lazy(self): """Same-level circular imports should fail without lazy mode.""" result = subprocess.run( - [sys.executable, "-X", "lazy_imports=none", "-c", + [sys.executable, "-c", "import test.test_lazy_import.data.circular_import_pkg.main"], capture_output=True, text=True, ) diff --git a/Lib/test/test_lazy_import/data/circular_import_pkg/__init__.py b/Lib/test/test_lazy_import/data/circular_import_pkg/__init__.py index 8b137891791fe9..e69de29bb2d1d6 100644 --- a/Lib/test/test_lazy_import/data/circular_import_pkg/__init__.py +++ b/Lib/test/test_lazy_import/data/circular_import_pkg/__init__.py @@ -1 +0,0 @@ - diff --git a/Lib/test/test_lazy_import/data/metasyntactic/__init__.py b/Lib/test/test_lazy_import/data/metasyntactic/__init__.py index 8b137891791fe9..e69de29bb2d1d6 100644 --- a/Lib/test/test_lazy_import/data/metasyntactic/__init__.py +++ b/Lib/test/test_lazy_import/data/metasyntactic/__init__.py @@ -1 +0,0 @@ - diff --git a/Makefile.pre.in b/Makefile.pre.in index 9435bf534fb512..5b3bccd786101d 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2671,6 +2671,20 @@ TESTSUBDIRS= idlelib/idle_test \ test/test_lazy_import/data \ test/test_lazy_import/data/pkg \ test/test_lazy_import/data/badsyntax \ + test/test_lazy_import/data/circular_import_pkg \ + test/test_lazy_import/data/metasyntactic \ + test/test_lazy_import/data/metasyntactic/foo \ + test/test_lazy_import/data/metasyntactic/foo/ack \ + test/test_lazy_import/data/metasyntactic/foo/bar \ + test/test_lazy_import/data/metasyntactic/foo/bar/baz \ + test/test_lazy_import/data/metasyntactic/foo/bar/baz/qux \ + test/test_lazy_import/data/metasyntactic/foo/bar/thud \ + test/test_lazy_import/data/metasyntactic/plugh \ + test/test_lazy_import/data/metasyntactic/waldo \ + test/test_lazy_import/data/metasyntactic/waldo/fred \ + test/test_lazy_import/data/module_same_name_var_order1 \ + test/test_lazy_import/data/module_same_name_var_order2 \ + test/test_lazy_import/data/versioned \ test/test_module \ test/test_multiprocessing_fork \ test/test_multiprocessing_forkserver \ From 84ae8b54c014a029ed8c606c2b39447c12ad4846 Mon Sep 17 00:00:00 2001 From: Brittany Reynoso Date: Fri, 29 May 2026 08:32:47 -0700 Subject: [PATCH 3/4] Remove two test suites that were specifically testing a no longer relevant implementation detail from pep690 --- Lib/test/test_lazy_import/__init__.py | 88 --------------------------- 1 file changed, 88 deletions(-) diff --git a/Lib/test/test_lazy_import/__init__.py b/Lib/test/test_lazy_import/__init__.py index 1ad03e8f396486..76fc312e5ed3c6 100644 --- a/Lib/test/test_lazy_import/__init__.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -2109,43 +2109,6 @@ def test_set_bad_filter(self): self.assertRaises(ValueError, _testcapi.PyImport_SetLazyImportsFilter, 42) - -class DictOperationsWithLazyTests(unittest.TestCase): - """Tests for dict operations with lazy import values.""" - - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - - def test_dict_copy_preserves_lazy(self): - """dict.copy() should preserve lazy import proxy objects.""" - sys.set_lazy_imports("all") - from test.test_lazy_import.data.metasyntactic import names - d = names.__dict__.copy() - self.assertIsInstance(d["Foo"], types.LazyImportType) - self.assertEqual(d["Metasyntactic"], "Metasyntactic") - - def test_dict_or_preserves_lazy(self): - """dict | should keep the winning side's lazy/resolved status.""" - sys.set_lazy_imports("all") - from test.test_lazy_import.data.metasyntactic import names - lazy = names.__dict__.copy() - resolved = {"Foo": "resolved"} - self.assertEqual((lazy | resolved)["Foo"], "resolved") - self.assertIsInstance((resolved | lazy)["Foo"], types.LazyImportType) - - def test_dict_update_preserves_lazy(self): - """dict.update() should transfer lazy import proxy objects.""" - sys.set_lazy_imports("all") - from test.test_lazy_import.data.metasyntactic import names - target = {} - target.update(names.__dict__) - self.assertIsInstance(target["Foo"], types.LazyImportType) - - class SubmoduleLazinessTests(unittest.TestCase): """Tests that module-level lazy imports remain lazy until accessed.""" @@ -2276,56 +2239,5 @@ def test_fails_without_lazy(self): self.assertIn("ImportError", result.stderr) -@support.requires_subprocess() -class DictMutationDuringLoadTests(unittest.TestCase): - """Tests that module dict mutation during loading doesn't crash.""" - - def test_dict_mutation_during_import(self): - """Iterating a module dict while lazy imports resolve should not - crash even if the dict is mutated during iteration.""" - with tempfile.TemporaryDirectory() as tmpdir: - pkg = os.path.join(tmpdir, "dcwl_pkg") - os.makedirs(pkg) - - with open(os.path.join(pkg, "__init__.py"), "w") as f: - f.write(textwrap.dedent("""\ - from .elements import elements_function - - def __go(lcls): - global __all__ - __all__ = sorted( - name - for name, obj in lcls.items() - if not name.startswith("_") - ) - - __go(locals()) - """)) - - with open(os.path.join(pkg, "elements.py"), "w") as f: - f.write(textwrap.dedent("""\ - from .elements_sub import elements_sub_function - - def elements_function(): - pass - """)) - - with open(os.path.join(pkg, "elements_sub.py"), "w") as f: - f.write("def elements_sub_function(): pass\n") - - env = os.environ.copy() - env["PYTHONPATH"] = tmpdir - result = subprocess.run( - [sys.executable, "-X", "lazy_imports=all", - "-c", "import dcwl_pkg; print('OK')"], - capture_output=True, text=True, env=env, - ) - self.assertEqual( - result.returncode, 0, - f"stdout: {result.stdout}, stderr: {result.stderr}", - ) - self.assertIn("OK", result.stdout) - - if __name__ == '__main__': unittest.main() From 99e8c60c9ce108c91186ac4f253cd1cef7bcc198 Mon Sep 17 00:00:00 2001 From: Brittany Reynoso Date: Fri, 29 May 2026 11:28:53 -0700 Subject: [PATCH 4/4] Trigger CI