diff options
-rw-r--r-- | .editorconfig | 2 | ||||
-rw-r--r-- | CHANGELOG.md | 21 | ||||
-rw-r--r-- | Taskfile.yml | 5 | ||||
-rw-r--r-- | rdflib/plugins/serializers/trig.py | 14 | ||||
-rw-r--r-- | test/data/roundtrip/bnode_refs.trig | 71 | ||||
-rw-r--r-- | test/test_roundtrip.py | 35 |
6 files changed, 116 insertions, 32 deletions
diff --git a/.editorconfig b/.editorconfig index a044bc5c..96bd27ac 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,6 +6,8 @@ root = true # Unix-style newlines with a newline ending every file [*] +indent_size = 4 +indent_style = space end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dc974e4..7ef9217b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -309,6 +309,27 @@ and will be removed for release. <!-- --> <!-- --> + +<!-- --> +<!-- --> +<!-- CHANGE BARRIER: START PR #2085 --> +<!-- --> +<!-- --> + +- Fixed serialization of BNodes in TriG. + The TriG serializer was only considering BNode references inside a single + graph and not counting the BNodes subjects as references when considering if a + BNode should be serialized as unlabeled blank nodes (i.e. `[ ]`), and as a + result it was serializing BNodes as unlabeled if they were in fact referencing + BNodes in other graphs. + [PR #2085](https://github.com/RDFLib/rdflib/pull/2085). + +<!-- --> +<!-- --> +<!-- CHANGE BARRIER: END PR #2085 --> +<!-- --> +<!-- --> + <!-- --> <!-- --> <!-- CHANGE BARRIER: START --> diff --git a/Taskfile.yml b/Taskfile.yml index c4028a45..f169a767 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -282,6 +282,11 @@ tasks: - task: install:flake8 - task: flake8 + cmd:rdfpipe: + desc: Run rdfpipe + cmds: + - cmd: "{{._PYTHON | shellQuote}} -m rdflib.tools.rdfpipe {{.CLI_ARGS}}" + _rimraf: # This task is a utility task for recursively removing directories, it is # similar to rm -rf but not identical and it should work wherever there is diff --git a/rdflib/plugins/serializers/trig.py b/rdflib/plugins/serializers/trig.py index fa9641d1..0fa62b71 100644 --- a/rdflib/plugins/serializers/trig.py +++ b/rdflib/plugins/serializers/trig.py @@ -3,7 +3,6 @@ Trig RDF graph serializer for RDFLib. See <http://www.w3.org/TR/trig/> for syntax specification. """ -from collections import defaultdict from typing import IO, TYPE_CHECKING, Optional, Union from rdflib.graph import ConjunctiveGraph, Graph @@ -37,17 +36,15 @@ class TrigSerializer(TurtleSerializer): for context in self.contexts: self.store = context self.getQName(context.identifier) - self._references = defaultdict(int) self._subjects = {} for triple in context: self.preprocessTriple(triple) - self._contexts[context] = ( - self.orderSubjects(), - self._subjects, - self._references, - ) + for subject in self._subjects.keys(): + self._references[subject] += 1 + + self._contexts[context] = (self.orderSubjects(), self._subjects) def reset(self): super(TrigSerializer, self).reset() @@ -77,11 +74,10 @@ class TrigSerializer(TurtleSerializer): self.startDocument() firstTime = True - for store, (ordered_subjects, subjects, ref) in self._contexts.items(): + for store, (ordered_subjects, subjects) in self._contexts.items(): if not ordered_subjects: continue - self._references = ref self._serialized = {} self.store = store self._subjects = subjects diff --git a/test/data/roundtrip/bnode_refs.trig b/test/data/roundtrip/bnode_refs.trig new file mode 100644 index 00000000..3c82e35f --- /dev/null +++ b/test/data/roundtrip/bnode_refs.trig @@ -0,0 +1,71 @@ +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix dc: <http://purl.org/dc/terms/> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix egdo: <http://example.org/> . + +{ + egdo:bob dc:publisher "Bob" . + egdo:alice dc:publisher "Alice" . +} + + +egdo:alice { + _:alice foaf:name "Alice"; + foaf:mbox <mailto:alice@work.example.org> . +} + +egdo:bob { + _:bob foaf:name "Bob"; + foaf:mbox <mailto:bob@oldcorp.example.org>; + foaf:knows _:alice . +} + + +egdo:blake { + [] foaf:name "Blake" ; + foaf:mbox <mailto:blake@oldcorp.example.org>; + foaf:knows [ + foaf:name "Taylor"; + foaf:mbox <mailto:taylor@work.example.org> + ] . +} + +egdo:austin { + _:austin foaf:name "Austin" ; + foaf:mbox <mailto:austin@oldcorp.example.org>; + foaf:knows _:carson. + + + _:carson foaf:name "Carson" ; + foaf:mbox <mailto:carson@oldcorp.example.org>; + foaf:knows _:austin. +} + +egdo:charlie { + _:charlie foaf:name "Charlie" ; + foaf:mbox <mailto:charlie@oldcorp.example.org>; + foaf:knows _:dylan; + foaf:knows _:greer. + + _:dylan foaf:name "Dylan" ; + foaf:mbox <mailto:dylan@oldcorp.example.org>; + foaf:knows _:charlie; + foaf:knows _:greer. + + _:greer foaf:name "Greer" ; + foaf:mbox <mailto:greer@oldcorp.example.org>; + foaf:knows _:charlie; + foaf:knows _:dylan. +} + +egdo:jaime { + _:jaime foaf:name "Jaime"; + foaf:mbox <mailto:jaime@work.example.org>; + foaf:knows _:keaton. +} + +egdo:kennedy { + _:kennedy foaf:name "Kennedy"; + foaf:mbox <mailto:kennedy@oldcorp.example.org>; + foaf:knows _:keaton . +} diff --git a/test/test_roundtrip.py b/test/test_roundtrip.py index 9c310a33..064fb9dc 100644 --- a/test/test_roundtrip.py +++ b/test/test_roundtrip.py @@ -144,28 +144,6 @@ XFAILS = { reason="results in invalid xml element name: <ns1:name(s)/>", raises=SAXParseException, ), - ("trig", "rdf11trig_eg2.trig"): pytest.mark.xfail( - reason=""" - Something is going wrong here with blank node serialization. In the second - graph below bob knows someone who does not exist, while in first he knows - someone that does exist and has the name Alice. - - AssertionError: in both: - (rdflib.term.BNode('cbb5eb12b5dcf688537b0298cce144c6dd68cf047530d0b4a455a8f31f314244fd'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/mbox'), rdflib.term.URIRef('mailto:alice@work.example.org')) - (rdflib.term.BNode('cbb5eb12b5dcf688537b0298cce144c6dd68cf047530d0b4a455a8f31f314244fd'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/name'), rdflib.term.Literal('Alice')) - (rdflib.term.URIRef('http://example.org/alice'), rdflib.term.URIRef('http://purl.org/dc/terms/publisher'), rdflib.term.Literal('Alice')) - (rdflib.term.URIRef('http://example.org/bob'), rdflib.term.URIRef('http://purl.org/dc/terms/publisher'), rdflib.term.Literal('Bob')) - only in first: - (rdflib.term.BNode('cb0'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.BNode('cbb5eb12b5dcf688537b0298cce144c6dd68cf047530d0b4a455a8f31f314244fd')) - (rdflib.term.BNode('cb0'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/mbox'), rdflib.term.URIRef('mailto:bob@oldcorp.example.org')) - (rdflib.term.BNode('cb0'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/name'), rdflib.term.Literal('Bob')) - only in second: - (rdflib.term.BNode('cb7be1d0397a49ddd4ae8aa96acc7b6135903c5f3fa5e47bf619c0e4b438aafcc1'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.BNode('cb0')) - (rdflib.term.BNode('cb7be1d0397a49ddd4ae8aa96acc7b6135903c5f3fa5e47bf619c0e4b438aafcc1'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/mbox'), rdflib.term.URIRef('mailto:bob@oldcorp.example.org')) - (rdflib.term.BNode('cb7be1d0397a49ddd4ae8aa96acc7b6135903c5f3fa5e47bf619c0e4b438aafcc1'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/name'), rdflib.term.Literal('Bob')) - """, - raises=AssertionError, - ), ("json-ld", "diverse_quads.trig"): pytest.mark.xfail( reason=""" jsonld serializer is dropping datatype: @@ -204,6 +182,10 @@ XFAILS = { "n3", "data/suites/w3c/n3/N3Tests/cwm_syntax/neg-single-quote.n3", ): pytest.mark.xfail(raises=BadSyntax, reason="no support for single quotes"), + ("json-ld", "bnode_refs.trig"): pytest.mark.xfail( + reason="a whole bunch of triples with bnode as subject is not in the reconstituted graph", + raises=AssertionError, + ), } # This is for files which can only be represented properly in one format @@ -253,7 +235,13 @@ def roundtrip( s = g1.serialize(format=testfmt) if logger.isEnabledFor(logging.DEBUG): - logger.debug("source = %s, serailized = \n%s", source, s) + logger.debug( + "infmt = %s, testfmt = %s, source = %s, serailized = \n%s", + infmt, + testfmt, + source, + s, + ) g2 = graph_type() if same_public_id: @@ -525,6 +513,7 @@ EXTRA_FILES = [ (TEST_DATA_DIR / "variants" / "diverse_triples.nt", "ntriples"), (TEST_DATA_DIR / "variants" / "diverse_quads.nq", "nquads"), (TEST_DATA_DIR / "variants" / "diverse_quads.trig", "trig"), + (TEST_DATA_DIR / "roundtrip" / "bnode_refs.trig", "trig"), (TEST_DATA_DIR / "example-lots_of_graphs.n3", "n3"), (TEST_DATA_DIR / "issue156.n3", "n3"), ] |