Skip to content

Commit 3356b67

Browse files
committed
move more functions to choice.py
1 parent da9a59c commit 3356b67

File tree

9 files changed

+81
-71
lines changed

9 files changed

+81
-71
lines changed

hypothesis-python/src/hypothesis/internal/conjecture/choice.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from hypothesis.errors import ChoiceTooLarge
2525
from hypothesis.internal.conjecture.floats import float_to_lex, lex_to_float
2626
from hypothesis.internal.conjecture.utils import identity
27-
from hypothesis.internal.floats import make_float_clamper, sign_aware_lte
27+
from hypothesis.internal.floats import float_to_int, make_float_clamper, sign_aware_lte
2828
from hypothesis.internal.intervalsets import IntervalSet
2929

3030
T = TypeVar("T")
@@ -454,3 +454,42 @@ def choice_permitted(choice: ChoiceT, kwargs: ChoiceKwargsT) -> bool:
454454
return True
455455
else:
456456
raise NotImplementedError(f"unhandled type {type(choice)} with value {choice}")
457+
458+
459+
def choices_key(choices: Sequence[ChoiceT]) -> tuple[ChoiceT, ...]:
460+
return tuple(choice_key(choice) for choice in choices)
461+
462+
463+
def choice_key(choice: ChoiceT) -> ChoiceT:
464+
if type(choice) is float:
465+
return float_to_int(choice)
466+
return choice
467+
468+
469+
def choice_equal(choice1: ChoiceT, choice2: ChoiceT) -> bool:
470+
assert type(choice1) is type(choice2), (choice1, choice2)
471+
return choice_key(choice1) == choice_key(choice2)
472+
473+
474+
def choice_kwargs_equal(
475+
ir_type: ChoiceNameT, kwargs1: ChoiceKwargsT, kwargs2: ChoiceKwargsT
476+
) -> bool:
477+
return choice_kwargs_key(ir_type, kwargs1) == choice_kwargs_key(ir_type, kwargs2)
478+
479+
480+
def choice_kwargs_key(ir_type, kwargs):
481+
if ir_type == "float":
482+
return (
483+
float_to_int(kwargs["min_value"]),
484+
float_to_int(kwargs["max_value"]),
485+
kwargs["allow_nan"],
486+
kwargs["smallest_nonzero_magnitude"],
487+
)
488+
if ir_type == "integer":
489+
return (
490+
kwargs["min_value"],
491+
kwargs["max_value"],
492+
None if kwargs["weights"] is None else tuple(kwargs["weights"]),
493+
kwargs["shrink_towards"],
494+
)
495+
return tuple(kwargs[key] for key in sorted(kwargs))

hypothesis-python/src/hypothesis/internal/conjecture/data.py

Lines changed: 12 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@
4444
FloatKWargs,
4545
IntegerKWargs,
4646
StringKWargs,
47+
choice_equal,
4748
choice_from_index,
49+
choice_key,
50+
choice_kwargs_equal,
51+
choice_kwargs_key,
4852
choice_permitted,
4953
)
5054
from hypothesis.internal.conjecture.floats import float_to_lex, lex_to_float
@@ -647,15 +651,15 @@ def trivial(self) -> bool:
647651

648652
if self.ir_type != "float":
649653
zero_value = choice_from_index(0, self.ir_type, self.kwargs)
650-
return ir_value_equal(self.value, zero_value)
654+
return choice_equal(self.value, zero_value)
651655
else:
652656
kwargs = cast(FloatKWargs, self.kwargs)
653657
min_value = kwargs["min_value"]
654658
max_value = kwargs["max_value"]
655659
shrink_towards = 0.0
656660

657661
if min_value == -math.inf and max_value == math.inf:
658-
return ir_value_equal(self.value, shrink_towards)
662+
return choice_equal(self.value, shrink_towards)
659663

