Skip to content

Commit 0a1d5f1

Browse files
dimblebyradoering
authored andcommitted
make constraints hashable
1 parent 6c202be commit 0a1d5f1

File tree

6 files changed

+41
-0
lines changed

6 files changed

+41
-0
lines changed

src/poetry/core/packages/constraints/any_constraint.py

+3
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,6 @@ def __str__(self) -> str:
3737

3838
def __eq__(self, other: object) -> bool:
3939
return isinstance(other, BaseConstraint) and other.is_any()
40+
41+
def __hash__(self) -> int:
42+
return hash("any")

src/poetry/core/packages/constraints/base_constraint.py

+3
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@ def is_empty(self) -> bool:
2929
def __repr__(self) -> str:
3030
return f"<{self.__class__.__name__} {str(self)}>"
3131

32+
def __hash__(self) -> int:
33+
raise NotImplementedError()
34+
3235
def __eq__(self, other: object) -> bool:
3336
raise NotImplementedError()

src/poetry/core/packages/constraints/empty_constraint.py

+3
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,8 @@ def __eq__(self, other: object) -> bool:
3333

3434
return other.is_empty()
3535

36+
def __hash__(self) -> int:
37+
return hash("empty")
38+
3639
def __str__(self) -> str:
3740
return ""

src/poetry/core/packages/constraints/multi_constraint.py

+7
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ def __eq__(self, other: object) -> bool:
8181

8282
return set(self._constraints) == set(other._constraints)
8383

84+
def __hash__(self) -> int:
85+
h = hash("multi")
86+
for constraint in self._constraints:
87+
h ^= hash(constraint)
88+
89+
return h
90+
8491
def __str__(self) -> str:
8592
constraints = []
8693
for constraint in self._constraints:

src/poetry/core/packages/constraints/union_constraint.py

+7
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ def __eq__(self, other: object) -> bool:
133133

134134
return set(self._constraints) == set(other._constraints)
135135

136+
def __hash__(self) -> int:
137+
h = hash("union")
138+
for constraint in self._constraints:
139+
h ^= hash(constraint)
140+
141+
return h
142+
136143
def __str__(self) -> str:
137144
constraints = []
138145
for constraint in self._constraints:

tests/packages/constraints/test_constraint.py

+18
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,21 @@ def test_difference() -> None:
167167

168168
assert c.difference(Constraint("win32")).is_empty()
169169
assert c.difference(Constraint("linux")) == c
170+
171+
172+
@pytest.mark.parametrize(
173+
"constraint",
174+
[
175+
(EmptyConstraint()),
176+
(AnyConstraint()),
177+
(Constraint("win32")),
178+
(UnionConstraint(Constraint("win32"), Constraint("linux"))),
179+
(MultiConstraint(Constraint("win32", "!="), Constraint("linux", "!="))),
180+
],
181+
)
182+
def test_constraints_are_hashable(
183+
constraint: BaseConstraint,
184+
) -> None:
185+
# We're just testing that constraints are hashable, there's nothing much to say
186+
# about the result.
187+
hash(constraint)

0 commit comments

Comments
 (0)