Skip to content

3.3.0

Latest

Choose a tag to compare

@trungdong trungdong released this 08 Nov 22:33
· 15 commits to main since this release
45a12de

3.3.0 is a minor release that rejects the input 3.2.3 warned about with ProvFutureRejectionWarning, requires Python 3.11, and adds a Pygments lexer for PROV-N and new command-line options. Code that reads PROV it did not write, catches a reader's errors or compares literals may need changes, and Upgrading to prov 3.3.0 gives each case. It also fixes GHSA-pp6h-3q6w-xr98 in the PROV-O reader, which 2.5.4 fixes on the 2.x line. Against 3.2.3 on the benchmark suite, most operations are faster by up to 30%, but the PROV-JSON and PROV-JSONLD reads are 7% to 11% slower, mostly because each attribute value gets its comparison key when it is asserted, and prov_to_graph() is 27% to 38% slower because it now includes the records inside bundles.

These changes need action:

  • Install on Python 3.11 or later
  • Catch prov.serializers.ProvSerializationError, or prov.Error, around a read (Exceptions)
  • Correct the input that raised ProvFutureRejectionWarning in 3.2.3, because it now raises an error (Read the message)
  • Index the list that get_records() with a class returns, where 3.2.3 returned an iterator (get_records())

Breaking changes

