The Onya model allows a node to have a set of types, and the Literate writer already serializes multiple types space-separated, but the
parser cannot read them back, so any graph with a multi-typed node fails to round-trip, and hand-authored multi-type headers crash with a confusing error.
Repro
# @docheader
* @document: https://example.org/g/doc
* @nodebase: https://example.org/g/
* @schema: https://schema.org/
* @iri:
* lv: https://example.org/g/schema
# acme [Organization lv:Client]
* name: ACME Corp
onya convert file.onya.md --mermaid →
NameError: name '_' is not defined
Root cause
- Writer (
literate.py): type_str = ' '.join(type_parts) emits all types,
space-separated—e.g. # acme [Organization lv:Client].
- Parser (
_literate_parse.py): the header grammar captures the bracket
content as a single token
(Optional(QuotedString('[', end_quote_char=']'))), and
process_nodeblock (~line 435) expands that whole string as one IRI:
expand_iri("Organization lv:Client", …). The space makes it an invalid IRI.
- The invalid-IRI branch in
amara/iri/irihelper.py (~line 59) raises
ValueError(_(f'Invalid IRI reference: …')), but _ (a gettext alias) is
undefined in that module → the real error is masked by NameError: name '_' is not defined. (Secondary bug worth fixing independently — it makes every
invalid-IRI failure opaque.)
Ergo a node with two types serializes fine but cannot be parsed. The round-trip
parse → write → parse is broken for any multi-typed node.
Proposed resolution
- SPEC (
#onya-literate-serialization): define the multi-type header syntax
explicitly — recommend space-separated types inside […]
([Organization lv:Client]), matching what the writer already emits, and
state that types are a set.
- Parser: tokenize the bracket content into 1..N type refs (split on
whitespace, respecting <…> CURIE/IRI wrappers), expand each, and add all to
node.types.
- Writer: already correct; add a round-trip test over a 2-type node.
Note: this upstream wart exacerbated the diagnosis of this problem.
The Onya model allows a node to have a set of types, and the Literate writer already serializes multiple types space-separated, but the
parser cannot read them back, so any graph with a multi-typed node fails to round-trip, and hand-authored multi-type headers crash with a confusing error.
Repro
onya convert file.onya.md --mermaid→Root cause
literate.py):type_str = ' '.join(type_parts)emits all types,space-separated—e.g.
# acme [Organization lv:Client]._literate_parse.py): the header grammar captures the bracketcontent as a single token
(
Optional(QuotedString('[', end_quote_char=']'))), andprocess_nodeblock(~line 435) expands that whole string as one IRI:expand_iri("Organization lv:Client", …). The space makes it an invalid IRI.amara/iri/irihelper.py(~line 59) raisesValueError(_(f'Invalid IRI reference: …')), but_(a gettext alias) isundefined in that module → the real error is masked by
NameError: name '_' is not defined. (Secondary bug worth fixing independently — it makes everyinvalid-IRI failure opaque.)
Ergo a node with two types serializes fine but cannot be parsed. The round-trip
parse → write → parseis broken for any multi-typed node.Proposed resolution
#onya-literate-serialization): define the multi-type header syntaxexplicitly — recommend space-separated types inside
[…](
[Organization lv:Client]), matching what the writer already emits, andstate that types are a set.
whitespace, respecting
<…>CURIE/IRI wrappers), expand each, and add all tonode.types.Note: this upstream wart exacerbated the diagnosis of this problem.