You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Python: from <external> import name binds to an unrelated project symbol of the same name (exact-match) — false import cycles #2566
In Python, from <external module> import <name> gets an imports edge to an unrelated project symbol that happens to have the same name: a top-level variable or function in another file. The edge has resolvedBy: "exact-match" and confidence 0.9. If that other file imports the first one, which is common when it is a script using the package, findCircularDependencies() reports a cycle that does not exist. callers <name> lists the importing file as a caller.
This is the Python counterpart of #2101 (TypeScript, closed via #2120/#2128). The 1.6.2 fix does not cover Python.
Environment
@colbymchenry/codegraph 1.6.2 from npm, which is the current release
also reproduced on main at eec9288 (built from source, tsc only)
#2409 (import logging → app/core/logging.py) is a different path through the resolver. There the edge targets a file and has resolvedBy: "import" (filename-suffix match). Here it targets a symbol and has resolvedBy: "exact-match".
I built the head of open PR #1921 (b9840f6), and it removes this edge as well: all three positive rows above give [], and the two controls stay []. The PR description mentions only the file-suffix case. Its tests may not pin this form, so this repro could be useful as a regression case if the PR lands.
Where it was found
On a real 280-file Python repository (a package plus research scripts), 1.6.2 reports 25 import cycles. 5 of them are this defect: one script defines a top-level stats, and five package modules do from scipy import stats. On #1921's head these 5 are gone, and the number of true cycles found does not change (16 of 45 in both builds).
Not checked: other languages; Windows; from X import a as b with a local b; whether callees / impact / affected follow the edge (I expect they do, as in #2101, but did not verify).
Reproduced on current main (c71a3d0) with the two files as given: analysis.py -> variable stats (report.py) as an imports edge, exact-match 0.9, and the same for from os import path against a path = … in report.py.
The open PR #1921 (@inth3shadows — Python imports resolved from the package roots the project has) already carries the rule this needs: a name imported from a module no package root of the project provides names nothing in the project, so the import stays unresolved instead of falling to name matching. With that branch applied on top of main, both edges are gone and findCircularDependencies() returns [] for this repository.
Activity
test(python): pin colbymchenry#2566 — `from <external> import name` n…
danusha2345 commentedon Oct 15, 2026
Reproduced on current
main(c71a3d0) with the two files as given:analysis.py -> variable stats (report.py)as animportsedge,exact-match0.9, and the same forfrom os import pathagainst apath = …inreport.py.The open PR #1921 (@inth3shadows — Python imports resolved from the package roots the project has) already carries the rule this needs: a name imported from a module no package root of the project provides names nothing in the project, so the import stays unresolved instead of falling to name matching. With that branch applied on top of
main, both edges are gone andfindCircularDependencies()returns[]for this repository.test(python): pin colbymchenry#2566 — `from <external> import name` n…