diff --git a/tests/backends/test_rdflib.py b/tests/backends/test_rdflib.py new file mode 100644 index 00000000..b9915b2b --- /dev/null +++ b/tests/backends/test_rdflib.py @@ -0,0 +1,27 @@ +"""Test rdflib backend. + +Most of the rdflib backend is already tested in tests/test_triplestore.py. +""" +import pytest + +from tripper import Literal, Triplestore + +rdflib = pytest.importorskip("rdflib") + + +# Test for issue #162: Literals are lost when listing triples with rdflib +ts = Triplestore("rdflib") +ts.parse( + format="turtle", + data=( + " " + '"abc"^^ .' + ), +) +assert list(ts.triples()) == [ + ( + "http://ex#s", + "http://ex#p", + Literal("abc", datatype="http://www.w3.org/2001/XMLSchema#string"), + ) +] diff --git a/tripper/mappings/mappings.py b/tripper/mappings/mappings.py index 8cdf9978..6c7b2373 100644 --- a/tripper/mappings/mappings.py +++ b/tripper/mappings/mappings.py @@ -122,7 +122,7 @@ def __repr__(self): args.append(f", property_iri={self.property_iri}") if self.cost: args.append(f", cost={self.cost}") - return f"Value({self._value}{''.join(args)})" + return f"Value({self._value!r}{''.join(args)})" def get_value(self, unit=None, magnitude=False, quantity=None) -> "Any": """Returns the evaluated value of given input route number. diff --git a/tripper/utils.py b/tripper/utils.py index 146ff7dc..523cf1b5 100644 --- a/tripper/utils.py +++ b/tripper/utils.py @@ -128,10 +128,18 @@ def parse_literal(literal: "Any") -> "Literal": if isinstance(literal, Literal): return literal + if hasattr(literal, "lang"): + lang = literal.lang + elif hasattr(literal, "language"): + lang = literal.language + + if not lang and hasattr(literal, "datatype"): + datatype = str(literal.datatype) + # This will handle rdflib literals correctly and probably most other # literal representations as well. if hasattr(literal, "value"): - return Literal(literal.value) + return Literal(literal.value, lang=lang, datatype=datatype) if not isinstance(literal, str): if isinstance(literal, tuple(Literal.datatypes)):