gh-144957: Add test for lazy imports with __getattr__#145330
Open
gourijain029-del wants to merge 2 commits intopython:mainfrom
Open
gh-144957: Add test for lazy imports with __getattr__#145330gourijain029-del wants to merge 2 commits intopython:mainfrom
gourijain029-del wants to merge 2 commits intopython:mainfrom
Conversation
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Adds regression test to verify lazy imports work correctly with modules that use __getattr__ for dynamic attributes (e.g. typing.Match). The issue appears to be already fixed in current main branch.
Member
Your test doesn't pass locally for me: ❯ ./python.exe -m unittest Lib.test.test_import.test_lazy_imports
....................................................F............BAR_MODULE_LOADED
...........................
======================================================================
FAIL: test_lazy_import_with_getattr (Lib.test.test_import.test_lazy_imports.LazyImportTests.test_lazy_import_with_getattr)
Lazy imports work with module __getattr__ (gh-144957).
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/bartosz.slawecki/Python/cpython/Lib/test/test_import/test_lazy_imports.py", line 101, in test_lazy_import_with_getattr
self.assertEqual(result.returncode, 0, result.stderr)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0 : Traceback (most recent call last):
File "<string>", line 4, in <module>
ImportError: deferred import of 'typing.Match' raised an exception during resolution
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<string>", line 5, in <module>
print(Match)
^^^^^
ImportError: cannot import name 'Match' from 'typing' (/Users/bartosz.slawecki/Python/cpython/Lib/typing.py)Presumably there's something with CI, needs investigation. |
122ad9f to
3e63300
Compare
When resolving lazy imports, check if a lazy import object was found and the module has __getattr__. If so, try calling __getattr__ first before using the lazy import object.
johnslavik
reviewed
Feb 27, 2026
Comment on lines
+90
to
+103
| code = textwrap.dedent(""" | ||
| import sys | ||
| sys.set_lazy_imports("normal") | ||
| lazy from test.test_import.data.lazy_imports.module_with_getattr import dynamic_attr | ||
| assert dynamic_attr == "from_getattr" | ||
| print("OK") | ||
| """) | ||
| result = subprocess.run( | ||
| [sys.executable, "-c", code], | ||
| capture_output=True, | ||
| text=True | ||
| ) | ||
| self.assertEqual(result.returncode, 0, result.stderr) | ||
| self.assertIn("OK", result.stdout) |
Member
There was a problem hiding this comment.
Less prone to false positives:
Suggested change
| code = textwrap.dedent(""" | |
| import sys | |
| sys.set_lazy_imports("normal") | |
| lazy from test.test_import.data.lazy_imports.module_with_getattr import dynamic_attr | |
| assert dynamic_attr == "from_getattr" | |
| print("OK") | |
| """) | |
| result = subprocess.run( | |
| [sys.executable, "-c", code], | |
| capture_output=True, | |
| text=True | |
| ) | |
| self.assertEqual(result.returncode, 0, result.stderr) | |
| self.assertIn("OK", result.stdout) | |
| code = textwrap.dedent(""" | |
| import sys | |
| sys.set_lazy_imports("normal") | |
| lazy from test.test_import.data.lazy_imports.module_with_getattr import dynamic_attr | |
| print(repr(dynamic_attr)) | |
| """) | |
| result = subprocess.run( | |
| [sys.executable, "-c", code], | |
| capture_output=True, | |
| text=True | |
| ) | |
| self.assertEqual(result.returncode, 0, result.stderr) | |
| self.assertIn("'from_getattr'", result.stdout) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a regression test for lazy imports working with modules that use
__getattr__.The issue reported that
lazy from typing import Matchwould fail sinceMatchis provided bytyping.__getattr__rather than being in the module dict. Testing shows this works correctly in current main - the existing code inregister_lazy_on_parent()already checks for__getattr__and skips adding lazy import objects to those modules.This test documents the expected behavior and prevents future regressions.
__getattr__when reifying #144957