fix(py-lsp): resolve calls through aliased imports#1049
Open
DeusData wants to merge 1 commit into
Open
Conversation
from m import f as g; g() produced no CALLS edge at all. Two stacked defects: (1) py_lsp_bind_imports keyed from-style detection on the local name matching the module-path tail - an alias never matches, so g was bound MODULE(m.f) and the call missed; (2) even with the binding fixed, the pass join compares the bare tail of the resolved QN (f) against the textual callee (g) and dropped the resolution. Fix: (1) a dotted module path whose tail differs from the local name is an aliased binding - bind NAMED(qn) and let phase 6 upgrade it to the registered function/class (from-import alias) or module (import a.b as z); (2) when the identifier-callee NAMED branch resolves a name whose textual form differs from the QN tail, emit strategy lsp_import_alias with the textual name stashed in reason, and gate that strategy in the join's reason list - the exact pattern already used by lsp_dict_dispatch and lsp_func_ptr. The parallel path's hash index misses the alias key and falls through to the same gated linear scan. The contract test pins all four import forms (aliased from-import, plain from-import, single-segment module alias, dotted module alias) so the flip from MODULE to NAMED binding cannot regress the module- alias attribute chains. Closes #988 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #988
Bug (worse than reported)
The issue reports lsp=MISS with registry fallback covering it. On current main with a minimal two-file fixture,
from m import f as g; g(x)produces no CALLS edge at all — the registry fallback doesn't cover the minimal shape either. Two stacked defects:py_lsp_bind_importsdetects from-style imports by the local name matching the module-path tail. An alias never matches (local=g,qn=m.f), sogwas boundMODULE(m.f)— a call on a module → MISS.cbm_pipeline_find_lsp_resolutioncompares the bare tail of the resolved QN (f) against the textual callee (g) and dropped the resolution — verified by local instrumentation ofresolve_file_calls(the reporter's exact observation point).Fix
NAMED(qn); phase 6 upgrades it to the registered function/class (from X import Y as Z) or module (import a.b as z). Single-segmentimport m as mmstaysMODULE(untouched).lsp_import_aliaswith the textual name stashed inreason, and gate that strategy in the join's reason list — the exact pattern already used forlsp_dict_dispatch/lsp_func_ptr/lsp_destructor. The parallel path's hash index misses the alias key by design and falls through to the same gated linear scan.Reproduce-first
contract_edge_python_aliased_import_call_resolves_issue988pins all four import forms: aliased from-import (RED on main:alias=0 plain=1 modalias=1 dotalias=1), plain from-import, single-segment module alias, and dotted module alias — the last two guard the MODULE→NAMED flip against regressing module-attribute chains. The unit testpylsp_import_from_aliasedis tightened from "NAMED or MODULE acceptable" to NAMED-only (the tolerance this issue proved wrong).Verification
Full local suite 5999 passed, 1 skipped (main + the new test), zero regressions; lint-ci clean.