Skip to content

fix(merge): Python 3.9 compat + accept documented batch-existing.json carryover - #545

Open
yzwooyi wants to merge 1 commit into
Egonex-AI:mainfrom
yzwooyi:fix/py39-merge-compat-and-batch-existing
Open

fix(merge): Python 3.9 compat + accept documented batch-existing.json carryover#545
yzwooyi wants to merge 1 commit into
Egonex-AI:mainfrom
yzwooyi:fix/py39-merge-compat-and-batch-existing

Conversation

@yzwooyi

@yzwooyi yzwooyi commented Jul 5, 2026

Copy link
Copy Markdown

Two bugs in skills/understand/merge-batch-graphs.py, both hit when /understand runs incrementally on a machine whose default python3 is 3.9 (stock macOS ships /usr/bin/python3 = 3.9.6).

1. X | None union annotations crash on Python 3.9

The script uses PEP 604 union syntax in function annotations, e.g.:

def load_batch(path: Path) -> dict[str, Any] | None:

On Python < 3.10 this annotation is evaluated at runtime and raises TypeError: unsupported operand type(s) for |: 'types.GenericAlias' and 'NoneType' at module load. SKILL.md invokes the script as bare python <SKILL_DIR>/merge-batch-graphs.py, so there's no interpreter pin to route around it, and the whole Phase 2 merge dies.

Fix: add from __future__ import annotations (PEP 563) so all annotations become lazy strings and are never evaluated at runtime. Every | union in the file is in an annotation position (verified — no runtime isinstance/cast unions, no match statements), so this fully resolves it with zero behavior change on 3.10+.

2. The documented batch-existing.json carryover is silently dropped

SKILL.md's incremental-update path (Phase 2) instructs:

  1. Write the pruned existing nodes/edges as batch-existing.json in the intermediate directory
  2. Run the same merge script — it will combine batch-existing.json with the fresh batch-*.json files

But the grouping regex only matches numeric batch names:

m = re.match(r"batch-(\d+)(?:-part-(\d+))?\.json", f.name)

so batch-existing.json falls into unrecognized_batch_files and is skipped at load. Result: every carried-over node from unchanged files — and every edge pointing at those nodes — is dropped from the merged graph. On an incremental refresh where most files are untouched, this silently guts the graph.

Fix: widen the regex to batch-(\d+|existing)… and map the non-numeric match to a report-only sentinel key (-1). It never collides with real batch indices, the file-discovery sort key already falls back for non-numeric names, and by_batch is used only for the summary counts — so node/edge loading is unaffected.

Verification

On /usr/bin/python3 (3.9.6): before this change the script crashes at import with the | TypeError; after, it loads cleanly and reaches its own argument handling (Error: … /intermediate does not exist, exit 1). py_compile clean on both 3.9 and 3.11. Diff is 6 insertions / 2 deletions, single file.

🤖 Generated with Claude Code

Two bugs in skills/understand/merge-batch-graphs.py that surface when
/understand runs incrementally on a machine whose default python3 is 3.9
(e.g. stock macOS ships /usr/bin/python3 = 3.9).

1. PEP 604 `X | None` union annotations are evaluated at runtime and raise
   `TypeError: unsupported operand type(s) for |` on Python < 3.10, so the
   module fails at import. SKILL.md invokes it as bare `python ...` with no
   interpreter pin. Fix: `from __future__ import annotations` makes all
   annotations lazy (PEP 563); every union usage in the file is an annotation,
   so this fully resolves it with no behavior change on 3.10+.

2. The incremental-update carryover file that SKILL.md tells the caller to
   write as `batch-existing.json` was silently dropped: the grouping regex
   only matched `batch-<N>.json`, so it landed in unrecognized_batch_files
   and every carried-over node from unchanged files (plus edges pointing at
   them) was excluded from the merged graph. Fix: widen the regex to accept
   `existing`, mapped to a report-only sentinel key (-1, never collides with
   real batch indices; the sort key already tolerates non-numeric names).

Verified: on /usr/bin/python3 3.9.6 the script crashed at import before,
loads cleanly after; py_compile clean on 3.9 and 3.11.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant