Skip to content

fix(rdf): delegate canonicalization to the diffable-rdf library - #26

Open
jdsika wants to merge 1 commit into
feat/diff-stable-serializationfrom
refactor/delegate-canonicalizer
Open

jdsika wants to merge 1 commit into
feat/diff-stable-serializationfrom
refactor/delegate-canonicalizer

Conversation

@jdsika

@jdsika jdsika commented Sep 11, 2026 •

Copy link
Copy Markdown

Mirror of linkml#3987, same head. Review there; this PR tracks the fork stack.

Stacked on #24. #25 is folded into this PR.

Summary

linkml_runtime.utils.rdf_canonicalize was extracted into diffable-rdf at the maintainers' request (linkml#3295), and the two copies diverged. This PR deletes the in-tree copy and calls the library. That fixes nine defects in the RDF output of every generator and RDF dumper on main:

Defect on main Effect
@base ending in # Every IRI sharing that prefix is rewritten. The output parses, but its meaning has changed.
Shared rdf:List tail Duplicated: 9 triples in, 11 out.
N-Triples with a relative IRI The file is unparseable. It now raises ValueError, as N-Triples §2.2 says: "IRIs may be written only as absolute IRIs".
U+2028 and other line separators in a literal Broken by the fallback's line sort.
JSON-LD, degraded Turtle, degraded RDF/XML Differ between processes; for example, gen-owl -f json-ld on personinfo with two hash seeds.
Trailing newline Differs by format.
rdflib.Dataset Named graphs are silently flattened. Datasets are now refused.

Each defect is a test in test_rdf_canonicalize_defects.py, run against both linkml_runtime's function and the library's.

Dependency

diffable-rdf becomes a required dependency of linkml-runtime, because the default path needs it. Facts for that decision:

The library logs degraded output, and linkml_runtime re-emits it as RDFCanonicalizationWarning, so the warning stays visible without any logging configuration.

Output

For the metamodel and personinfo, the Turtle output of gen-owl, gen-shacl, gen-rdf and gen-shex --format rdf is byte-identical before and after this PR. JSON-LD output is now deterministic, and its graph is unchanged (isomorphic, 1,134 triples).

Testing

  • test_rdf_canonicalize_defects.py covers the nine properties above. Before delegation, each of them failed for linkml and passed for the library.
  • Runtime suite: 1,864 passed. Compiler suite: 12,393 passed.

Fork stack: #24 → #26; #27 (docs) is based on #24.

The RDF canonicalizer in linkml_runtime was extracted into diffable-rdf,
and the two copies diverged. Calling the library fixes nine defects of
the in-tree copy, each asserted against both entry points in
test_rdf_canonicalize_defects.py:

- a base IRI ending in # no longer rewrites every IRI sharing its prefix
- a shared rdf:List tail is no longer duplicated
- N-Triples refuses a relative IRI instead of writing a file its own
  parser rejects; N-Triples allows only absolute IRIs
- literals containing U+2028 and other line separators survive sorting
- degraded RDF/XML, degraded Turtle and JSON-LD are byte-identical
  across processes
- every format ends with exactly one newline
- a Dataset is refused instead of silently flattened

diffable-rdf becomes a required dependency of linkml-runtime. It needs
only rdflib and pyoxigraph, which the runtime already requires. The
diff-stable extras remain as aliases. Turtle output of the four RDF
generators is unchanged.

The library logs degraded output; the runtime re-emits those records as
RDFCanonicalizationWarning so they stay visible without logging
configuration.

Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
@jdsika
jdsika force-pushed the refactor/delegate-canonicalizer branch from 38f1f9b to 011fc23 Compare October 13, 2026 18:39
@jdsika jdsika changed the title refactor(rdf): delegate canonicalization to the diffable-rdf library fix(rdf): delegate canonicalization to the diffable-rdf library Oct 13, 2026
@jdsika
jdsika changed the base branch from main to feat/diff-stable-serialization October 13, 2026 18:39
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