Repository navigation
3.2.3 is a bug-fix release that also warns about input 3.3.0 rejects or reads
differently. No dependency or Python-floor changes; one additive class,
prov.model.ProvFutureRejectionWarning. In the PROV-JSON read benchmark, the new checks
make reading about 8% slower than in 3.2.2.
Five kinds of fix change behaviour that existing code may rely on:
- Some errors change type. An empty PROV-N namespace IRI raises
ProvNSyntaxError, not
ValueError(#512). A PROV-JSON formal attribute written as an empty array raises
ProvJSONException, notIndexError. So does a time written as a value object that
is not anxsd:dateTime, which raisedAttributeError(#554) - A PROV-JSONLD value with both
@idand@value, which read as the@value, now
raisesProvJSONLDException(#545) - An ill-formed typed literal, such as
"abc" %% xsd:int, stays aLiteralinstead of
raising (#522) unified()leavesalternateOf,specializationOf,mentionOfandhadMember
records out of the merge by identifier, so equal ones stay two and differing ones no
longer raise (#530).prov_to_graph()andprov_to_dot()draw such records as
separate edges- The writers change their output for non-finite doubles (#550), a prefix named
default(#518), default-namespace names containing:(#517) andxsi:names
(#510)
Warnings ahead of 3.3.0
prov now emits ProvFutureRejectionWarning, a new subclass of ProvWarning, for
input that 3.3.0 rejects or reads differently, and still reads that input as before.
Each message ends with the issue that tracks the 3.3.0 rule, such as (#529). The
warnings cover:
- PROV-N: a repeated
default, a prefix name PROV-N does not allow, anxsi:name with
noprefix xsi, whitespace PROV-N does not allow, an attribute named after one of the
statement's arguments, and fourstrict-profile rules (#508, #509, #510, #511, #519,
#523) - Any reader or code: timezone offsets beyond ±14:00, malformed language tags, local
parts PROV-N cannot write, Python values with no PROV form, and qualified names that
do not resolve or are full IRIs (#472, #482, #513, #516, #524, #553) - PROV-JSON: repeated keys, malformed times, one-element arrays, nulls, names that are
not strings, unknown value-object keys, a$that is not a string, undeclared
datatypes, and full IRIs as names (#528, #529, #531, #532, #551, #552, #555, #597) unified(): an empty non-expandable position merged with a filled one (#547)
Prepare for prov 3.3.0
lists every message, the input that triggers it and what to write instead. It also shows
how to turn the warnings into errors to check a corpus.
Fixes
- The PROV-JSONLD reader accepts a qualified name written as a node reference,
{"@id": "ex:shed"}, under any attribute (#545). The 2026-10-14 revision of the
PROV-JSONLD schema adds this form, and ProvToolbox 2.2.5 writes it for a qualified name
under any attribute other thanprov:type,prov:locationandprov:role. The reader
raisedProvJSONLDExceptionfor the missing"@value". A node reference with a key
other than@idnow raisesProvJSONLDException. Before, one that also had an
"@value"read as that value, and its"@id"was dropped prov.read()without a format no longer showsprov's warnings from a format it tried
and set aside. Under anerrorfilter, a warning from the format it settles on now
raises fromread(). Before, the warning maderead()give up on that format and try
the next one- The PROV-N reader treats
xsias an ordinary prefix, as PROV-N reserves onlyprov
andxsd(#510).prefix xsi <http://example.org/>raised "prefix 'xsi' is reserved".
Anxsi:name now resolves against the document's own declaration. The PROV-N
writer declaresprefix xsiwhenever it writes anxsi:name - An empty namespace IRI in PROV-N,
prefix z <>ordefault <>, raises
ProvNSyntaxErrorat the IRI under every profile (#512). It raised a bareValueError
with no position. Code that catchesValueErroraround such a document no longer
catches it, sinceProvNSyntaxErroris not aValueErrorsubclass - The PROV-N reader decodes the code point escapes
\uXXXXand\UXXXXXXXXin
strings and IRIs, as PROV-N section 6 allows (#521)."caf\u00E9"raised
"unknown string escape '\u'". An escape that is not a Unicode scalar value, or that
encodes a character an IRI cannot contain, raisesProvNSyntaxErrorat the escape - The PROV-JSON and PROV-JSONLD writers write a default-namespace name whose local part
contains:, such as PROV-N'sa\:b, through a prefix bound to the default namespace
IRI (#517). They wrote it asa:b, which reads back as the namebunder the prefix
a. When no prefix is bound to that IRI, the writer declaresdn, ordn_1or the
next free suffix ifdnis taken - The PROV-JSON writer renames a prefix called
defaulttodefault_1, or the next free
suffix (#518). PROV-JSON uses thedefaultkey for the default namespace, so the
prefix read back as the default namespace and the names that used it did not resolve - Every writer spells the non-finite doubles
INF,-INFandNaN, thexsd:double
lexical forms (#550). The PROV-N, PROV-JSON, PROV-JSONLD and PROV-XML writers wrote
Python'sinf,-infandnan, which are outside the lexical space, and the PROV-O
writer did the same in RDF/XML, N-Triples and N-Quads. Every reader accepts both. A
float subclass, such asnumpy.float64, is written as the plain float it holds - The PROV-N writer warns with a
ProvWarningwhen it writes a%as%25because two
hexadecimal digits do not follow it, as it already did for the characters it
percent-encodes (#524). A PROV-N reader keeps the%25, so it recovers a different IRI - The PROV-N writer escapes an
xsd:anyURIvalue as it does a string (#526). A value
containing",\, a carriage return or a line feed produced PROV-N that the reader
rejected - A typed literal whose text is outside its datatype's lexical space, such as
"abc" %% xsd:int, stays aLiteralwith its text and datatype, as
"maybe" %% xsd:booleanalready did (#522). An ill-formedxsd:int,xsd:long,
xsd:integerorxsd:doubleraisedValueErrorfrom every reader and from the model.
The PROV-N reader reported it as a syntax error, and itslenientprofile skipped the
statement. The PROV-O reader also raisedValueErrorfor an ill-formedxsd:dateTime,
xsd:gYearorxsd:gYearMonth prov:time,prov:startTimeandprov:endTimeaccept aLiteraltyped
xsd:dateTime, so PROV-N's[prov:time="2012-01-01T00:00:00" %% xsd:dateTime]reads
(#515). It raised "Invalid value for attribute prov:time", and so did the model given
the sameLiteralin code. Text outside thexsd:dateTimelexical space still raises- The PROV-JSON reader accepts
prov:time,prov:startTimeandprov:endTimewritten
as a value object,{"$": "2012-01-01T00:00:00", "type": "xsd:dateTime"}(#554). It
raisedAttributeError. Any other value object, such as one with another datatype or
an ill-formed text, and a time that is neither a string nor a value object, raise
ProvJSONExceptionnaming the record and the attribute - A PROV-JSON formal attribute written as an empty array, such as
"prov:entity": [],
raisesProvJSONExceptionnaming the record and the attribute. It raised a bare
IndexError. TheProvJSONExceptionfor an array of several values now names the
record and the attribute too, and its message no longer goes to the
prov.serializers.provjsonlogger first unified()leavesalternateOf,specializationOf,mentionOfandhadMember
records out of the merge by identifier, since PROV-DM and PROV-Links give these
relations no identifier (#530). Two such records that shared an identifier and
differed raisedProvUnificationError; they now pass through unchanged. Two equal
ones were merged into one record and now stay two, untilunified()removes
duplicates in 3.3.0 (#548).prov_to_graph()andprov_to_dot()callunified(),
so they draw such records as separate edges. On a document that failed to unify only
because of such records,prov_to_graph()no longer raises andprov_to_dot()no
longer falls back to the bundle as asserted- The PROV-JSON reader gives every record of a
hadMemberwhoseprov:entityis an
array the membership's identifier and attributes (#530). Only the first record had
them, so the same collection read differently depending on which member came first.
A membership with several members and noprov:collectionreads; it raised
KeyError. A later member that does not resolve, such as one with an undeclared
prefix or a null, now reads as a membership with no entity, as the first member
already did, instead of raisingProvExceptionInvalidQualifiedName - The PROV-JSONLD reader keeps the
@idof aMembershipwith several members on every
record it reads, as it already did for one member (#530). 3.2.1 dropped the@id
with aProvWarning, becauseunified()raised on records sharing it
Project
- Python 3.15 is supported and tested in CI, so 3.2.x covers CPython 3.10 to 3.15 and
PyPy 3.11. No code changes were needed (#542)