From 77f473437b1f12c00f05a37cb5cd168397ce1e80 Mon Sep 17 00:00:00 2001 From: Mpasha17 Date: Mon, 12 Oct 2026 20:21:18 +0530 Subject: [PATCH] fix(serve): refuse the dotted-symbol same-file tie in _tier_refusal (#4366) Moves the check out of _resolve_single_node so the path endpoint (CLI path / MCP shortest_path) refuses pkg.mod.run the same way get_node and explain do, instead of taking the first hit. Co-Authored-By: Grok Bot --- graphify/serve.py | 12 +++++------- tests/test_serve.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/graphify/serve.py b/graphify/serve.py index 90a5d3cb1..757bfc2a0 100644 --- a/graphify/serve.py +++ b/graphify/serve.py @@ -1701,13 +1701,7 @@ def _resolve_single_node(G: nx.Graph, label: str) -> tuple[str | None, str | Non tier = source_exact or exact or prefix or substring if not tier: return None, f"No node matching '{label}' found." - # A dotted symbol's tier is symbols, not a file followed by its members, so - # several hits in one file (a function and a same-named method) are a tie. - file_query = ( - bool(source_exact) and "::" not in label - and source_exact != _resolve_python_qualified(G, label) - ) - refusal = _tier_refusal(G, label, tier, file_query=file_query) + refusal = _tier_refusal(G, label, tier, file_query=bool(source_exact) and "::" not in label) if refusal: return None, refusal return tier[0], None @@ -1723,6 +1717,10 @@ def _tier_refusal(G: nx.Graph, label: str, tier: list[str], *, file_query: bool) rivals = _rivals_across_files(G, tier) if rivals: return _ambiguity_message(G, label, rivals) + # A dotted Python symbol's tier is symbols, not a file followed by its + # members, so a function and a same-named method in one module tie (#4366). + if file_query and len(tier) > 1 and tier == _resolve_python_qualified(G, label): + file_query = False if len(tier) > 1 and not file_query: return _same_file_ambiguity_message(G, label, tier) return None diff --git a/tests/test_serve.py b/tests/test_serve.py index 136c18152..0cfe882af 100644 --- a/tests/test_serve.py +++ b/tests/test_serve.py @@ -1895,3 +1895,13 @@ def test_dotted_python_symbol_same_file_tie_is_refused(): G.add_node("m", label=".run()", source_file="pkg/mod.py", source_location="L9") nid, err = _resolve_single_node(G, "pkg.mod.run") assert nid is None and err.startswith("Ambiguous") + + +def test_dotted_python_symbol_same_file_tie_is_refused_by_path_endpoint(): + """`path` refuses the same dotted tie `get_node`/`explain` do (#4366).""" + from graphify.serve import _resolve_path_endpoint + G = nx.Graph() + G.add_node("f", label="run()", source_file="pkg/mod.py", source_location="L1") + G.add_node("m", label=".run()", source_file="pkg/mod.py", source_location="L9") + nid, _, err = _resolve_path_endpoint(G, "pkg.mod.run") + assert nid is None and err.startswith("Ambiguous")