Repository navigation
Conversation
jdsika
force-pushed
the
fix/rdf-canonicalize-defects
branch
from
October 14, 2026 19:10
a438150 to
1d3952e
Compare
The comparison with diffable-rdf recorded defects in linkml_runtime.utils.rdf_canonicalize. Fix them in the module itself: - Declare a base IRI without its fragment, as RFC 3986 section 5.1 uses it. A base ending in "#" made rdflib read relative references back as different IRIs. On the rdflib fallback, keep the base only if the output reads back with the same absolute IRIs, because rdflib relativizes by string prefix. - Refuse N-Triples and N-Quads with ValueError for graphs pyoxigraph rejects. Their N-Triples is what pyoxigraph's parser just refused; N-Triples 1.1 section 2.2 admits only absolute IRIs. This removes the fallback's line sort, which split literals on U+2028. - On the fallback, hand rdflib the statements in sorted order and name unbound namespaces in sorted order, so Turtle, RDF/XML and JSON-LD no longer vary with the hash seed. - Serialize JSON-LD through pyoxigraph like the other formats, indented. rdflib's JSON-LD writer relativized IRIs against a base without declaring it, so they resolved against the reader's location. - Write TriG on the fallback as Turtle, a TriG document with every triple in the default graph, where the pyoxigraph path puts them. rdflib named the graph after a random blank node. - End every output with exactly one newline. - Refuse a Dataset or ConjunctiveGraph instead of flattening it. rdflib 7.6 and earlier still write an rdf:List cell shared by two lists once per list on the fallback; that test is a strict xfail until rdflib releases its fix. Also replace mock_black_import with the general mock_missing_import fixture. Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
jdsika
force-pushed
the
fix/rdf-canonicalize-defects
branch
from
October 14, 2026 19:11
1d3952e to
5d3a664
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces linkml#3987, as requested there. It fixes the canonicalizer defects that the diffable-rdf comparison (linkml#3986, linkml#3987) recorded, in
linkml_runtime.utils.rdf_canonicalizeitself rather than by delegating to the library. There is no new dependency, and thediff_stablepath is unchanged.Fixes
main#makes rdflib read relative references back as different IRIs (http://ex.org/d##a)ValueError. The fallback is taken because pyoxigraph's N-Triples parser refused exactly this textns1/ns2names)Datasetis silently flattenedTypeErrorfor context-aware graphs@ids without declaring@base, so they resolve against the reader's locationrdf:Listtail is written twice on the fallbackBehaviour changes
ntandnquadsraiseValueErrorfor graphs pyoxigraph rejects, instead of returning text that no N-Triples parser accepts.DatasetorConjunctiveGraphraisesTypeError. All generators and dumpers pass a plainGraph.rdf:typeas a property rather than as@type. The RDF is the same.Output
gen-owl,gen-shacl,gen-rdfandgen-shex --format rdfon the metamodel and personinfomaingen-shacl --include-annotationson the metamodel, the only generator run that reaches the fallbackgen-owl -f json-ldmain's output (5,318 and 1,134 triples), and now identical across processesTests
New tests in
test_rdf_canonicalize.py, each of which fails onmain:#and one ending in/. 12 of these 20 cases fail onmain.Datasetrefusal, and the shared list (strict xfail). fix(rdf): delegate canonicalization to the diffable-rdf library linkml/linkml#3987's defect file also passes against this module, except the shared list case, as expected with rdflib 7.6.Two existing tests change:
pretty-xml, becausejson-ldis now supported.nt, which is now refused, and covers the formats above.The PR also folds in the fixture cleanup from the linkml#3985 review:
test_template_noblackusesmock_missing_import("black"), andmock_black_importis removed.Local results: runtime suite 1,865 passed; compiler suite 12,393 passed; pre-commit clean.
Upstream and limitations
gen-shacl --include-annotationswrites an annotation tag without:as a literal predicate, which is not RDF. That is a separate generator defect.