Skip to content

Fix inferred Python uses edge attribution for sibling classes - #2375

Open
hopstreax wants to merge 1 commit into
Graphify-Labs:v8from
hopstreax:fix/2318-python-uses-edge-scope
Open

Fix inferred Python uses edge attribution for sibling classes#2375
hopstreax wants to merge 1 commit into
Graphify-Labs:v8from
hopstreax:fix/2318-python-uses-edge-scope

Conversation

@hopstreax

Copy link
Copy Markdown
Contributor

Closes #2318

Summary

Fixes incorrect inference of Python uses edges where every class in a file inherited dependencies from shared from ... import ... statements, even if only one class actually referenced the imported symbol.

Root Cause

_resolve_cross_file_imports() treated imported symbols as file-level ownership and unconditionally emitted inferred uses edges for every entry in local_classes.

As a result, sibling classes that never referenced an imported symbol were incorrectly attributed with uses edges.

Solution

This change adds a scoped ownership collection pass during the resolver's existing AST processing.

Instead of broadcasting resolved imports to every local class, the resolver now:

  • Performs a single AST traversal while tracking the current class scope.
  • Collects referenced identifiers for each class using canonical class node IDs.
  • Distinguishes reference occurrences from common binding contexts.
  • Emits inferred uses edges only for classes that actually reference the imported symbol.

The extraction pipeline and output schema remain unchanged.

Verification

Verified using targeted reproduction scenarios including:

  • Sibling classes sharing module imports.
  • Module-level references.
  • Nested classes.
  • Duplicate class names.
  • Decorators and base classes.

Also ran the existing targeted test suite:

pytest tests/test_python_import_resolution.py tests/test_symbol_resolution.py

All targeted tests passed.

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).


Graphify review — findings

This pull request removes several recently-added features and fixes that were staged under the unreleased 0.9.32 changelog entry, reverting the associated code and its changelog notes. Affected areas include tier-aware (AST vs. semantic) node/edge merging logic in build.py (removing _is_ast_tier and _origin shape-fallback handling), the numeric-id coercion helpers (_coerce_id/_coerce_non_string_ids), and the directed-flag preservation in _load_existing_graph, along with touched code across the extractors, detect, watch, and serve modules. The change surface spans build.py, resolution/engine extractors, and corresponding test files (detect, watch, build), plus multiple changelog version entries. Reviewers should focus on whether the reverted behavior and removed helper functions are intended to be dropped or relocated.

No blocking issues surfaced. 6 lower-confidence candidates did not survive cross-model review.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 3360 functions depend on the 1733 functions this change touches.

Health — grade A; 10 existing hotspot(s) in the area this change touches (pre-existing, not introduced here):

  • extract() — 351 callers, 28 callees (high)
  • _rebuild_code() — 55 callers, 48 callees (high)
  • build_from_json() — 138 callers, 13 callees (high)
  • deduplicate_entities() — 49 callers, 21 callees (high)
  • detect() — 80 callers, 11 callees (high)
  • extract_files_direct() — 15 callers, 19 callees (high)
  • _extract_generic() — 18 callers, 15 callees (high)
  • extract_xaml() — 19 callers, 12 callees (high)
  • …and 2 more

Verification — 3360 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 3139 function(s) in the blast radius were not formally verified this run

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.

Semantic extractor over-attributes "uses" edges to all sibling classes in a file, not just the class that references the import

1 participant