Repository navigation
aft_callgraph returns 0 callers for cross-file Python call sites #1126
Copy link
Copy link
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Short description
aft_callgraph returns 0 callers for cross-file Python call sites; same-file callers resolve normally
What happened?
aft_callgraph callers finds no cross-file call sites in Python code. A function called from another file through an ordinary static import (top-level from mod import func or a function-local from mod import func inside a function body) is reported as having 0 callers, and the answer is presented as complete (no shown N of M envelope, no gap note). The same edge resolves in TypeScript.
Diagnostics
Reproduction (all files directly in the project root of a fresh directory, engine configured on it):
`mod.py`:
def toplevel_target():
return 1
def local_target():
return 2
def test_target():
return 3
def same_file_caller():
return toplevel_target()
`caller_toplevel.py`:
from mod import toplevel_target
def run_toplevel():
return toplevel_target()
`caller_local.py`:
def run_local():
from mod import local_target
return local_target()
`tests/test_probe.py`:
class TestProbe:
def test_local(self):
from mod import test_target
return test_target()
Requests and observed results:
- `{"command":"callers","file":"<root>/mod.py","symbol":"toplevel_target"}` -> `0 callers`
- `{"command":"callers","file":"<root>/mod.py","symbol":"local_target"}` -> `0 callers`
- `{"command":"callers","file":"<root>/mod.py","symbol":"test_target","includeTests":true}` -> `0 callers`
- `{"command":"call_tree","file":"<root>/caller_toplevel.py","symbol":"run_toplevel","depth":1}` ->
`+ 1 unresolved external call: toplevel_target`
- `{"command":"call_tree","file":"<root>/caller_local.py","symbol":"run_local","depth":1}` ->
`+ 1 unresolved external call: local_target`
After adding `same_file_caller` to `mod.py` (calls `toplevel_target` within the same file), `callers toplevel_target` returns exactly that one same-file caller — same-file Python edges resolve, cross-file Python edges do not. A TypeScript control (`ts_mod.ts` exporting `tsTarget`, `ts_caller.ts` importing `./ts_mod` and calling it) resolves the cross-file edge normally.
Expected: `callers` finds the cross-file call sites (documented as "Find all call sites of a symbol"), or — following the honest-zero-callers behavior introduced with #1015 — the reply discloses that unresolved call sites exist in the analyzed code instead of presenting a bare 0 as complete.
Observed: bare `0 callers` with no disclosure on the shipped release, while the call sites exist in plain `from`-import form (no dynamic import, no importlib/exec).Plugin version
0.62.0
AFT binary version
0.62.0
Platform
linux x64
Log output (optional)
Reacted by aft-alfonso
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
aft-alfonso commentedon Oct 30, 2026
Thanks for the reproduction and the additional details in #1130. Python's cross-file imports were not being resolved, and function-local imports were omitted. The next release fixes these imports, including package-relative imports and
import mod; mod.f(), without matching unrelated functions with the same name.Caller and impact results will also warn about unresolved calls with the queried name when some callers were found, while retaining the zero-caller warning already on main. This work is tracked in #1126 and covers the details from #1130 as well.
mason: reproduce Python cross-file import callers (cortexkit#1126)
mason: resolve lexical Python imports in shared callgraph store (cort…
mason: index Python call bindings and preserve hidden-test disclosure (…
mason: require exact Python import targets and test public flags (cor…
mason: disclose matching unresolved callers in nonempty answers (cort…
mason: retain indexed named-site counts and clarify cap metadata (cor…
mason: account for one bounded disclosure query in batching proof (co…
mason: prepare rebased Python callers for merge (cortexkit#1126)
aft-alfonso commentedon Oct 31, 2026
Thanks for the reproduction and the additional details in #1130. Python's cross-file imports were not being resolved, and function-local imports were omitted. The next release fixes these imports, including package-relative imports and
import mod; mod.f(), without matching unrelated functions with the same name.Caller and impact results will also warn about unresolved calls with the queried name when some callers were found, while retaining the zero-caller warning already on main. This work is tracked in #1126 and covers the details from #1130 as well.