feat: extract Python method body references for dependency graph#147
Conversation
Add collectBodyReferences() to Python daemon that walks method/function body AST to find Call nodes and resolve their callees. This dramatically increases relationship density for Python projects (from ~27 to potentially 100+ rels/component), which was the root cause of Python's 0% match rate in the existential test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 828ffd45bb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const resolved = resolveTypeFromRaw(calleeText, ctx); | ||
| if (resolved) { | ||
| refs.push({ raw: calleeText, targetUniqueName: resolved, externalLabel: resolved }); |
There was a problem hiding this comment.
Avoid resolving instance calls as module functions
When the callee is a dotted expression, resolving the entire text through resolveTypeFromRaw makes ordinary instance calls look like module-level symbols whenever the receiver name matches a module in the package. In the added fixture, dao = UserDao(); dao.find_by_id(...) is emitted by the daemon as a targetUniqueName of src.dao.find_by_id (not the UserDao.find_by_id(...) method component), so after classification the method gains a bogus external dependency. This will pollute dependency graphs for common variable names like repo.save() or service.call() that happen to match sibling modules; dotted callees should only be resolved this way when the base is a known imported module/alias, not a local variable.
Useful? React with 👍 / 👎.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #147 +/- ##
============================================
- Coverage 71.87% 71.77% -0.11%
- Complexity 903 904 +1
============================================
Files 65 65
Lines 4093 4106 +13
Branches 699 705 +6
============================================
+ Hits 2942 2947 +5
- Misses 723 727 +4
- Partials 428 432 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…tives Only resolve dotted callees (e.g. dao.find_by_id) when the base is a known imported symbol or local class, not an arbitrary local variable. This prevents variable names matching module names from creating bogus external dependencies. Also bump version to 9.7.0. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
collectBodyReferences()that walks the suite AST to find Call nodes and resolve their callees viaresolveTypeFromRaw(). Skips nested Function/Class nodes. Results attached to bothextractMethod()andextractFunction()return values.bodyReferencesfield (List<PythonTypeRefModel>)SimpleTypeReferenceentries in bothbuildMethodComponent()andbuildFunctionComponent()This dramatically increases relationship density for Python projects (~27 rels/component → potentially 100+), which was the root cause of Python's 0% match rate in the existential test.
Test plan
PythonMethodBodyRefsTest— all passing🤖 Generated with Claude Code