3.3.0 rejects the input that 3.2.3 warned about with a ProvFutureRejectionWarning, and a further set of ill-formed inputs, and reads a few inputs differently. Upgrading to prov 3.3.0 lists each message, the input that causes it and what to write instead.

  • prov requires Python 3.11 or later, since Python 3.10 reached its end of life on 2026-10-31 (#604)
  • A reader raises its format's error, a ProvSerializationError, for a model rejection too, where 3.2.3 raised the model's error, or a bare ValueError or AttributeError. Write except ProvSerializationError around a read, or except prov.Error for both kinds (#653)
  • A Literal of xsd:boolean, xsd:decimal, xsd:double, xsd:float or an integer type compares by its value, so Literal("05", XSD_INT) == Literal("5", XSD_INT), and keeps a non-canonical text such as "05" as written, where 3.2.3 compared every type but xsd:decimal by its text (#527)
  • A record without an identifier no longer equals one with an identifier, and two documents are equal only when they hold the same bundles, where 3.2.3 found each pair equal from one side. hash() agrees with ==, and prov-compare exits by the same rule (#525)
  • unified() keeps each record once and drops a record equal to an earlier one, so two equal anonymous used statements become one and prov_to_graph() and prov_to_dot() draw one edge, where 3.2.3 kept both (#548)
  • get_records() with a class or a tuple of classes returns a list, so write next(iter(...)) to take the first record, where 3.2.3 returned a one-shot iterator (#491)
  • A bundle declares only the namespaces it binds itself, so a document read from PROV-JSON, PROV-JSONLD or PROV-XML no longer writes the document's prefix ex again inside each bundle that uses it, and bundle.get_registered_namespaces() lists the bundle's own declarations only (#449)
  • The PROV-N writer wraps a statement with an attribute block wider than 80 columns, one attribute per row, where 3.2.3 wrote one line. Pass width=None for one line, and give a get_provn() override a width parameter (#131)
  • A record holds one value of each PROV attribute, so assert one hadMember per entity, where 3.2.3 accepted several in one call. The PROV-XML reader reads a hadMember with several entities as one record per entity (#700)
  • A hadMember, alternateOf, specializationOf or mentionOf missing either party raises ProvMissingFormalAttribute, so assert both, and every reader skips such a statement with a ProvWarning, where 3.2.3 built the record (#710)
  • A Literal whose datatype is not a QualifiedName or None raises ProvValueError when it is built or unpickled, so pass the resolved name, where 3.2.3 accepted any object (#705)
  • prov_to_graph() flattens the document before it unifies it, so the records inside bundles become nodes and edges, where 3.2.3 drew the top-level records only. Pass it a document, not a bundle. Bundles that disagree about a shared identifier raise ProvUnificationError (#651)
  • prov-convert writes an output file whose extension names a format, such as out.xml, in that format, where 3.2.3 wrote PROV-JSON. Errors print one line, Ctrl-C exits 130, and -V prints the program name and version (#737)
  • The PROV-O reader raises ProvRDFException for an IRI typed as both an element and a relation, such as an element whose prov:type names a relation class, where 3.2.3 raised a bare StopIteration, lost a record or read the element (#743)
  • The PROV-O reader raises ProvRDFException for a relation that repeats a formal attribute, so write one relation per value, where 3.2.3 read one record per combination of the values, without a warning (GHSA-pp6h-3q6w-xr98)

New features

  • A Pygments lexer for PROV-N, registered as provn and prov-n, lets pygmentize, Sphinx, MkDocs and other Pygments-based tools highlight a provn code block. The pygments extra installs Pygments (#628)
  • prov-convert and prov-compare gain four features.
    • Both detect the input format from the file's extension or else its content, so a format flag is needed only to override it (#737)
    • prov-convert -w and -r, and prov-compare -r and -R, pass NAME=VALUE options to a format's writer or reader (#667)
    • prov-convert --color highlights the output with Pygments, which the pygments extra installs (#684)
    • Both have reference pages, and each GitHub release attaches their man pages (#83)

Fixes

  • The PROV-O, PROV-JSON and PROV-JSONLD readers register a default binding, such as Turtle's @prefix :, as the document's default namespace, where 3.2.3 wrote it as a nameless PROV-N prefix. The PROV-O reader no longer declares rdflib's own bindings (#654)
  • A Literal whose datatype is in a namespace nothing declared registers that namespace when it is asserted, so every writer declares it, where 3.2.3 wrote "1" %% zz:t with no prefix zz (#615)
  • The PROV-N reader parses an extensibility expression, prefix:name(...), under every profile and drops it with one ProvWarning, where the strict and default profiles of 3.2.3 raised. A stray { or } is a parse error that lenient skips (#520)
  • prov_to_dot() and plot() with use_labels=True draw an element that has no prov:label with its identifier once, where 3.2.3 drew it twice (#695)
  • A refused ProvDocument.add_bundle() leaves the bundle's identifier and namespaces as they were, where 3.2.3 could set the identifier and leave the bundle's namespaces linked to the document (#726)
  • prov-convert reads its input before it opens the output file, so an input that fails to parse leaves an existing output file as it was, where 3.2.3 emptied it (#742)
  • The PROV-JSONLD writer writes a qualified name under an attribute other than prov:type, prov:location and prov:role as a node reference, {"@id": "ex:x"}, where 3.2.3 wrote an xsd:QName value object. prov 3.2.2 and earlier cannot read the new form (#564)
  • PROV-N writes an xsd:QName literal value as 'ex:x' and PROV-O writes the IRI, where 3.2.3 wrote "ex:x" %% xsd:QName and "ex:x"^^xsd:QName (#238)

The 3.3.0 milestone lists every fixed issue.

Project

  • The wheel no longer holds prov.tests and its fixtures, which ship in the sdist (#728)
  • These warn DeprecationWarning, and 4.0 removes them:
    • ProvBundle.unified(). Unify the document with ProvDocument.unified() instead (#652)
    • prov_to_dot() and plot() given a bundle that is not a document, because 4.0 draws documents only (#652)
    • ProvBundle.document and the document argument of ProvBundle(). Keep a reference to the document and create a bundle with ProvDocument.bundle() (#650)
    • ProvRecord.bundle. Keep the document or bundle that made the record beside it (#734)
  • Identifier, QualifiedName, Namespace and Literal raise AttributeError when code assigns or deletes a stored field such as _value after construction, so a subclass that set one in its own __init__ now calls the base class's __init__, where 3.2.3 let the change through (#444)
  • sorted_attributes is no longer public API and stays importable (#742)