Skip to content

Python LSP does not resolve import ... as ... bindings — lsp=MISS for aliased call sites #988

Description

@LA-10

Version

0.8.1

Platform

macOS (Intel)

Install channel

Built from source

Binary variant

standard

What happened, and what did you expect?

When a Python module imports a symbol under an alias (from m import f as g) and calls it as g(), the Python LSP does not resolve the call. Instrumenting resolve_file_calls (pass_parallel.c) shows lsp=MISS with a null callee_qn for every aliased call site, while non-aliased calls to the same function resolve correctly with lsp=HIT.

Because lsp is NULL, these calls fall through to the registry chain. After #979 the registry resolves them correctly, so this is not user-visible today.
But the LSP path is the higher-confidence resolver (strategy=lsp_direct, confidence 0.95+) and would be preferable to the textual import_map fallback.

Expected: the LSP resolves g() to m.f, the same way it resolves a non-aliased f().

Reproduction

  1. Code: the repro repo from Python: CALLS / trace_path blind to import aliases (import scan_bash as _scan_bash) #875,
    file willow/fylgja/events/pre_tool.py

  2. Command:
    codebase-memory-mcp cli delete_project '{"project":"project-here"}'
    CBM_PROFILE=1 codebase-memory-mcp cli index_repository '{"repo_path":"abs-path-for-willow-here"}'

(CBM_PROFILE=1 preserves the worker log, which the supervisor otherwise deletes on a clean exit; delete_project forces a full index rather than the incremental no-op.)

  1. Observed by adding a temporary cbm_log_info in resolve_file_calls (pass_parallel.c) after the LSP lookup

     const cbm_gbuf_node_t *lsp_target = NULL;
     if (lsp) {
         lsp_target = cbm_pipeline_lsp_target_node(rc->main_gbuf, rc->project_name,
                                                   lsp->callee_qn, allow_tail);
         if (lsp_target) {
             res.qualified_name = lsp_target->qualified_name;
             res.strategy = lsp->strategy ? lsp->strategy : "lsp_override";
             res.confidence = (double)lsp->confidence;
             res.candidate_count = 1;
             ws->lsp_overrides++;
         }
     } else {
         res = cbm_registry_resolve(rc->registry, call->callee_name, module_qn, imp_keys,
                                    imp_vals, imp_count);
     }
    
     /* TEMPORARY Prints LSP resolution outcome */
     if (call->callee_name && strstr(call->callee_name, "scan")) {
         cbm_log_info("dbg875", "callee", call->callee_name,
                      "lsp", lsp ? "HIT" : "MISS",
                      "lsp_callee_qn", (lsp && lsp->callee_qn) ? lsp->callee_qn : "(null)",
                      "lsp_target", lsp_target ? lsp_target->qualified_name : "(null)");
     }
    

Logs

callee=scan_bash    lsp=HIT   lsp_callee_qn=willow.fylgja.safety.security_scan.scan_bash
callee=scan_write   lsp=HIT   lsp_callee_qn=willow.fylgja.safety.security_scan.scan_write
callee=scan_output  lsp=HIT   lsp_callee_qn=willow.fylgja.safety.security_scan.scan_output

callee=_scan_bash   lsp=MISS  lsp_callee_qn=(null)
callee=_scan_write  lsp=MISS  lsp_callee_qn=(null)
callee=_scan_worst  lsp=MISS  lsp_callee_qn=(null)
callee=_scan_output lsp=MISS  lsp_callee_qn=(null)

Diagnostics trajectory (memory / performance / leak issues)


Project scale (if relevant)

18,587 nodes / 82,156 edges / 1,423 files

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingparsing/qualityGraph extraction bugs, false positives, missing edgespriority/normalStandard review queue; useful PR with ordinary maintainer urgency.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions