]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-149321: Fix stdlib imports with lazy imports disabled (#149338)
authorPablo Galindo Salgado <Pablogsal@gmail.com>
Mon, 4 May 2026 18:03:21 +0000 (19:03 +0100)
committerGitHub <noreply@github.com>
Mon, 4 May 2026 18:03:21 +0000 (19:03 +0100)
Lib/ast.py
Lib/dataclasses.py
Lib/test/test_lazy_import/__init__.py
Misc/NEWS.d/next/Library/2026-05-03-12-00-00.gh-issue-149321.fUaxrz.rst [new file with mode: 0644]

index ba4ee0197b85d2639c9470a259c4b33ecff577b1..a7997c4b7406355d9abcff5bb39fe06edd078015 100644 (file)
@@ -21,7 +21,6 @@ that work tightly with the python syntax (template engines for example).
 :license: Python License.
 """
 from _ast import *
-lazy from _colorize import can_colorize, get_theme
 
 
 def parse(source, filename='<unknown>', mode='exec', *,
@@ -142,6 +141,8 @@ def dump(
     If show_empty is False, then empty lists and fields that are None
     will be omitted from the output for better readability.
     """
+    from _colorize import get_theme
+
     t = get_theme(force_color=color, force_no_color=not color).ast
 
     def _format(node, level=0):
@@ -708,6 +709,7 @@ def main(args=None):
 
     tree = parse(source, name, args.mode, type_comments=args.no_type_comments,
                  feature_version=feature_version, optimize=args.optimize)
+    from _colorize import can_colorize
     print(dump(tree, include_attributes=args.include_attributes,
                color=can_colorize(file=sys.stdout),
                indent=args.indent, show_empty=args.show_empty))
index d67cc4dd1b19ab5dd38d42f86c27ca6d51eff15c..dbfabded2e47aa2b8b10225fdf15fa919eee4e71 100644 (file)
@@ -6,7 +6,6 @@ import annotationlib
 import abc
 from reprlib import recursive_repr
 lazy import copy
-lazy import inspect
 lazy import re
 
 
@@ -981,6 +980,7 @@ class _AutoDocstring:
         try:
             # In some cases fetching a signature is not possible.
             # But, we surely should not fail in this case.
+            import inspect
             text_sig = str(inspect.signature(
                  cls,
                  annotation_format=annotationlib.Format.FORWARDREF,
@@ -1391,6 +1391,7 @@ def _add_slots(cls, is_frozen, weakref_slot, defined_fields):
 
         # If this is a wrapped function, unwrap it.
         if not isinstance(member, type) and hasattr(member, '__wrapped__'):
+            import inspect
             member = inspect.unwrap(member)
 
         if isinstance(member, types.FunctionType):
index a9a8cd143e0d7562d86eb0b027c6f94de2f65cac..1d1d2e00bd733f47014cf07c06925b8323f84491 100644 (file)
@@ -1034,6 +1034,50 @@ class CommandLineAndEnvVarTests(unittest.TestCase):
         self.assertEqual(result.returncode, 0, f"stderr: {result.stderr}")
         self.assertIn("EAGER", result.stdout)
 
+    @support.requires_resource("cpu")
+    def test_cli_lazy_imports_modes_import_stdlib_modules(self):
+        """-X lazy_imports modes should import available stdlib modules."""
+        # Do not smoke-test modules with intentional import-time effects.
+        import_side_effect_modules = {"antigravity", "this"}
+        importable = []
+
+        for module in sorted(sys.stdlib_module_names):
+            if module in import_side_effect_modules:
+                continue
+
+            with self.subTest(module=module):
+                code = f"import {module}; print({module})"
+                baseline = subprocess.run(
+                    [sys.executable, "-I", "-c", code],
+                    capture_output=True,
+                    text=True,
+                    timeout=60,
+                )
+                if baseline.returncode:
+                    # sys.stdlib_module_names includes modules for other
+                    # platforms and optional extension modules not built here.
+                    continue
+                importable.append(module)
+
+                for mode in ("normal", "none"):
+                    with self.subTest(module=module, mode=mode):
+                        result = subprocess.run(
+                            [
+                                sys.executable,
+                                "-I",
+                                "-X",
+                                f"lazy_imports={mode}",
+                                "-c",
+                                code,
+                            ],
+                            capture_output=True,
+                            text=True,
+                            timeout=60,
+                        )
+                        self.assertEqual(result.returncode, 0, result.stderr)
+
+        self.assertGreater(len(importable), 100)
+
     def test_cli_lazy_imports_normal_respects_lazy_keyword_only(self):
         """-X lazy_imports=normal should respect lazy keyword only."""
         # Note: Use test modules instead of stdlib modules to avoid
diff --git a/Misc/NEWS.d/next/Library/2026-05-03-12-00-00.gh-issue-149321.fUaxrz.rst b/Misc/NEWS.d/next/Library/2026-05-03-12-00-00.gh-issue-149321.fUaxrz.rst
new file mode 100644 (file)
index 0000000..8fd4bf6
--- /dev/null
@@ -0,0 +1,2 @@
+Fix import cycles exposed by running standard library modules with
+``-X lazy_imports=none``.