mirror of
https://github.com/safishamsi/graphify.git
synced 2026-08-27 00:36:39 +00:00
fix(export): tolerate id-less persisted hyperedges in attach_hyperedges (#2775)
The semantic extractor emits hyperedges with no id and build.py persists them
verbatim, so a prior graph.json can contain id-less hyperedges. Seeding the
dedup set with a hard h["id"] raised KeyError: 'id' on every incremental
re-extract, silently failing the whole graph load. Guard the comprehension with
h.get("id"), symmetric with the incoming-set guard already below it; id-less
entries are retained in the graph, id-bearing dedup is unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
safishamsi
co-authored by
Claude Opus 4.8
parent
4fca621532
commit
ae8d059231
+7
-1
@@ -163,7 +163,13 @@ _CONFIDENCE_SCORE_DEFAULTS = {"EXTRACTED": 1.0, "INFERRED": 0.5, "AMBIGUOUS": 0.
|
||||
def attach_hyperedges(G: nx.Graph, hyperedges: list) -> None:
|
||||
"""Store hyperedges in the graph's metadata dict."""
|
||||
existing = G.graph.get("hyperedges", [])
|
||||
seen_ids = {h["id"] for h in existing}
|
||||
# Skip id-less persisted entries when seeding the dedup set (#2775): the
|
||||
# semantic extractor emits hyperedges with no `id` and build.py persists them
|
||||
# verbatim, so a prior graph.json can contain id-less hyperedges. A hard
|
||||
# `h["id"]` here raised `KeyError: 'id'` on every incremental re-extract,
|
||||
# symmetric with the `.get("id")` guard the loop below already applies to the
|
||||
# incoming set.
|
||||
seen_ids = {h["id"] for h in existing if h.get("id")}
|
||||
for h in hyperedges:
|
||||
if h.get("id") and h["id"] not in seen_ids:
|
||||
existing.append(h)
|
||||
|
||||
@@ -137,6 +137,20 @@ def test_attach_hyperedges_skips_entry_without_id():
|
||||
assert G.graph.get("hyperedges", []) == []
|
||||
|
||||
|
||||
def test_attach_hyperedges_tolerates_id_less_persisted():
|
||||
# Regression for #2775: the semantic extractor emits hyperedges with no `id`
|
||||
# and build.py persists them verbatim, so a prior graph.json can carry id-less
|
||||
# hyperedges. On the next (incremental) run, attach_hyperedges read that
|
||||
# persisted set with a hard `h["id"]` and died with `KeyError: 'id'`, writing
|
||||
# nothing. Reading the persisted set must tolerate missing ids.
|
||||
G = nx.DiGraph()
|
||||
G.graph["hyperedges"] = [{"nodes": ["a", "b"], "type": "project", "attributes": {}}]
|
||||
attach_hyperedges(G, [{"id": "flow_a", "label": "Flow A", "nodes": ["A", "B"]}])
|
||||
# No crash; the id-less persisted entry is retained and the new id-bearing
|
||||
# incoming hyperedge is appended.
|
||||
assert len(G.graph["hyperedges"]) == 2
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 3. to_json includes hyperedges key
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user