Skip to content

Commit

Permalink
fix not clamping -0.0 to 0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
tybug committed Feb 2, 2025
1 parent 8c7c254 commit 582f306
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 15 deletions.
3 changes: 3 additions & 0 deletions hypothesis-python/RELEASE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
RELEASE_TYPE: patch

Fixes a recently-introduced bug where we might have generated ``-0.0`` for ``st.floats(min_value=0.0)``, which is unsound.
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,9 @@ def draw_float(
clamped = result # pragma: no cover
else:
clamped = clamper(result)
if clamped != result and not (math.isnan(result) and allow_nan):
if float_to_int(clamped) != float_to_int(result) and not (
math.isnan(result) and allow_nan
):
result = clamped
else:
result = nasty_floats[i - 1]
Expand Down
30 changes: 16 additions & 14 deletions hypothesis-python/tests/conjecture/test_provider_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@
from hypothesis.internal.conjecture.providers import BytestringProvider
from hypothesis.internal.intervalsets import IntervalSet

from tests.conjecture.common import float_kw, integer_kw, ir_types_and_kwargs, string_kw
from tests.conjecture.common import (
float_kw,
integer_kw,
ir_types_and_kwargs,
nodes,
string_kw,
)


@example(b"\x00" * 100, [("integer", integer_kw())])
Expand Down Expand Up @@ -50,20 +56,16 @@ def test_provider_contract_bytestring(bytestring, ir_type_and_kwargs):
except StopTest:
return

# ir_value_permitted is currently restricted to what *could* be generated
# by the buffer. once we're fully on the TCS, we can drop this restriction.
# until then, the BytestringProvider can theoretically generate values
# that aren't forcable to a buffer - but this requires an enormous shrink_towards
# value and is such an edge case that I'm just going to bank on nobody hitting
# it before we're off the bytestring.
integer_edge_case = (
ir_type == "integer"
and kwargs["shrink_towards"] is not None
and kwargs["shrink_towards"].bit_length() > 100
)
assert choice_permitted(value, kwargs) or integer_edge_case

assert choice_permitted(value, kwargs)
kwargs["forced"] = choice_from_index(0, ir_type, kwargs)
assert choice_equal(
kwargs["forced"], getattr(data, f"draw_{ir_type}")(**kwargs)
)


@given(st.lists(nodes()), st.randoms())
def test_provider_contract_hypothesis(nodes, random):
data = ConjectureData(random=random)
for node in nodes:
value = getattr(data, f"draw_{node.ir_type}")(**node.kwargs)
assert choice_permitted(value, node.kwargs)

0 comments on commit 582f306

Please sign in to comment.