Skip to content

Commit fe1a8f8

Browse files
authored
fix: add __hash__ and __eq__ back to rdflib.paths.Path (#2292)
These methods were removed when `@total_ordering` was added, but `@total_ordering` does not add them, so removing them essentially removes functionality. This change adds the methods back and adds tests to ensure they work correctly. All path related tests are also moved into one file. - Closes <#2281>. - Closes <#2242>.
1 parent dd44ae1 commit fe1a8f8

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

rdflib/paths.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ def eval(
229229
) -> Iterator[Tuple["_SubjectType", "_ObjectType"]]:
230230
raise NotImplementedError()
231231

232+
def __hash__(self):
233+
return hash(repr(self))
234+
235+
def __eq__(self, other):
236+
return repr(self) == repr(other)
237+
232238
def __lt__(self, other: Any) -> bool:
233239
if not isinstance(other, (Path, Node)):
234240
raise TypeError(

test/test_mulpath_n3.py

Lines changed: 0 additions & 8 deletions
This file was deleted.

test/test_paths_n3.py renamed to test/test_path.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33

44
import pytest
55

6-
from rdflib import RDF, RDFS, Graph
6+
from rdflib import RDF, RDFS, Graph, URIRef
7+
from rdflib.namespace import DCAT, DCTERMS
78
from rdflib.paths import (
89
AlternativePath,
910
InvPath,
1011
MulPath,
1112
NegatedPath,
1213
OneOrMore,
14+
Path,
1315
SequencePath,
1416
ZeroOrMore,
1517
ZeroOrOne,
@@ -71,3 +73,45 @@ def test_paths_n3(
7173
logging.debug("path = %s", path)
7274
assert path.n3() == no_nsm
7375
assert path.n3(nsm) == with_nsm
76+
77+
78+
def test_mulpath_n3():
79+
uri = "http://example.com/foo"
80+
n3 = (URIRef(uri) * ZeroOrMore).n3()
81+
assert n3 == "<" + uri + ">*"
82+
83+
84+
@pytest.mark.parametrize(
85+
["lhs", "rhs"],
86+
[
87+
(DCTERMS.temporal / DCAT.endDate, DCTERMS.temporal / DCAT.endDate),
88+
(SequencePath(DCTERMS.temporal, DCAT.endDate), DCTERMS.temporal / DCAT.endDate),
89+
],
90+
)
91+
def test_eq(lhs: Path, rhs: Path) -> None:
92+
logging.debug("lhs = %s/%r, rhs = %s/%r", type(lhs), lhs, type(rhs), rhs)
93+
assert lhs == rhs
94+
95+
96+
@pytest.mark.parametrize(
97+
["lhs", "rhs"],
98+
[
99+
(DCTERMS.temporal / DCAT.endDate, DCTERMS.temporal / DCAT.endDate),
100+
(SequencePath(DCTERMS.temporal, DCAT.endDate), DCTERMS.temporal / DCAT.endDate),
101+
],
102+
)
103+
def test_hash(lhs: Path, rhs: Path) -> None:
104+
logging.debug("lhs = %s/%r, rhs = %s/%r", type(lhs), lhs, type(rhs), rhs)
105+
assert hash(lhs) == hash(rhs)
106+
107+
108+
@pytest.mark.parametrize(
109+
["insert_path", "check_path"],
110+
[
111+
(DCTERMS.temporal / DCAT.endDate, DCTERMS.temporal / DCAT.endDate),
112+
(SequencePath(DCTERMS.temporal, DCAT.endDate), DCTERMS.temporal / DCAT.endDate),
113+
],
114+
)
115+
def test_dict_key(insert_path: Path, check_path: Path) -> None:
116+
d = {insert_path: "foo"}
117+
assert d[check_path] == "foo"

0 commit comments

Comments
 (0)