Skip to content

Commit 9c73581

Browse files
authored
fix: formatting of SequencePath and AlternativePath (#2504)
These path types were formatted without parentheses even if they contained multiple elements, resulting in string representations that did not accurately represent the path. This change fixes the formatting so that the string representations are enclosed in parentheses when necessary. - Fixes <#2503>.
1 parent bd797ac commit 9c73581

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

rdflib/paths.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,15 @@
213213
ZeroOrOne = "?"
214214

215215

216+
def _n3(
217+
arg: Union["URIRef", "Path"], namespace_manager: Optional["NamespaceManager"] = None
218+
) -> str:
219+
# type error: Item "Path" of "Union[Path, URIRef]" has no attribute "n3" [union-attr]
220+
if isinstance(arg, (SequencePath, AlternativePath)) and len(arg.args) > 1:
221+
return "(%s)" % arg.n3(namespace_manager)
222+
return arg.n3(namespace_manager) # type: ignore[union-attr]
223+
224+
216225
@total_ordering
217226
class Path:
218227
__or__: Callable[["Path", Union["URIRef", "Path"]], "AlternativePath"]
@@ -260,8 +269,7 @@ def __repr__(self) -> str:
260269
return "Path(~%s)" % (self.arg,)
261270

262271
def n3(self, namespace_manager: Optional["NamespaceManager"] = None) -> str:
263-
# type error: Item "Path" of "Union[Path, URIRef]" has no attribute "n3" [union-attr]
264-
return "^%s" % self.arg.n3(namespace_manager) # type: ignore[union-attr]
272+
return "^%s" % _n3(self.arg, namespace_manager)
265273

266274

267275
class SequencePath(Path):
@@ -318,8 +326,7 @@ def __repr__(self) -> str:
318326
return "Path(%s)" % " / ".join(str(x) for x in self.args)
319327

320328
def n3(self, namespace_manager: Optional["NamespaceManager"] = None) -> str:
321-
# type error: Item "Path" of "Union[Path, URIRef]" has no attribute "n3" [union-attr]
322-
return "/".join(a.n3(namespace_manager) for a in self.args) # type: ignore[union-attr]
329+
return "/".join(_n3(a, namespace_manager) for a in self.args)
323330

324331

325332
class AlternativePath(Path):
@@ -345,8 +352,7 @@ def __repr__(self) -> str:
345352
return "Path(%s)" % " | ".join(str(x) for x in self.args)
346353

347354
def n3(self, namespace_manager: Optional["NamespaceManager"] = None) -> str:
348-
# type error: Item "Path" of "Union[Path, URIRef]" has no attribute "n3" [union-attr]
349-
return "|".join(a.n3(namespace_manager) for a in self.args) # type: ignore[union-attr]
355+
return "|".join(_n3(a, namespace_manager) for a in self.args)
350356

351357

352358
class MulPath(Path):
@@ -470,8 +476,7 @@ def __repr__(self) -> str:
470476
return "Path(%s%s)" % (self.path, self.mod)
471477

472478
def n3(self, namespace_manager: Optional["NamespaceManager"] = None) -> str:
473-
# type error: Item "Path" of "Union[Path, URIRef]" has no attribute "n3" [union-attr]
474-
return "%s%s" % (self.path.n3(namespace_manager), self.mod) # type: ignore[union-attr]
479+
return "%s%s" % (_n3(self.path, namespace_manager), self.mod)
475480

476481

477482
class NegatedPath(Path):
@@ -505,8 +510,7 @@ def __repr__(self) -> str:
505510
return "Path(! %s)" % ",".join(str(x) for x in self.args)
506511

507512
def n3(self, namespace_manager: Optional["NamespaceManager"] = None) -> str:
508-
# type error: Item "Path" of "Union[Path, URIRef]" has no attribute "n3" [union-attr]
509-
return "!(%s)" % ("|".join(arg.n3(namespace_manager) for arg in self.args)) # type: ignore[union-attr]
513+
return "!(%s)" % ("|".join(_n3(arg, namespace_manager) for arg in self.args))
510514

511515

512516
class PathList(list):

test/test_path.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,40 @@
5454
"rdfs:subClassOf?",
5555
),
5656
(
57-
RDF.type / RDFS.subClassOf * "*",
57+
RDF.type / MulPath(RDFS.subClassOf, "*"),
5858
f"<{RDF.type}>/<{RDFS.subClassOf}>*",
5959
"rdf:type/rdfs:subClassOf*",
6060
),
61+
(
62+
RDF.type / ((SequencePath(RDFS.subClassOf)) * "*"),
63+
f"<{RDF.type}>/<{RDFS.subClassOf}>*",
64+
"rdf:type/rdfs:subClassOf*",
65+
),
66+
(
67+
RDF.type / RDFS.subClassOf * "*",
68+
f"(<{RDF.type}>/<{RDFS.subClassOf}>)*",
69+
"(rdf:type/rdfs:subClassOf)*",
70+
),
6171
(
6272
-(RDF.type | RDFS.subClassOf),
6373
f"!(<{RDF.type}>|<{RDFS.subClassOf}>)",
6474
"!(rdf:type|rdfs:subClassOf)",
6575
),
76+
(
77+
-(RDF.type | ((SequencePath(RDFS.subClassOf)) * "*")),
78+
f"!(<{RDF.type}>|<{RDFS.subClassOf}>*)",
79+
"!(rdf:type|rdfs:subClassOf*)",
80+
),
81+
(
82+
SequencePath(RDFS.subClassOf),
83+
f"<{RDFS.subClassOf}>",
84+
"rdfs:subClassOf",
85+
),
86+
(
87+
AlternativePath(RDFS.subClassOf),
88+
f"<{RDFS.subClassOf}>",
89+
"rdfs:subClassOf",
90+
),
6691
],
6792
)
6893
def test_paths_n3(

0 commit comments

Comments
 (0)