Skip to content
12 changes: 8 additions & 4 deletions rdflib/plugins/parsers/notation3.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,10 @@ def unicodeExpand(m: Match) -> str:
langcode = re.compile(r"[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*")


class sfloat(str):
""" don't normalize raw XSD.double string representation """


class SinkParser:
def __init__(
self,
Expand Down Expand Up @@ -1530,7 +1534,7 @@ def nodeOrLiteral(self, argstr: str, i: int, res: MutableSequence[Any]) -> int:
m = exponent_syntax.match(argstr, i)
if m:
j = m.end()
res.append(float(argstr[i:j]))
res.append(sfloat(argstr[i:j]))
return j

m = decimal_syntax.match(argstr, i)
Expand Down Expand Up @@ -1921,15 +1925,15 @@ def normalise(self, f: Formula | Graph | None, n: int) -> Literal: ...
def normalise(self, f: Formula | Graph | None, n: Decimal) -> Literal: ...

@overload
def normalise(self, f: Formula | Graph | None, n: float) -> Literal: ...
def normalise(self, f: Formula | Graph | None, n: sfloat) -> Literal: ...

@overload
def normalise(self, f: Formula | Graph | None, n: Node) -> Node: ...

def normalise(
self,
f: Formula | Graph | None,
n: Union[tuple[int, str], bool, int, Decimal, float, Node, _AnyT],
n: Union[tuple[int, str], bool, int, Decimal, sfloat, Node, _AnyT],
) -> Union[URIRef, Literal, BNode, Node, _AnyT]:
if isinstance(n, tuple):
return URIRef(str(n[1]))
Expand All @@ -1949,7 +1953,7 @@ def normalise(
s = Literal(value, datatype=DECIMAL_DATATYPE)
return s

if isinstance(n, float):
if isinstance(n, sfloat):
s = Literal(str(n), datatype=DOUBLE_DATATYPE)
return s

Expand Down
26 changes: 26 additions & 0 deletions test/test_n3.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,32 @@ def test_empty_prefix(self):
g2
), "Document with declared empty prefix must match default #"

def test_float_no_norm(self):
import rdflib
_ps = rdflib.NORMALIZE_LITERALS
try:
bads = []
for norm_lit in (True, False):
rdflib.NORMALIZE_LITERALS = norm_lit
g1 = Graph()
g1.parse(data=":a :b 1e10, 1e0 .", format="n3")
strep = [str(o) for o in g1.objects()]
if norm_lit:
if '1e10' not in strep and '1e0' not in strep:
pass
else:
bads.append(('NOT normalized when should have been', strep))
else:
if '1e10' in strep and '1e0' in strep:
pass
else:
bads.append(('normalized when it should NOT have been', strep))

finally:
rdflib.NORMALIZE_LITERALS = _ps

assert not bads, bads


class TestRegularExpressions:
def test_exponents(self):
Expand Down
Loading