Skip to content

fix(resolve): follow Python receiver reassignments - #395

Merged
bompus merged 1 commit into
fork/consolidatedfrom
fix/python-reassignment
Oct 5, 2026
Merged

bompus merged 1 commit into
fork/consolidatedfrom
fix/python-reassignment

Conversation

@bompus

@bompus bompus commented Oct 5, 2026

Copy link
Copy Markdown
Owner

Python member calls could keep a receiver's original type after a later assignment. The following code linked m.dump() to Other::dump instead of Model::dump:

m = Other()
m = Model()
m.dump()

Receiver lookup now follows the latest preceding value in the same lexical scope. Unknown replacements remain unresolved.

Bare annotations preserve an existing value, captured variables retain their closure resolution, and a newly assigned import alias resolves through its selected module. Unaliased package imports preserve sibling modules across function boundaries. Multiple statements on one line retain the existing limitation.

Validation on Node 24:

  • Native kernel clippy/release build and application build passed.
  • Three receiver suites passed all 72 cases. Original and review regressions have before/after failure evidence at the real indexing boundary.
  • Full suite passed: 578 files, 7,402 tests, 39 existing skips.
  • Eight golden cases passed; regeneration produced no dump changes.
  • Flask's two positive precision controls and Vite's two positive/six negative controls passed. Complete call-edge comparisons found zero losses or gains in either corpus (1,115 Flask calls; 6,839 Vite calls).

README rows checked: the name/call-resolution description in About this fork was updated; its benchmark numbers are unchanged. The Python language reference and changelog describe the corrected behavior.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (4)
.cursor/rules/codegraph.mdc — auto-discovered
AGENTS.md — auto-discovered
Generated by CodeRabbit — auto-discovered
docs/viewer-launch-changelog.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9a5b391c-f43d-4083-b6f3-75b167277482
📥 Commits

Reviewing files that changed from the base of the PR and between 07c6778 and 44f91c8.

📒 Files selected for processing (9)
  • CHANGELOG.md
  • README.md
  • __tests__/receiver-scope-lookup.test.ts
  • codegraph-kernel/src/resolve/bound.rs
  • codegraph-kernel/src/resolve/imports.rs
  • codegraph-kernel/src/resolve/method_call.rs
  • codegraph-kernel/src/resolve/prefilter.rs
  • codegraph-kernel/src/resolve/receivers.rs
  • site/src/content/docs/reference/languages.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.


📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Python member calls now use the receiver’s latest preceding value in its lexical scope. If that value is unknown, the call remains unresolved instead of inheriting an earlier type.
    • Assignments after a call, bare annotations, and assignments in nested functions no longer incorrectly change receiver type resolution.
  • Documentation
    • Updated the Python resolution guidance and unreleased fixes list to describe receiver reassignment behavior.

Walkthrough

Python receiver resolution now selects the latest eligible binding in lexical scope for member calls and type inference. Unknown replacements do not reuse earlier types. Import resolution uses receiver-specific imports and preserves matching unaliased package imports. Tests and documentation cover assignment order, annotations, nested scopes, and imports.

Changes

Python receiver resolution

Layer / File(s) Summary
Select the Python receiver binding
codegraph-kernel/src/resolve/prefilter.rs, codegraph-kernel/src/resolve/method_call.rs, __tests__/receiver-scope-lookup.test.ts, README.md, CHANGELOG.md, site/src/content/docs/reference/languages.md
Python receiver lookup selects the latest eligible binding in the same scope at or before the reference. Bare annotation-only assignments do not replace a value. The tests and documentation cover assignment order, unknown replacements, later local bindings, nested scopes, and annotations.
Apply receiver bindings to resolution
codegraph-kernel/src/resolve/bound.rs, codegraph-kernel/src/resolve/method_call.rs, codegraph-kernel/src/resolve/receivers.rs, __tests__/receiver-scope-lookup.test.ts
Bound-type lookup, method-call matching, and receiver inference use the selected binding. Later bindings and unknown replacements do not supply an earlier receiver type.
Resolve receiver-specific imports
codegraph-kernel/src/resolve/imports.rs, __tests__/receiver-scope-lookup.test.ts
Python member import resolution uses the receiver binding. For an unaliased package import, it also includes matching package-import bindings. Tests cover local aliases, submodule imports, and explicit aliases.

Priority: ➖ Normal

Merge Risk: 🔵 Low · up to 44f91

Some calls inside captured functions may point to the wrong method after the outer variable changes. This bounded limitation does not prevent merging.

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: Python receiver lookup now follows reassignments.
Description check ✅ Passed The description explains the receiver-resolution bug, the intended behavior, and the reported validation results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Suppressions Explained ✅ Passed The pull request adds no lint, type-check, or compiler suppression directive. The changed-file list contains no lint or compiler configuration files, and the added-line diff contains no directive such…
User-Visible Changes Documented ✅ Passed The diff changes Python receiver resolution and adds tests. It does not add, remove, or rename a CLI command or flag, an MCP tool or argument, a supported language or framework, an agent target, or a …
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@bompus
bompus merged commit 89837c0 into fork/consolidated Oct 5, 2026
1 check passed
@bompus
bompus deleted the fix/python-reassignment branch October 5, 2026 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant