Skip to content

Commit 49afac8

Browse files
edmondchucbulricht
andauthored
fix: skip prefix generation for predicates corresponding to base namespace (#3244)
* skip prefix generation for predicates corresponding to base namespace * fix: skip prefix generation for predicates corresponding to the base namespace. This applies to both turtle and longturtle Also added fix to escape brackets in pnames to longturtle. --------- Co-authored-by: bulricht <108867473+bulricht@users.noreply.github.com>
1 parent 1964642 commit 49afac8

File tree

3 files changed

+60
-7
lines changed

3 files changed

+60
-7
lines changed

rdflib/plugins/serializers/longturtle.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
from rdflib.compare import to_canonical_graph
2424
from rdflib.exceptions import Error
25-
from rdflib.graph import Graph
25+
from rdflib.graph import Graph, _TripleType
2626
from rdflib.namespace import RDF
2727
from rdflib.term import BNode, Literal, URIRef
2828

@@ -149,11 +149,20 @@ def serialize(
149149

150150
self.base = None
151151

152-
def preprocessTriple(self, triple):
152+
def preprocessTriple(self, triple: _TripleType) -> None:
153153
super(LongTurtleSerializer, self).preprocessTriple(triple)
154154
for i, node in enumerate(triple):
155-
if node in self.keywords:
156-
continue
155+
if i == VERB:
156+
if node in self.keywords:
157+
# predicate is a keyword
158+
continue
159+
if (
160+
self.base is not None
161+
and isinstance(node, URIRef)
162+
and node.startswith(self.base)
163+
):
164+
# predicate corresponds to base namespace
165+
continue
157166
# Don't use generated prefixes for subjects and objects
158167
self.getQName(node, gen_prefix=(i == VERB))
159168
if isinstance(node, Literal) and node.datatype:
@@ -180,6 +189,8 @@ def getQName(self, uri, gen_prefix=True):
180189

181190
prefix, namespace, local = parts
182191

192+
local = local.replace(r"(", r"\(").replace(r")", r"\)")
193+
183194
# QName cannot end with .
184195
if local.endswith("."):
185196
return None

rdflib/plugins/serializers/turtle.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,17 @@ def serialize(
263263
def preprocessTriple(self, triple: _TripleType) -> None:
264264
super(TurtleSerializer, self).preprocessTriple(triple)
265265
for i, node in enumerate(triple):
266-
if i == VERB and node in self.keywords:
267-
# predicate is a keyword
268-
continue
266+
if i == VERB:
267+
if node in self.keywords:
268+
# predicate is a keyword
269+
continue
270+
if (
271+
self.base is not None
272+
and isinstance(node, URIRef)
273+
and node.startswith(self.base)
274+
):
275+
# predicate corresponds to base namespace
276+
continue
269277
# Don't use generated prefixes for subjects and objects
270278
self.getQName(node, gen_prefix=(i == VERB))
271279
if isinstance(node, Literal) and node.datatype:
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from rdflib import Graph, Namespace, URIRef
2+
3+
# https://github.com/RDFLib/rdflib/issues/3237
4+
# Test that the ns1 prefix is not generated when the base is set.
5+
mns = Namespace("http://my-namespace.net/")
6+
7+
8+
def test_turtle():
9+
g = Graph(base="http://my-base.net/")
10+
g.add((mns.foo, URIRef("http://my-base.net/my-predicate"), mns.bar))
11+
result = g.serialize(format="text/turtle")
12+
assert (
13+
result
14+
== """@base <http://my-base.net/> .
15+
16+
<http://my-namespace.net/foo> <my-predicate> <http://my-namespace.net/bar> .
17+
18+
"""
19+
)
20+
21+
22+
def test_longturtle():
23+
g = Graph(base="http://my-base.net/")
24+
g.add((mns.foo, URIRef("http://my-base.net/my-predicate"), mns.bar))
25+
result = g.serialize(format="longturtle", canon=True)
26+
assert (
27+
result
28+
== """BASE <http://my-base.net/>
29+
30+
<http://my-namespace.net/foo>
31+
<my-predicate> <http://my-namespace.net/bar> ;
32+
.
33+
"""
34+
), print(result)

0 commit comments

Comments
 (0)