Repository navigation
fix(graph): resolve Python calls made through a module name or import alias - #544
Knightkolla wants to merge 1 commit into
Conversation
🌱 graft blast radius1 area changed → 4 areas can be affected. 8 dependent symbols, depth 2. flowchart TB
A0(("Dependency Graph Construction<br/>5 symbols"))
A1(("Graph Engine<br/>1 symbol"))
A2(("Pull Request Review<br/>1 symbol"))
A3(("Symbol Overlap Detection<br/>1 symbol"))
classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
class A0,A1,A2,A3 reached;
Who knows this code — 3 people across 5 areas
Ownership is git history over each area's own files, weighted towards recent work (120-day half-life). Merge commits and bots are dropped, and you are dropped from your own PR. A name with no All 8 dependent symbols, grouped by areaDependency Graph Construction — 5 symbols in 5 files
Graph Engine — 1 symbol in 1 file
Pull Request Review — 1 symbol in 1 file
Symbol Overlap Detection — 1 symbol in 1 file
Test signal per changed area — 1 ⚠Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.
49 test suites also reference this code59 symbols, kept out of the diagram and the table so they cannot crowd out the areas a reviewer has to look at.
Open the interactive graph → — click an area to see its dependent symbols at file:line. |
|
The bug still reproduces on main, thanks: |
|
Thanks for checking! I’ll rebase onto main, switch to children/namedChildren so it fits the new SyntaxNode interface, and re-run the Python module test. Will push the update soon. |
… alias `import util` + `util.f()`, `import util as u` + `u.f()` and `from pkg import sub` + `sub.f()` were dropped, so `graft callers` reported no indexed callers for them. The extractor already captured these as member calls, but resolve.ts only resolves member calls whose receiver has a type, and a module has none. - src/graph/extract.ts: record which local names are bound to modules, and put the module specifier on calls made through them. A parameter or local with the same name shadows the module inside that function. - src/graph/resolve.ts: map the specifier to a repo file (absolute or relative) and look the name up inside that file only. - test/graph-python-module-calls.test.ts (new): the three call forms, same-named functions in two files, shadowing, and the relative import. Not covered: `import a.b` without an alias, and rebinding a module name later in the same scope. Assisted-by: Claude Code Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Knightkolla <kartikeyadhavala2468@gmail.com>
3c8b31d to
eeb5e29
Compare
|
@shhdwi rebased onto current main (e02b754) and pushed, so it applies cleanly and compiles again. I took the children/namedChildren route, so the SyntaxNode interface and both parser backends are untouched. It only uses Checked:
Two trail-scenario-hooks tests fail on a second local run because they keep a per-session "said once" marker in the Trail home dir. They fail the same on pristine main and pass with a clean HOME. Unrelated, but you may hit it. Known gaps are unchanged ( Ready for another look when you have time. |
Fixes #537.
graft callers said "no indexed callers" for Python calls made through a
module. Three forms now resolve:
from . import sub
Why it was dropped: the extractor was fine, util.f() came through as a
member call with receiver "util". But resolve.ts only resolves member
calls when the receiver has a type, and a module has no type, so the
edge just got thrown away.
What changed:
call on one of them carries the module info.
file only, functions first then class constructors, needs exactly one
match. So a same-named function in another file can't accidentally win.
defines sub itself, that wins. Otherwise it's the submodule file.
Not in scope here, left as known gaps:
Also ran into a separate bug while in here: the existing from-import
case doesn't really use an import table either, it just searches the
whole repo for a uniquely named function. Two files with the same
function name would silently break that too. Filing it separately,
didn't want to widen this PR.