Skip to content

Bare import aliases can collapse into file-level self-loops #2037

Description

@Endogen

Summary

Graph construction can turn an unresolved bare import target into a self-loop when the target matches a legacy alias for the importing file.

Examples seen with Graphify 0.9.20:

  • Python stdlib: src/contracting/stdlib/builtins.py containing import builtins
  • Python package: playground/services/contracting.py containing from contracting import constants
  • Rust parent module imports such as use crate::fixture::{...} inside tests in fixture.rs
  • Rust external paths containing the current basename, such as ...::poseidon::{...} in poseidon.rs

The AST extraction initially emits a bare target such as builtins, contracting, or poseidon. During build_from_json(), the legacy-ID alias index can resolve that target to the importing file node, yielding an imports or imports_from edge whose source and target are identical.

Expected behavior

A file-level import or re-export that resolves to its own source should not be materialized. It carries no connectivity at file-node granularity and is reported as unhealthy by graphify diagnose multigraph.

Other meaningful self-edges, especially recursive calls, should remain intact.

Proposed fix

After endpoint resolution in build_from_json(), discard only self-loops whose relation is one of:

  • imports
  • imports_from
  • re_exports

A regression suite should cover the Python and Rust cases above and verify that recursive call self-loops are preserved.

Validation

The proposed patch removes all seven observed import self-loops across two real repositories. Their rebuilt diagnostics report zero self-loops, dangling endpoints, missing endpoints, or endpoint-collapse groups. The full Graphify test suite passes: 3,478 passed, 3 skipped.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions