Skip to content

fix(python): avoid false ambiguity for aliased module imports - #2429

Open
hopstreax wants to merge 1 commit into
Graphify-Labs:v8from
hopstreax:fix/2428-python-aliased-import-member-resolution
Open

fix(python): avoid false ambiguity for aliased module imports#2429
hopstreax wants to merge 1 commit into
Graphify-Labs:v8from
hopstreax:fix/2428-python-aliased-import-member-resolution

Conversation

@hopstreax

Copy link
Copy Markdown
Contributor

Summary

Fixes #2428.

Fix Python member-call resolution when multiple imported modules share the same filename stem but one of them is imported with an alias.

Previously, aliased imports were still matched by their module stem during _resolve_python_member_calls. This could incorrectly introduce ambiguity when another imported module shared the same stem, causing valid calls edges to be skipped.

For example:

from pkg import service
from other import service as other_service

def register(payload):
    other_service.ping()
    return service.register_user(payload["name"])

The resolver incorrectly treated both pkg.service and other.service as candidates for the receiver service, even though Python only binds other.service to other_service.

Root Cause

The resolver matched imported modules using:

_module_stem_key(t) == rkey or file_aliases.get(t) == rkey

This allowed an aliased import to continue matching by its original module stem, creating false ambiguity whenever another imported module shared that stem.

Fix

Update _resolve_python_member_calls so that:

  • imports with a custom alias are matched only by their alias;
  • non-aliased imports continue to be matched by their module stem.

This aligns the resolver with Python's name-binding semantics while preserving existing behavior for non-aliased imports.

Tests

Added a regression test covering the following scenario:

  • from pkg import service
  • from other import service as other_service
  • other_service.ping()
  • service.register_user()

The test verifies that both calls edges are emitted.

Additionally:

  • Verified the new regression test fails on the original implementation.
  • Verified the regression test passes after the fix.
  • Ran the existing Python alias-related tests successfully.

@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 PR modifies the module-matching logic in _resolve_python_member_calls within graphify/extract.py. The condition for matching imported modules against a resolution key now prefers an alias match when the module has an alias entry, and otherwise falls back to comparing the module stem key. A new test is added in tests/test_extract.py covering the case where two imported modules share the same filename stem (one aliased, one not) to check that both calls resolve to their respective files.

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

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 1403 functions depend on the 465 functions this change touches.

Health — this change adds coupling hotspots:

  • worse: extract() — 360 callers, 29 callees

Verification — 1403 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: 1275 function(s) in the blast radius were not formally verified this run

· 1 more finding(s) on lines outside this diff (see the check 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.

1 participant