LazyImportType.resolve() does not replace the module global and can import twice
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
Bug report
Bug description:
Calling resolve() on a lazy import proxy forces the import and returns the resolved object, but it does not replace the original lazy object in the module globals. A later normal global access reifies the same lazy object again.
import builtins
import types
real_import = builtins.__import__
calls = []
lazy import target_module as target
def custom_import(name, globals=None, locals=None, fromlist=None, level=0):
if name == "target_module":
index = len(calls) + 1
calls.append((index, name, globals.get("__name__"), fromlist))
module = types.ModuleType(name)
module.VALUE = f"value-{index}"
return module
return real_import(name, globals, locals, fromlist, level)
builtins.__import__ = custom_import
try:
def resolve_from_dict():
lazy_obj = globals()["target"]
resolved = lazy_obj.resolve()
print("resolved:", resolved.VALUE)
print("global after resolve:", type(globals()["target"]).__name__)
resolve_from_dict()
print("direct:", target.VALUE)
print("global after direct:", type(globals()["target"]).__name__)
print("calls:", calls)
finally:
builtins.__import__ = real_import
Expected: one import, with the module global replaced after resolve().
Actual on current main:
resolved: value-1
global after resolve: lazy_import
direct: value-2
global after direct: module
calls: [(1, 'target_module', '__main__', None), (2, 'target_module', '__main__', None)]
I confirmed this across tier1, tier2, and tier2 without uop optimization:
https://github.com/Kuhai9801/cpython/actions/runs/28243825007
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
- gh-152308
- gh-152524
- gh-157730
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reproducer in the issue and trace LazyImportType.resolve(), focusing on how the lazy object is stored in module globals. Done means resolve() causes one import, replaces the module global, and later direct access returns the same module; verify against the shown calls and output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 30/100