Skip to content

fix(python): get_method blind to module-level functions — get_callers/get_callees silent false-empty (local + Neo4j) #246

Description

@rahlk

PROBLEM

get_method delegates to get_all_methods_in_class(class_name) and therefore only searches class scope — module-level functions (most Python code; exactly the Odoo functions in #65) are unreachable. get_all_callers/get_all_callees call get_method internally, so for module-level functions they return the silent false-empty {"caller_details": []} even when the call graph knows the truth (G.predecessors("pkg.mod.helper") == ["pkg.mod.entry"]).

The backend demonstrably knows about module functions: get_all_methods_in_application (codeanalyzer.py:448-454) indexes module.functions under the module name, and _iter_callables (:559-563) enumerates them — the symmetric single-entity lookup is simply missing.

AFFECTED CODE (audit class A)

  • cldk/analysis/python/codeanalyzer/codeanalyzer.py:470 — get_method (class-only)
  • cldk/analysis/python/codeanalyzer/codeanalyzer.py:621, :660 — get_all_callers/get_all_callees false-empty for module funcs
  • cldk/analysis/python/codeanalyzer/codeanalyzer.py:494, :692, :703 — get_method_parameters, get_class_call_graph(method_sig), get_comments_in_a_method inherit the blindness
  • cldk/analysis/python/neo4j/neo4j_backend.py:439, :346, :354, :448 — identical bug on the Neo4j backend (and no bare-signature escape hatch)

FIX CONTRACT

  1. get_method(scope, name) resolves module-level functions when scope is a module name (mirroring get_all_methods_in_application's outer keys), with the same short-name fallback the class path has. Nested inner_callables reachable the same way _iter_callables sees them is in scope if cheap; document if deferred.
  2. get_all_callers("pkg.mod", "helper") returns the true predecessors from the call graph; same for callees.
  3. Both backends fixed identically — backend parity is part of the contract (assert both in tests).
  4. No public signature changes; miss-shape semantics unchanged (that is the 2.0.0 batch issue).

DEFINITION OF DONE

  • Failing tests first (test-driven): module-level function lookup + callers/callees on a fixture with a pkg.mod.entry -> pkg.mod.helper edge, exercised on BOTH backends.
  • Existing tests green; no facade signature changes.
  • Branch fix/issue-NNN; one PR closes this.

Found in the 2026-07-09 lookup audit (see #238 discussion; F1 oracle note on #239).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions