Merge pull request #1280 from s22hyun/fix/affected-edges-key

fix(affected): handle "edges"-keyed graph.json in load_graph (KeyError: 'links')
This commit is contained in:
Safi
2026-06-12 19:54:38 +01:00
committed by GitHub
2 changed files with 36 additions and 0 deletions
+6
View File
@@ -165,6 +165,12 @@ def load_graph(path: Path) -> nx.Graph:
# Force directed so stored caller→callee direction survives the round-trip;
# mirrors serve.py and __main__.py (#1174).
raw = {**raw, "directed": True}
# Normalize the edge key: graphify's `extract` output uses "edges" while
# networkx's node_link_data default is "links". Without this, an edges-keyed
# graph.json raises an uncaught KeyError: 'links' here — every other loader
# (__main__.py) already normalizes this (#738; same class as #1198).
if "links" not in raw and "edges" in raw:
raw = dict(raw, links=raw["edges"])
try:
return json_graph.node_link_graph(raw, edges="links")
except TypeError:
+30
View File
@@ -94,6 +94,36 @@ def test_affected_cli_forces_directed_on_undirected_graph(monkeypatch, tmp_path,
assert "No affected nodes found." not in out
def test_affected_cli_loads_edges_keyed_graph(monkeypatch, tmp_path, capsys):
"""graphify's `extract` writes graph.json with an "edges" key (not networkx's
default "links"). affected.load_graph must handle it; before the edges/links
normalization it raised an uncaught KeyError: 'links' (same class as #1198)."""
graph = nx.DiGraph()
graph.add_node("target", label="Foo", source_file="pkg/foo.py", source_location="L1")
graph.add_node("caller", label="X()", source_file="app.py", source_location="L4")
graph.add_edge("caller", "target", relation="calls", context="call", confidence="EXTRACTED")
# Emulate graphify extract output: top-level "edges" key instead of "links".
data = json_graph.node_link_data(graph, edges="links")
data["edges"] = data.pop("links")
graph_path = tmp_path / "graph.json"
graph_path.write_text(json.dumps(data), encoding="utf-8")
monkeypatch.setattr(mainmod, "_check_skill_version", lambda _: None)
monkeypatch.setattr(
mainmod.sys,
"argv",
["graphify", "affected", "Foo", "--graph", str(graph_path)],
)
mainmod.main()
out = capsys.readouterr().out
assert "Affected nodes for Foo" in out
assert "X()" in out
assert "calls" in out
def test_resolve_seed_bare_name_matches_callable_label():
from graphify.affected import resolve_seed