`lazy import a.b as c` resolves `b` as an attribute of `a` instead of importing the module `a.b`
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 68/100
Hướng nghiên cứu
Bắt đầu bằng cách đọc _PyEval_LazyImportFrom trong Python/ceval.c và _PyImport_LoadLazyImportTstate trong Python/import.c, sau đó tái hiện các ví dụ Case A và Case B từ issue trên Python 3.15. Được xem là hoàn tất khi lazy import a.b as c tuân theo ngữ nghĩa của eager import: nó import a.b theo tên, phát sinh lỗi đối với một subpath không phải là module và không sử dụng thuộc tính che khuất nó.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Bug report
Bug description:
lazy import a.b as c never imports the module a.b by name. On first use it imports a and reads the attribute b off it, as lazy from a import b would, so c becomes whatever that attribute lookup finds. This manifests in two ways.
Case A: a.b is not a module. The eager statement raises; the lazy one binds the attribute.
lazy import math.pi as lazy_x
print(lazy_x) # 3.141592653589793
import math.pi as x # ModuleNotFoundError: No module named 'math.pi'; 'math' is not a package
The bare lazy import math.pi was fixed in #155194; the as form was not.
Case B: a.b is a module, but a has an attribute b that shadows it and a.b has not been imported yet. The eager statement imports the submodule, which rebinds a.b to the module; the lazy one binds the attribute and never imports the submodule. json does not import json.tool, so the assignment below stands in for an attribute a package's __init__.py would define:
import json
json.tool = "attribute"
lazy import json.tool as lazy_c
print(type(lazy_c).__name__) # str
import json.tool as c
print(type(c).__name__) # module
Case B is related to #151208, which reports the same shadowing for import a.foo under -X lazy_imports=all followed by an attribute access a.foo, resolved in Objects/moduleobject.c. That script now passes on main; this statement still fails, because it is resolved on a different path.
Possible root cause
import a.b as c compiles to IMPORT_NAME a.b followed by IMPORT_FROM b. Lazily, IMPORT_NAME leaves a placeholder holding a.b, and _PyEval_LazyImportFrom (Python/ceval.c:3329-3384) replaces it with one holding lz_from = "a", lz_attr = "b". That is the same placeholder lazy from a import b produces.
Reification in _PyImport_LoadLazyImportTstate (Python/import.c:3902-4093) therefore runs __import__("a", fromlist=("b",)) followed by getattr(a, "b") for both statements. Nothing records that the statement was an import, so the module a.b is never imported by its own name: the "is not a package" check never runs, and an existing attribute b is never overwritten by the submodule.
This is not #157614, which is about the sys.modules fast path in _PyEval_LazyImportFrom consulting the wrong module. The present issue reproduces with the fix in #157626 applied.
CPython versions tested on:
3.15
Operating systems tested on:
Linux
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 36k
- Merge trung bình
- 1 ngày 9 giờ
- Pull request đã merge (30 ngày)
- 558
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của python/cpython
-
docs pending
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
stdlib type-feature
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
stdlib type-feature
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
build type-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
-
stdlib topic-email type-feature
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Tất cả issue của python/cpython
Issue tương tự
-
link-check link-check:sphinx-theme
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
qgis/QGIS-Documentation#11275 ·
-
bug priority:normal ready-for-dev
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
OpenHands/extensions#626 · 1 bình luận ·
-
Change observation tooltip text Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
CSCfi/sd-search-api#39 ·
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100