Skip to content

Commit 158514e

Browse files
author
Sylvain MARIE
committed
LazyValue, LazyTuple and LazyTupleItem are now hashable. This increases compatibility with plugins hashing the parameter values, such as pytest-steps. See smarie/python-pytest-steps#41 . Fixes #199
1 parent 4273d85 commit 158514e

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

pytest_cases/common_pytest_lazy_values.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ def __init__(self,
164164
self.cached_value_context = None
165165
self.cached_value = None
166166

167+
def __hash__(self):
168+
"""Provide a minimal hash representing the class, valuegetter, id and marks"""
169+
return hash((self.__class__, self.valuegetter, self._id, self._marks))
170+
167171
def get_marks(self,
168172
as_decorators=False # type: bool
169173
):
@@ -268,6 +272,10 @@ def __init__(self,
268272
self.host = host
269273
self.item = item
270274

275+
def __hash__(self):
276+
"""Provide a minimal hash representing the class, host and item number"""
277+
return hash((self.__class__, self.host, self.item))
278+
271279
def __repr__(self):
272280
"""Override the inherited method to avoid infinite recursion"""
273281
vals_to_display = (
@@ -321,6 +329,10 @@ def __init__(self,
321329
self._lazyvalue = valueref
322330
self.theoretical_size = theoretical_size
323331

332+
def __hash__(self):
333+
"""Provide a minimal hash representing the class, lazy value, and theoretical size"""
334+
return hash((self.__class__, self._lazyvalue, self.theoretical_size))
335+
324336
def __len__(self):
325337
return self.theoretical_size
326338

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from pytest_steps import test_steps
2+
3+
from pytest_cases import parametrize, fixture, lazy_value
4+
5+
6+
@fixture
7+
def fix():
8+
return 1
9+
10+
11+
@fixture
12+
def fixtuple():
13+
return 1, 2
14+
15+
16+
def foo():
17+
return 2
18+
19+
20+
def footuple():
21+
return 3, 4
22+
23+
24+
@test_steps("step1", "step2")
25+
@parametrize("b,c", [fixtuple, lazy_value(footuple)])
26+
@parametrize(a=[fix, lazy_value(foo)])
27+
def test_steps_and_cases(a, b, c):
28+
29+
print("step 1")
30+
assert a in (1, 2)
31+
assert (b, c) in ((1, 2), (3, 4))
32+
yield
33+
34+
print("step 2")
35+
assert a in (1, 2)
36+
assert (b, c) in ((1, 2), (3, 4))
37+
yield
38+
39+
40+
@test_steps("step1", "step2")
41+
@parametrize("b,c", [lazy_value(footuple)]) # no fixture ref: only lazy
42+
@parametrize(a=[lazy_value(foo)]) # no fixture ref: only lazy
43+
def test_steps_and_cases2(a, b, c):
44+
45+
print("step 1")
46+
assert a in (1, 2)
47+
assert (b, c) in ((1, 2), (3, 4))
48+
yield
49+
50+
print("step 2")
51+
assert a in (1, 2)
52+
assert (b, c) in ((1, 2), (3, 4))
53+
yield

pytest_cases/tests/pytest_extension/parametrize_plus/test_lazy_value_low_level.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import pytest
66

77
from pytest_cases.common_pytest_marks import PYTEST53_OR_GREATER
8-
from pytest_cases.common_pytest_lazy_values import LazyValue, LazyTuple
8+
from pytest_cases.common_pytest_lazy_values import LazyValue, LazyTuple, LazyTupleItem
99

1010
from pytest_cases import lazy_value
1111
from pytest_cases.common_pytest import mini_idval
@@ -30,6 +30,9 @@ def foo():
3030

3131
a = lazy_value(foo)
3232

33+
# test that it is hashable
34+
assert hash(a) == hash((LazyValue, foo, None, ()))
35+
3336
# test that ids will be correctly generated even on old pytest
3437
assert mini_idval(a, 'a', 1) == 'foo'
3538
assert 'LazyValue' in repr(a)
@@ -67,9 +70,15 @@ def __init__(self):
6770
_called = 0 if not src.has_cached_value() else 1
6871
at = src.as_lazy_tuple(2)
6972

73+
# test that it is hashable
74+
assert hash(at) == hash((LazyTuple, src, 2))
75+
7076
# test when the tuple is unpacked into several parameters
7177
if not at.has_cached_value():
7278
for i, a in enumerate(at):
79+
# test that it is hashable
80+
assert hash(a) == hash((LazyTupleItem, at, i))
81+
7382
# test that ids will be correctly generated even on old pytest
7483
assert mini_idval(a, 'a', 1) == 'foo[%s]' % i
7584
assert ('LazyTupleItem(item=%s' % i) in repr(a)

0 commit comments

Comments
 (0)