diff --git a/graphify/benchmark.py b/graphify/benchmark.py index cf2bc6ba..a7edf5d0 100644 --- a/graphify/benchmark.py +++ b/graphify/benchmark.py @@ -39,7 +39,7 @@ def _query_subgraph_tokens(G: nx.Graph, question: str, depth: int = 3) -> int: terms = _query_terms(question) scored = [] for nid, data in G.nodes(data=True): - label = data.get("label", "").lower() + label = (data.get("label") or "").lower() score = sum(1 for t in terms if t in label) if score > 0: scored.append((score, nid)) diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py index b5751adc..27ea336e 100644 --- a/tests/test_benchmark.py +++ b/tests/test_benchmark.py @@ -54,6 +54,21 @@ def test_query_keeps_short_non_english_terms(): assert tokens > 0 +def test_query_handles_node_with_none_label(): + """A node can carry `label` with a None VALUE, not just a missing key. + + `.get("label", "")` only substitutes when the key is absent, so a stored + None reached `.lower()` and raised + `AttributeError: 'NoneType' object has no attribute 'lower'`. The loop + scans every node before returning, so one such node broke the whole + benchmark rather than just its own score. + """ + G = _make_graph() + G.add_node("n6", label=None, source_file="orphan.py", source_location="L1", community=0) + G.add_edge("n6", "n1", relation="calls", confidence="INFERRED") + assert _query_subgraph_tokens(G, "how does authentication work") > 0 + + # --- run_benchmark --- def test_run_benchmark_returns_reduction(tmp_path):