Skip to content

Fix import path boundaries and reuse absolute resolutions - #62

Open
TristanKruse wants to merge 2 commits into
perf/import-ast-traversalfrom
fix/import-boundary-and-resolution
Open

TristanKruse wants to merge 2 commits into
perf/import-ast-traversalfrom
fix/import-boundary-and-resolution

Conversation

@TristanKruse

Copy link
Copy Markdown
Collaborator

Summary

  • Fix an existing path-boundary bug: when the project root is .../app, a resolved sibling under .../app2 must be external. Previously startswith(project_root) classified it as internal, and the graph could drop the dependency entirely.
  • Cache absolute-import resolutions within an extraction session. Relative imports remain source-specific and uncached. clear_graph_cache() and CheckOptions(clear_cache=True) invalidate the session and its resolution cache.

This PR is stacked on #61. It does not change the parser or the public rule API.

Correctness

  • New tests cover sibling modules and packages, repeated absolute imports, explicit invalidation when a missing target appears, and equal-spelling relative imports from different directories.
  • 331 tests pass on Python 3.12 and 3.13. Ruff, strict Mypy, and git diff --check pass.
  • The existing 5,000-module clean, forbidden-edge, and cycle gates pass; ten-rule violation count remains 7,494. An eight-pair real-source check preserves all 385 ordered graph edges and import kinds exactly.

Performance (paired runs on one Windows host)

  • For 1,251 selected files and 3,747 imports, repeated absolute resolution reduces os.path.isfile probes from 3,747 to 2,499.
  • Library-only first rule: median 0.431 → 0.406 s (8 pairs). Ten subsequent rules: 1.160 → 1.009 s (8 pairs).
  • Full graph of this repository's source: 0.170 → 0.125 s (8 pairs, startup excluded).
  • Fresh pytest process, 5,000 modules: 1.186 → 1.183 s (12 pairs), effectively unchanged at end-to-end scale. Small fresh-process medians improved in a separate five-pair check but are too noisy for a strong claim.

These measurements do not establish that ArchUnitPython is the fastest tool. In a separate same-session five-round end-to-end comparison on the same corpus, ArchUnitPython via pytest was 1.269 s, Tach 1.053 s, and Import Linter 0.789 s. That comparison is local diagnostic evidence, not a CI threshold.

The resolution cache assumes a stable project snapshot during a session, like the existing graph and file-inventory caches. Callers changing files should clear the cache before rechecking.

This branch has not been deployed

No deployments
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