Repository navigation
python: an imported module-level instance types its receiver across the module boundary (#1140) - #1856
Merged
swapnilpaliwal-sd merged 1 commit intoOct 7, 2026
Conversation
…he module boundary (#1140) Three pieces, one shape: `order_service = OrderService()` in one module, `from svc.order_service import order_service; order_service.cancel(oid)` in another, and the call fell to a name match while the identical call next to the assignment resolved. - parser, import step: when the imported member's name collides with the module's own last segment -- the ordinary singleton idiom, the value named after its module -- the member-vs-submodule fallback suffix-matched the TARGET MODULE ITSELF and resolved the import as MODULE with an empty hash, so the VARIABLE branch (#1143) never ran. A module-level variable now counts as a declared member ahead of the submodule fallback, and a "submodule" that is the target module itself is rejected as the suffix collision it is. - parser, call sites: the per-module local type index is now built for every module before any module resolves call sites, and a binding created by a VARIABLE import copies the exporting binding's inferred type. The ordinary NAME-receiver lookup then resolves calls through the imported instance. - engine: binding_value_type gains the mirror clause -- a name bound by a VARIABLE import takes the type of the binding it names, write-count trade-offs inherited from the exporting side. Suite: 43/43 green; new case 43-module-singleton-import pins both shapes (colliding and non-colliding names) plus a genuine-submodule control, all known_edge. Cases 21 and 42 re-blessed: +1 and +3 known_edge, the untyped_receiver:local_untyped reason disappears, nothing demoted. On three corpus projects the parse-level A/B gains 621 resolved call sites and loses zero; engine A/B on one subject replaces 18 placeholder rows with 24 known_edge rows, solve time unchanged (53s -> 42s). Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
swapnilpaliwal-sd
requested review from
JaredHLZhang,
Whua689 and
suyashpaliwal26
as code owners
October 6, 2026 06:59
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.
Closes the residual of #1140. The external weekly report measured this shape at 22.4% of in-repo call sites unresolved in a Python repo vs 6.7% in the same repo rewritten in TypeScript, with the singleton idiom (
from svc.order_service import order_service) as the named repro.What was still broken after #1143
MODULEwith an empty hash, and the python/parser: resolve a from-import of a module-level value to VARIABLE, not MODULE (#1140) #1143VARIABLEbranch never ran.VARIABLEimports at all.The fix
VARIABLE-import binding copies the exporting binding's type.binding_value_typegains the mirror clause overimport_binding+import_resolved_target("VARIABLE", …).Evidence
43-module-singleton-importpins the colliding and non-colliding shapes plus a genuine-submodule control (allknown_edge). Cases 21/42 re-blessed: +4known_edge, theuntyped_receiver:local_untypedreason disappears, nothing demoted.MODULE('')→VARIABLE(hash). The only label-only churn is hashlessIMPORTED→ hashlessUNRESOLVEDon receivers that were previously mislabeled as module imports.ambiguous_unknown/boundary_lib) replaced by 24known_edgerows; noknown_edgeormulti_inferredlost; solve 53s → 42s.