Every validation guard in scripts/generate_seed.py is an assert. Python strips assert statements under -O, so under that flag all three vanish and the generator writes unvalidated output while reporting success.
Raised during review of #9, where only one of the three checks was in scope. This tracks closing it for all of them.
The three checks
| line |
guard |
| 93 |
duplicate circumscription IDs |
| 99 |
type resolves against data/circumscription_types.json |
| 105 |
church_sui_iuris is a well-formed esi: reference |
Demonstrated, not theorised
Seeding two deliberately invalid values — "church_sui_iuris": "esi:" and "type": "ctype:bogus" — and running the real generator both ways:
python3 -O scripts/generate_seed.py … exit=0 "Wrote 2935 circumscriptions"
python3 scripts/generate_seed.py … exit=1 AssertionError
Under -O the run succeeds, prints its usual success line, and commits data/circumscriptions.json with church_sui_iuris: "esi:" and type: "ctype:bogus" throughout — two unresolvable cross-references, no warning, exit 0.
Note also that the failing run leaves the corrupt file in place, because the -O run had already written it. The guards abort before the write, but they cannot un-write a previous bad run.
Proposed change
Replace the three asserts with explicit checks that cannot be optimised away:
def fail(*problems):
raise SystemExit("generate_seed.py: " + "; ".join(problems))
Worth collecting all problems and reporting them together rather than aborting on the first — someone repairing seed data wants the full list, not one error per run.
The three checks are the whole of the validation surface, so this is a contained change. It should not alter behaviour on valid input: the generator must still exit 0 and write byte-identical output.
Also add the negative tests
The gap is really two gaps. crpdr ships scripts/test_generate_seed.py and coecdr ships scripts/test_generate_registry.py; this repository has no test module at all, so nothing would have caught the -O behaviour and nothing pins the guards' behaviour now.
The negative cases used in #8 and #9 were run ad hoc and thrown away. They should be committed as tests:
- duplicate ID → non-zero exit, no write
- unknown
ctype: → non-zero exit, no write
- malformed
church_sui_iuris (esi:, latin, esi:Latin, esi:-latin) → non-zero exit, no write
- each of the above under
-O as well, which is the case that regressed
- valid input → exit 0, output byte-identical
Sibling exposure
CatholicOS/cesidr has the same problem in scripts/generate_registry.py, with five guards rather than three: duplicate IDs (line 60), entry_count consistency (61), trad: resolution (65), cstat: resolution (67), and TRADITION_ORDER consistency (68). The fix is identical and should land alongside this one; say the word and I will open the companion issue there.
Every validation guard in
scripts/generate_seed.pyis anassert. Python stripsassertstatements under-O, so under that flag all three vanish and the generator writes unvalidated output while reporting success.Raised during review of #9, where only one of the three checks was in scope. This tracks closing it for all of them.
The three checks
typeresolves againstdata/circumscription_types.jsonchurch_sui_iurisis a well-formedesi:referenceDemonstrated, not theorised
Seeding two deliberately invalid values —
"church_sui_iuris": "esi:"and"type": "ctype:bogus"— and running the real generator both ways:Under
-Othe run succeeds, prints its usual success line, and commitsdata/circumscriptions.jsonwithchurch_sui_iuris: "esi:"andtype: "ctype:bogus"throughout — two unresolvable cross-references, no warning, exit 0.Note also that the failing run leaves the corrupt file in place, because the
-Orun had already written it. The guards abort before the write, but they cannot un-write a previous bad run.Proposed change
Replace the three
asserts with explicit checks that cannot be optimised away:Worth collecting all problems and reporting them together rather than aborting on the first — someone repairing seed data wants the full list, not one error per run.
The three checks are the whole of the validation surface, so this is a contained change. It should not alter behaviour on valid input: the generator must still exit 0 and write byte-identical output.
Also add the negative tests
The gap is really two gaps.
crpdrshipsscripts/test_generate_seed.pyandcoecdrshipsscripts/test_generate_registry.py; this repository has no test module at all, so nothing would have caught the-Obehaviour and nothing pins the guards' behaviour now.The negative cases used in #8 and #9 were run ad hoc and thrown away. They should be committed as tests:
ctype:→ non-zero exit, no writechurch_sui_iuris(esi:,latin,esi:Latin,esi:-latin) → non-zero exit, no write-Oas well, which is the case that regressedSibling exposure
CatholicOS/cesidrhas the same problem inscripts/generate_registry.py, with five guards rather than three: duplicate IDs (line 60),entry_countconsistency (61),trad:resolution (65),cstat:resolution (67), andTRADITION_ORDERconsistency (68). The fix is identical and should land alongside this one; say the word and I will open the companion issue there.