Found by the Task 13 Hypothesis property-based round-trip tests (src/prov/tests/test_property_roundtrip.py).
A Python float attribute value is typed by prov as xsd:float (single precision). The RDF serializer canonicalises xsd:float to a short decimal literal, so a value whose exact decimal expansion is longer than that short form comes back changed after an RDF round trip. PROV-JSON and PROV-XML preserve the full repr and are unaffected.
Reproduction:
import io, struct
from prov.model import ProvDocument
def rt(d, fmt):
s = io.BytesIO(); d.serialize(destination=s, format=fmt, indent=4); s.seek(0)
return ProvDocument.deserialize(source=s, format=fmt)
def f32(x): # nearest float32, as a Python float
return struct.unpack("f", struct.pack("f", x))[0]
for v in [f32(0.1), f32(1.7), 0.125, -12.5]:
d = ProvDocument(); d.add_namespace("ex", "http://example.org/")
d.entity("ex:e0", {"ex:k": v})
print(f"{v!r:24} rdf:{rt(d,rdf)==d}")
# 0.10000000149011612 rdf:False (0.1 -> "1e-01" -> 0.1 as float64)
# 1.7000000476837158 rdf:False
# 0.125 rdf:True (dyadic, exact short decimal)
# -12.5 rdf:True
Values that are exactly float32-representable and have a short exact decimal (dyadic rationals) survive; others do not. Related to #77 (xsd:decimal fidelity loss through RDF), but this is the xsd:float path.
Status: deferred to 3.0.0 under the 2.x output freeze. Excluded from Hypothesis generation by restricting float values to eighth-step dyadic rationals of modest magnitude (src/prov/tests/strategies.py), commented pointing here. No behaviour change made in 2.x.
Found by the Task 13 Hypothesis property-based round-trip tests (
src/prov/tests/test_property_roundtrip.py).A Python
floatattribute value is typed byprovasxsd:float(single precision). The RDF serializer canonicalisesxsd:floatto a short decimal literal, so a value whose exact decimal expansion is longer than that short form comes back changed after an RDF round trip. PROV-JSON and PROV-XML preserve the fullreprand are unaffected.Reproduction:
Values that are exactly float32-representable and have a short exact decimal (dyadic rationals) survive; others do not. Related to #77 (xsd:decimal fidelity loss through RDF), but this is the
xsd:floatpath.Status: deferred to 3.0.0 under the 2.x output freeze. Excluded from Hypothesis generation by restricting float values to eighth-step dyadic rationals of modest magnitude (
src/prov/tests/strategies.py), commented pointing here. No behaviour change made in 2.x.