660664
if (
661665
not math.isinf(min_value)
@@ -666,7 +670,7 @@ def trivial(self) -> bool:
666670
# one closest to shrink_towards
667671
shrink_towards = max(math.ceil(min_value), shrink_towards)
668672
shrink_towards = min(math.floor(max_value), shrink_towards)
669-
return ir_value_equal(self.value, float(shrink_towards))
673+
return choice_equal(self.value, float(shrink_towards))
670674

671675
# the real answer here is "the value in [min_value, max_value] with
672676
# the lowest denominator when represented as a fraction".
@@ -680,17 +684,17 @@ def __eq__(self, other: object) -> bool:
680684

681685
return (
682686
self.ir_type == other.ir_type
683-
and ir_value_equal(self.value, other.value)
684-
and ir_kwargs_equal(self.ir_type, self.kwargs, other.kwargs)
687+
and choice_equal(self.value, other.value)
688+
and choice_kwargs_equal(self.ir_type, self.kwargs, other.kwargs)
685689
and self.was_forced == other.was_forced
686690
)
687691

688692
def __hash__(self) -> int:
689693
return hash(
690694
(
691695
self.ir_type,
692-
ir_value_key(self.value),
693-
ir_kwargs_key(self.ir_type, self.kwargs),
696+
choice_key(self.value),
697+
choice_kwargs_key(self.ir_type, self.kwargs),
694698
self.was_forced,
695699
)
696700
)
@@ -726,39 +730,6 @@ def ir_size(ir: Iterable[Union[IRNode, NodeTemplate, ChoiceT]]) -> int:
726730
return size
727731

728732

729-
def ir_value_key(v):
730-
if type(v) is float:
731-
return float_to_int(v)
732-
return v
733-
734-
735-
def ir_kwargs_key(ir_type, kwargs):
736-
if ir_type == "float":
737-
return (
738-
float_to_int(kwargs["min_value"]),
739-
float_to_int(kwargs["max_value"]),
740-
kwargs["allow_nan"],
741-
kwargs["smallest_nonzero_magnitude"],
742-
)
743-
if ir_type == "integer":
744-
return (
745-
kwargs["min_value"],
746-
kwargs["max_value"],
747-
None if kwargs["weights"] is None else tuple(kwargs["weights"]),
748-
kwargs["shrink_towards"],
749-
)
750-
return tuple(kwargs[key] for key in sorted(kwargs))
751-
752-
753-
def ir_value_equal(v1, v2):
754-
assert type(v1) is type(v2), (v1, v2)
755-
return ir_value_key(v1) == ir_value_key(v2)
756-
757-
758-
def ir_kwargs_equal(ir_type, kwargs1, kwargs2):
759-
return ir_kwargs_key(ir_type, kwargs1) == ir_kwargs_key(ir_type, kwargs2)
760-
761-
762733
@dataclass_transform()
763734
@attr.s(slots=True)
764735
class ConjectureResult:
@@ -1969,7 +1940,7 @@ def _pooled_kwargs(self, ir_type, kwargs):
19691940
if self.provider.avoid_realization:
19701941
return kwargs
19711942

1972-
key = (ir_type, *ir_kwargs_key(ir_type, kwargs))
1943+
key = (ir_type, *choice_kwargs_key(ir_type, kwargs))
19731944
try:
19741945
return POOLED_KWARGS_CACHE[key]
19751946
except KeyError:

hypothesis-python/src/hypothesis/internal/conjecture/engine.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
)
4545
from hypothesis.internal.cache import LRUReusedCache
4646
from hypothesis.internal.compat import NotRequired, TypeAlias, TypedDict, ceil, override
47-
from hypothesis.internal.conjecture.choice import ChoiceKwargsT, ChoiceT
47+
from hypothesis.internal.conjecture.choice import ChoiceKwargsT, ChoiceT, choices_key
4848
from hypothesis.internal.conjecture.data import (
4949
AVAILABLE_PROVIDERS,
5050
ConjectureData,
@@ -58,7 +58,6 @@
5858
Status,
5959
_Overrun,
6060
ir_size,
61-
ir_value_key,
6261
)
6362
from hypothesis.internal.conjecture.datatree import (
6463
DataTree,
@@ -346,8 +345,8 @@ def __stoppable_test_function(self, data: ConjectureData) -> None:
346345
# correct engine.
347346
raise
348347

349-
def _cache_key(self, choices: Sequence[ChoiceT]) -> tuple[int, ...]:
350-
return tuple(ir_value_key(choice) for choice in choices)
348+
def _cache_key(self, choices: Sequence[ChoiceT]) -> tuple[ChoiceT, ...]:
349+
return choices_key(choices)
351350

352351
def _cache(self, data: ConjectureData) -> None:
353352
result = data.as_result()

hypothesis-python/src/hypothesis/internal/conjecture/shrinker.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
import attr
1717

1818
from hypothesis.internal.conjecture.choice import (
19+
choice_equal,
1920
choice_from_index,
21+
choice_key,
2022
choice_permitted,
2123
choice_to_index,
2224
)
@@ -27,8 +29,6 @@
2729
Status,
2830
draw_choice,
2931
ir_size,
30-
ir_value_equal,
31-
ir_value_key,
3232
)
3333
from hypothesis.internal.conjecture.junkdrawer import (
3434
endswith,
@@ -1082,7 +1082,7 @@ def __changed_nodes(self):
10821082
assert len(prev_nodes) == len(new_nodes)
10831083
for i, (n1, n2) in enumerate(zip(prev_nodes, new_nodes)):
10841084
assert n1.ir_type == n2.ir_type
1085-
if not ir_value_equal(n1.value, n2.value):
1085+
if not choice_equal(n1.value, n2.value):
10861086
self.__all_changed_nodes.add(i)
10871087

10881088
return self.__all_changed_nodes
@@ -1295,7 +1295,7 @@ def duplicated_nodes(self):
12951295
"""Returns a list of nodes grouped (ir_type, value)."""
12961296
duplicates = defaultdict(list)
12971297
for node in self.nodes:
1298-
duplicates[(node.ir_type, ir_value_key(node.value))].append(node)
1298+
duplicates[(node.ir_type, choice_key(node.value))].append(node)
12991299
return list(duplicates.values())
13001300

13011301
@defines_shrink_pass()
@@ -1437,7 +1437,7 @@ def minimize_nodes(self, nodes):
14371437
# same operation on both basically just works.
14381438
kwargs = nodes[0].kwargs
14391439
assert all(
1440-
node.ir_type == ir_type and ir_value_equal(node.value, value)
1440+
node.ir_type == ir_type and choice_equal(node.value, value)
14411441
for node in nodes
14421442
)
14431443

hypothesis-python/tests/conjecture/test_forced.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
import hypothesis.strategies as st
1616
from hypothesis import HealthCheck, assume, example, given, settings
1717
from hypothesis.internal.conjecture import utils as cu
18-
from hypothesis.internal.conjecture.data import ConjectureData, ir_value_equal
18+
from hypothesis.internal.conjecture.choice import choice_equal
19+
from hypothesis.internal.conjecture.data import ConjectureData
1920
from hypothesis.internal.floats import SIGNALING_NAN, SMALLEST_SUBNORMAL
2021

2122
from tests.conjecture.common import fresh_data, ir_types_and_kwargs
@@ -142,13 +143,13 @@ def test_forced_values(ir_type_and_kwargs):
142143

143144
forced = kwargs["forced"]
144145
data = fresh_data()
145-
assert ir_value_equal(getattr(data, f"draw_{ir_type}")(**kwargs), forced)
146+
assert choice_equal(getattr(data, f"draw_{ir_type}")(**kwargs), forced)
146147

147148
# now make sure the written buffer reproduces the forced value, even without
148149
# specifying forced=.
149150
del kwargs["forced"]
150151
data = ConjectureData.for_choices(data.choices)
151-
assert ir_value_equal(getattr(data, f"draw_{ir_type}")(**kwargs), forced)
152+
assert choice_equal(getattr(data, f"draw_{ir_type}")(**kwargs), forced)
152153

153154

154155
@pytest.mark.parametrize("sign", [1, -1])

hypothesis-python/tests/conjecture/test_ir.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
)
2626
from hypothesis.errors import StopTest
2727
from hypothesis.internal.conjecture.choice import (
28+
choice_equal,
2829
choice_from_index,
2930
choice_permitted,
3031
choice_to_index,
@@ -36,7 +37,6 @@
3637
NodeTemplate,
3738
Status,
3839
ir_size,
39-
ir_value_equal,
4040
)
4141
from hypothesis.internal.conjecture.datatree import (
4242
MAX_CHILDREN_EFFECTIVELY_INFINITE,
@@ -286,7 +286,7 @@ def test_copy_ir_node(node):
286286
new_value = draw_value(node.ir_type, node.kwargs)
287287
# if we drew the same value as before, the node should still be equal
288288
assert (node.copy(with_value=new_value) == node) is (
289-
ir_value_equal(new_value, node.value)
289+
choice_equal(new_value, node.value)
290290
)
291291

292292

@@ -325,9 +325,9 @@ def test_data_with_changed_forced_value(node):
325325
draw_func = getattr(data, f"draw_{node.ir_type}")
326326
kwargs = deepcopy(node.kwargs)
327327
kwargs["forced"] = draw_value(node.ir_type, node.kwargs)
328-
assume(not ir_value_equal(kwargs["forced"], node.value))
328+
assume(not choice_equal(kwargs["forced"], node.value))
329329

330-
assert ir_value_equal(draw_func(**kwargs), kwargs["forced"])
330+
assert choice_equal(draw_func(**kwargs), kwargs["forced"])
331331

332332

333333
# ensure we hit bare-minimum coverage for all ir types.
@@ -374,7 +374,7 @@ def test_data_with_same_forced_value_is_valid(node):
374374

375375
kwargs = deepcopy(node.kwargs)
376376
kwargs["forced"] = node.value
377-
assert ir_value_equal(draw_func(**kwargs), kwargs["forced"])
377+
assert choice_equal(draw_func(**kwargs), kwargs["forced"])
378378

379379

380380
@given(ir_types_and_kwargs())
@@ -565,7 +565,7 @@ def values(draw):
565565
return getattr(data, f"draw_{node.ir_type}")(**node.kwargs)
566566

567567
# if we're trivial, then shrinking should produce the same value.
568-
assert ir_value_equal(minimal(values()), node.value)
568+
assert choice_equal(minimal(values()), node.value)
569569

570570

571571
@pytest.mark.parametrize(
@@ -623,7 +623,7 @@ def values(draw):
623623
return getattr(data, f"draw_{node.ir_type}")(**node.kwargs)
624624

625625
# if we're nontrivial, then shrinking should produce something different.
626-
assert not ir_value_equal(minimal(values()), node.value)
626+
assert not choice_equal(minimal(values()), node.value)
627627

628628

629629
@pytest.mark.parametrize(
@@ -671,7 +671,7 @@ def values(draw):
671671
data = draw(st.data()).conjecture_data
672672
return getattr(data, f"draw_{node.ir_type}")(**node.kwargs)
673673

674-
assert ir_value_equal(minimal(values()), node.value)
674+
assert choice_equal(minimal(values()), node.value)
675675

676676

677677
@given(ir_nodes())
@@ -785,7 +785,7 @@ def test_choice_index_and_value_are_inverses(ir_type_and_kwargs):
785785
v = draw_value(ir_type, kwargs)
786786
index = choice_to_index(v, kwargs)
787787
note({"v": v, "index": index})
788-
ir_value_equal(choice_from_index(index, ir_type, kwargs), v)
788+
choice_equal(choice_from_index(index, ir_type, kwargs), v)
789789

790790

791791
@pytest.mark.parametrize(
@@ -814,7 +814,7 @@ def test_choice_index_and_value_are_inverses(ir_type_and_kwargs):
814814
def test_choice_index_and_value_are_inverses_explicit(ir_type, kwargs, choices):
815815
for choice in choices:
816816
index = choice_to_index(choice, kwargs)
817-
assert ir_value_equal(choice_from_index(index, ir_type, kwargs), choice)
817+
assert choice_equal(choice_from_index(index, ir_type, kwargs), choice)
818818

819819

820820
@pytest.mark.parametrize(
@@ -852,7 +852,7 @@ def test_drawing_directly_matches_for_choices(nodes):
852852
data = ConjectureData.for_choices([n.value for n in nodes])
853853
for node in nodes:
854854
value = getattr(data, f"draw_{node.ir_type}")(**node.kwargs)
855-
assert ir_value_equal(node.value, value)
855+
assert choice_equal(node.value, value)
856856

857857

858858
def test_draw_directly_explicit():

hypothesis-python/tests/cover/test_database_backend.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
)
3636
from hypothesis.errors import HypothesisWarning
3737
from hypothesis.internal.compat import WINDOWS
38-
from hypothesis.internal.conjecture.data import ir_value_equal
38+
from hypothesis.internal.conjecture.choice import choice_equal
3939
from hypothesis.stateful import Bundle, RuleBasedStateMachine, rule
4040
from hypothesis.strategies import binary, lists, tuples
4141
from hypothesis.utils.conventions import not_set
@@ -485,7 +485,7 @@ def test_ir_nodes_rountrips(nodes1):
485485
assert len(nodes1) == len(ir2)
486486

487487
for n1, v2 in zip(nodes1, ir2):
488-
assert ir_value_equal(n1.value, v2)
488+
assert choice_equal(n1.value, v2)
489489

490490
s2 = ir_to_bytes(ir2)
491491
assert s1 == s2

hypothesis-python/tests/cover/test_float_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import pytest
1515

1616
from hypothesis import example, given, strategies as st
17-
from hypothesis.internal.conjecture.data import ir_value_equal
17+
from hypothesis.internal.conjecture.choice import choice_equal
1818
from hypothesis.internal.floats import (
1919
count_between_floats,
2020
float_permitted,
@@ -103,4 +103,4 @@ def test_float_clamper(kwargs, input_value):
103103
allow_nan=allow_nan,
104104
smallest_nonzero_magnitude=smallest_nonzero_magnitude,
105105
):
106-
assert ir_value_equal(input_value, clamped)
106+
assert choice_equal(input_value, clamped)

0 commit comments

Comments
 (0)