Skip to content

Commit

Permalink
Fix some flaky tests and fix a longstanding bug in recursive (#2156)
Browse files Browse the repository at this point in the history
Fix some flaky tests and fix a longstanding bug in recursive
  • Loading branch information
Zac-HD committed Oct 30, 2019
2 parents 8898d30 + 3400a02 commit 4faf3ae
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 4 deletions.
6 changes: 6 additions & 0 deletions hypothesis-python/RELEASE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
RELEASE_TYPE: patch

This release fixes a bug in :func:`~hypothesis.strategies.recursive` which would
have meant that in practice ``max_leaves`` was treated as if it was lower than
it actually is - specifically it would be capped at the largest power of two
smaller than it. It is now handled correctly.
5 changes: 4 additions & 1 deletion hypothesis-python/src/hypothesis/searchstrategy/recursive.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def __init__(self, strategy):
self.marker = 0
self.currently_capped = False

def __repr__(self):
return "LimitedStrategy(%r)" % (self.base_strategy,)

def do_validate(self):
self.base_strategy.validate()

Expand Down Expand Up @@ -65,7 +68,7 @@ def __init__(self, base, extend, max_leaves):
self.extend = extend

strategies = [self.limited_base, self.extend(self.limited_base)]
while 2 ** len(strategies) <= max_leaves:
while 2 ** (len(strategies) - 1) <= max_leaves:
strategies.append(extend(OneOfStrategy(tuple(strategies))))
self.strategy = OneOfStrategy(strategies)

Expand Down
25 changes: 24 additions & 1 deletion hypothesis-python/tests/cover/test_recursive.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import hypothesis.strategies as st
from hypothesis import given
from hypothesis.errors import InvalidArgument
from tests.common.debug import minimal
from tests.common.debug import find_any, minimal


@given(st.recursive(st.booleans(), st.lists, max_leaves=10))
Expand Down Expand Up @@ -56,6 +56,29 @@ def test_recursive_call_validates_base_is_strategy():
x.example()


def test_can_find_exactly_max_leaves():
strat = st.recursive(st.none(), lambda x: st.tuples(x, x), max_leaves=5)

def enough_leaves(t):
print(t)
count = 0
stack = [t]
while stack:
s = stack.pop()
if s is None:
count += 1
else:
stack.extend(s)
return count >= 5

find_any(strat, enough_leaves)


@given(st.recursive(st.none(), lambda x: st.tuples(x, x), max_leaves=1))
def test_can_exclude_branching_with_max_leaves(t):
assert t is None


@given(st.recursive(st.none(), lambda x: st.one_of(x, x)))
def test_issue_1502_regression(s):
pass
6 changes: 6 additions & 0 deletions hypothesis-python/tests/cover/test_reproduce_failure.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ def test_decoding_may_fail(t):
assert False, "decoding failed with %r, not InvalidArgument" % (e,)


def test_invalid_base_64_gives_invalid_argument():
with pytest.raises(InvalidArgument) as exc_info:
decode_failure(b"/")
assert "Invalid base64 encoded" in exc_info.value.args[0]


def test_reproduces_the_failure():
b = b"hello world"
n = len(b)
Expand Down
5 changes: 3 additions & 2 deletions hypothesis-python/tests/quality/test_integers.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ def problems(draw):
d = ConjectureData.for_buffer(buf)
k = d.draw(st.integers())
stop = d.draw_bits(8)
if stop > 0 and k > 0:
return (draw(st.integers(0, k - 1)), hbytes(d.buffer))
except (StopTest, IndexError):
pass
else:
if stop > 0 and k > 0:
return (draw(st.integers(0, k - 1)), hbytes(d.buffer))


@example((2, b"\x00\x00\n\x01"))
Expand Down

0 comments on commit 4faf3ae

Please sign in to comment.