https://github.com/python/cpython/commit/39ee468e092eed659bfc2a4e0ce02572e0d81de0 commit: 39ee468e092eed659bfc2a4e0ce02572e0d81de0 branch: main author: Jelle Zijlstra <jelle.zijls...@gmail.com> committer: JelleZijlstra <jelle.zijls...@gmail.com> date: 2025-04-17T03:46:36Z summary:
gh-118761: Add helper to ensure that lazy imports are actually lazy (#132614) This ensures that if we jump through some hoops to make sure something is imported lazily, we don't regress on importing it. I recently already accidentally made typing import warnings and annotationlib eagerly. Co-authored-by: Adam Turner <9087854+aa-tur...@users.noreply.github.com> files: M Lib/test/support/import_helper.py M Lib/test/test_annotationlib.py M Lib/test/test_typing.py diff --git a/Lib/test/support/import_helper.py b/Lib/test/support/import_helper.py index 2b91bdcf9cd859..42cfe9cfa8cb72 100644 --- a/Lib/test/support/import_helper.py +++ b/Lib/test/support/import_helper.py @@ -5,6 +5,7 @@ import os import shutil import sys +import textwrap import unittest import warnings @@ -309,3 +310,25 @@ def ready_to_import(name=None, source=""): sys.modules[name] = old_module else: sys.modules.pop(name, None) + + +def ensure_lazy_imports(imported_module, modules_to_block): + """Test that when imported_module is imported, none of the modules in + modules_to_block are imported as a side effect.""" + modules_to_block = frozenset(modules_to_block) + script = textwrap.dedent( + f""" + import sys + modules_to_block = {modules_to_block} + if unexpected := modules_to_block & sys.modules.keys(): + startup = ", ".join(unexpected) + raise AssertionError(f'unexpectedly imported at startup: {{startup}}') + + import {imported_module} + if unexpected := modules_to_block & sys.modules.keys(): + after = ", ".join(unexpected) + raise AssertionError(f'unexpectedly imported after importing {imported_module}: {{after}}') + """ + ) + from .script_helper import assert_python_ok + assert_python_ok("-S", "-c", script) diff --git a/Lib/test/test_annotationlib.py b/Lib/test/test_annotationlib.py index 6f097c07295f3b..0890be529a7e52 100644 --- a/Lib/test/test_annotationlib.py +++ b/Lib/test/test_annotationlib.py @@ -24,6 +24,7 @@ ) from test import support +from test.support import import_helper from test.test_inspect import inspect_stock_annotations from test.test_inspect import inspect_stringized_annotations from test.test_inspect import inspect_stringized_annotations_2 @@ -1367,3 +1368,9 @@ def test_multiple_ways_to_create(self): class TestAnnotationLib(unittest.TestCase): def test__all__(self): support.check__all__(self, annotationlib) + + def test_lazy_imports(self): + import_helper.ensure_lazy_imports("annotationlib", { + "typing", + "warnings", + }) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 32f12a3f8b22f1..81474a81be645d 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -6317,6 +6317,15 @@ def test_collect_parameters(self): typing._collect_parameters self.assertEqual(cm.filename, __file__) + def test_lazy_import(self): + import_helper.ensure_lazy_imports("typing", { + "warnings", + "inspect", + "re", + "contextlib", + # "annotationlib", # TODO + }) + @lru_cache() def cached_func(x, y): _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com