Repository navigation
Conversation
jdsika
marked this pull request as draft
October 5, 2026 10:27
jdsika
force-pushed
the
fix/string-derived-anyuri-types-stay-literals
branch
from
October 5, 2026 10:42
75f9be6 to
3e1b4ef
Compare
jdsika
marked this pull request as ready for review
October 5, 2026 10:55
jdsika
force-pushed
the
fix/string-derived-anyuri-types-stay-literals
branch
from
October 14, 2026 06:15
3e1b4ef to
d9d2745
Compare
This was referenced Oct 14, 2026
jdsika
force-pushed
the
fix/string-derived-anyuri-types-stay-literals
branch
from
October 21, 2026 15:56
d9d2745 to
419b047
Compare
jdsika
force-pushed
the
fix/string-derived-anyuri-types-stay-literals
branch
2 times, most recently
from
October 21, 2026 19:25
a378558 to
373df7a
Compare
This was referenced Oct 21, 2026
…nerator A value of a type is an IRI, a blank node or a literal according to one rule, linkml_runtime.utils.rdf_terms.type_term, which gen-jsonld-context, gen-owl, gen-shacl, gen-shex, gen-yarrrml and the RDF dumper and loader now share: - uri, uriorcurie and the types derived from them are IRIs; - objectidentifier is an IRI, and nodeidentifier and types with uri: rdfs:Resource are IRIs or blank nodes; - every other type is a literal of its datatype, including a type derived from string with uri: xsd:anyURI, which keeps URI references as text. The rule resolves the inherited, expanded datatype, so its spelling does not matter, and recognises uri and uriorcurie by name and definition rather than by from_schema, which merging imports rewrites. A datatype with an undeclared prefix is an error (xsd, shex and rdfs are known). The dumper writes the inherited datatype of a derived type and rejects relative values of IRI types (RDF 1.1 Concepts §3.2); the loader accepts IRIs for node-kind ranges in strict mode, keeps uri values complete, compacts uriorcurie values to CURIEs and keeps blank-node labels. gen-shacl gives sh:in values and sh:defaultValue the slot's term kind. The --xsd-anyuri-as-iri option of gen-owl and gen-jsonld-context is deprecated in 1.13.0, has no effect, and is scheduled for removal in 1.14.0. Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
jdsika
force-pushed
the
fix/string-derived-anyuri-types-stay-literals
branch
from
October 22, 2026 20:16
373df7a to
88e231b
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.
Mirror of linkml#4156, same head. Review there; this PR tracks the fork stack.
One rule decides whether a value of a type becomes an IRI, a blank node or a literal in RDF.
linkml_runtime.utils.rdf_terms.type_termis shared by gen-jsonld-context, gen-owl, gen-shacl, gen-shex, gen-yarrrml and the RDF dumper and loader.Example
For
homepage: https://alice.example.org/andfile_path: ./docs/cv.pdf:mainhomepage→"…"^^xsd:anyURIliteral,file_path→ same literalhomepage→@id,file_path→xsd:anyURIliteralhomepage→ IRI,file_path→<./docs/cv.pdf>(not an IRI, RDF 1.1 §3.2)homepage→ IRI,file_path→"./docs/cv.pdf"^^xsd:anyURIsh:nodeKind sh:IRIsh:IRI/sh:datatype xsd:anyURIowl:DatatypePropertyowl:ObjectProperty/owl:DatatypePropertyhomepageSo on
main, data written through the generated context fails the generated shapes, and the dumper writes relative IRIs. The--xsd-anyuri-as-irioption only moved the problem: with it,./docs/cv.pdfis resolved against the reader's location.The rule
uri,uriorcurieand types derived from themobjectidentifier(shex:iri)nodeidentifier(shex:nonLiteral), types withuri: rdfs:Resourcetypeof: stringwithuri: xsd:anyURIThe rule reads the inherited, expanded datatype, so its spelling does not matter, and it follows the
typeofchain, as gen-python does for the Python base class (ImageLink(URI)vsFilePath(str)).urianduriorcurieare recognised by name and definition, not byfrom_schema, which merging imports rewrites. An explicit datatype on a derived type wins (typeof: uriwithuri: xsd:stringis a string literal).Standards
xsd:anyURIliteral, not an IRI.sh:incompares terms exactly; ShEx 2.1 §5.4.2iri,bnode,nonliteral.LinkML contract and history
Literal(V, Type)and coerces context terms to@type=<s.type.uri>; types.yaml says aurivalue "is treated as a literal of type xsd:anyURI unless it is an identifier". cmungall chose literals in Clarify behavior of uriorcurie in rdf dumpers linkml/linkml#450, feat(shacl): improve type generation linkml/linkml#1300 and Fix xsd:anyURI range in JSON-LD generator linkml/linkml#2242.xsd:anyURI.--xsd-anyuri-as-irias an interim option for the context and OWL. Make it possible to map a URI to an RDF Node linkml/linkml#2495 and Using wrong XSD type for URIorCURIE linkml/linkml#2213 are open.uri/uriorcurie, and asks for that decision. The spec and types.yaml text then need a linkml-model update.Behaviour changes
uri/uriorcurieslots and derived types become@idandowl:ObjectPropertyby default (before: with the option; OWL also hadowl:allValuesFrom xsd:string). The metamodel and Biolink context snapshots change accordingly; OWLtype_objectsmode is unchanged.xsd:anyURItype is a literal (before: IRI).objectidentifierissh:IRI(wassh:BlankNodeOrIRI);nodeidentifierandrdfs:Resourcetypes are IRIs or blank nodes in the context, dumper, OWL, ShEx and YARRRML (before:^^shex:nonLiteralliterals that failed SHACL and reloaded asNone). Closes nodeidentifier values are written as shex:nonLiteral literals by the JSON-LD context and rdflib_dumper, so they never satisfy gen-shacl #51.sh:invalues andsh:defaultValuetake the slot's term kind; acurieslot withsubproperty_ofwas unsatisfiable.typeof: uritype without its ownuriwas a plain string literal; now the inherited datatype applies. Relative values of IRI types raiseValueError.cast_literals=False) and returns_:labelfor blank nodes in IRI-or-blank-node slots.xsd,shex,rdfsare known).--xsd-anyuri-as-iri: deprecated in 1.13.0, no effect, removal scheduled for 1.14.0. To keep aurislot as text, give it a string-derivedxsd:anyURItype. SEMICeu/core_person_linkml's threerange: urislots would need this.Alternatives not chosen
xsd:anyURI, as Emit URIRef for xsd:anyURI values in RDF serialization linkml/linkml#3221): relative references, which are validxsd:anyURI, cannot be IRIs.iritype: a metamodel change; not favoured in the feat(generators): add --xsd-anyuri-as-iri flag for cross-generator IRI consistency linkml/linkml#3292 review.Not in this PR
curiestays an unexpandedxsd:stringliteral although types.yaml says it MUST be expanded in RDF; JSON-LD cannot expand inside a literal, so it needs a decision (Using wrong XSD type for URIorCURIE linkml/linkml#2213).format: urionly when the inducedbaseisURI; the runtimeURIclass accepts relative references; the loader compacts IRIs to CURIEs also forurislots.Identifier.is_validrejects blank-node labels such as_:b1, sonodeidentifierblank nodes work through the context and the loader only withrdfs:Resourcetypes until that is fixed.linkmlneedslinkml-runtimeof the same release for the new module (floor bump at release, as for earlier runtime additions).Testing
test_uri_term_kinds.py(61): context, SHACL, OWL, ShEx and YARRRML output; dumper and context data paths validated with pyshacl; loader round trip and blank nodes; wrong-kind negatives, relative links,curiewithsubproperty_of. 31 fail onmain.test_rdf_terms.py(35): datatypes, spelling, identity in own and merged schemas, prefixes, values.