Skip to content

Commit 61e384d

Browse files
authored
Merge pull request #4525 from Liam-DeVoe/threading-wrapped-strategy
Fix a race condition in `DeferredStrategy.wrapped_strategy`
2 parents 513be56 + 609cfe7 commit 61e384d

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

hypothesis-python/RELEASE.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
RELEASE_TYPE: patch
2+
3+
Fixes a race condition under threading when using |st.deferred|.

hypothesis-python/src/hypothesis/strategies/_internal/deferred.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,18 @@ def __init__(self, definition: Callable[[], SearchStrategy[Ex]]):
3535

3636
@property
3737
def wrapped_strategy(self) -> SearchStrategy[Ex]:
38+
# we assign this before entering the condition to avoid a race condition
39+
# under threading. See issue #4523.
40+
definition = self.__definition
3841
if self.__wrapped_strategy is None:
3942
check_sideeffect_during_initialization("deferred evaluation of {!r}", self)
4043

41-
if not inspect.isfunction(self.__definition):
44+
if not inspect.isfunction(definition):
4245
raise InvalidArgument(
43-
f"Expected definition to be a function but got {self.__definition!r} "
44-
f"of type {type(self.__definition).__name__} instead."
46+
f"Expected definition to be a function but got {definition!r} "
47+
f"of type {type(definition).__name__} instead."
4548
)
46-
result = self.__definition()
49+
result = definition()
4750
if result is self:
4851
raise InvalidArgument("Cannot define a deferred strategy to be itself")
4952
check_strategy(result, "definition()")

hypothesis-python/tests/conjecture/test_shrinker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ def shrinker(data: ConjectureData):
625625
)
626626
assert (
627627
# pytest.approx for differences in floating-point summations
628-
pytest.approx(shrinker.choices[0] + shrinker.choices[1])
628+
pytest.approx(shrinker.choices[0] + shrinker.choices[1], rel=0.001)
629629
== node1.value + node2.value
630630
)
631631

0 commit comments

Comments
 (0)