Skip to content

Commit a38bae9

Browse files
committed
migrate redistribute_block_pairs to the ir
1 parent 8888cfc commit a38bae9

File tree

1 file changed

+41
-17
lines changed
  • hypothesis-python/src/hypothesis/internal/conjecture

1 file changed

+41
-17
lines changed

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

+41-17
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@
2020
prefix_selection_order,
2121
random_selection_order,
2222
)
23-
from hypothesis.internal.conjecture.data import ConjectureData, ConjectureResult, Status
23+
from hypothesis.internal.conjecture.data import (
24+
ConjectureData,
25+
ConjectureResult,
26+
Status,
27+
bits_to_bytes,
28+
ir_value_permitted,
29+
)
2430
from hypothesis.internal.conjecture.dfa import ConcreteDFA
2531
from hypothesis.internal.conjecture.floats import is_simple
2632
from hypothesis.internal.conjecture.junkdrawer import (
@@ -1241,32 +1247,50 @@ def redistribute_block_pairs(self, chooser):
12411247
to exceed some bound, lowering one of them requires raising the
12421248
other. This pass enables that."""
12431249

1244-
block = chooser.choose(self.blocks, lambda b: not b.all_zero)
1250+
node = chooser.choose(
1251+
self.nodes, lambda node: node.ir_type == "integer" and not node.trivial
1252+
)
12451253

1246-
for j in range(block.index + 1, len(self.blocks)):
1247-
next_block = self.blocks[j]
1248-
if next_block.length == block.length:
1254+
# The preconditions for this pass are that the two integer draws are only
1255+
# separated by non-integer nodes, and have the same size value in bytes.
1256+
#
1257+
# This isn't particularly principled. For instance, this wouldn't reduce
1258+
# e.g. @given(integers(), integers(), integers()) where the sum property
1259+
# involves the first and last integers.
1260+
#
1261+
# A better approach may be choosing *two* such integer nodes arbitrarily
1262+
# from the list, instead of conditionally scanning forward.
1263+
1264+
for j in range(node.index + 1, len(self.nodes)):
1265+
next_node = self.nodes[j]
1266+
if next_node.ir_type == "integer" and bits_to_bytes(
1267+
node.value.bit_length()
1268+
) == bits_to_bytes(next_node.value.bit_length()):
12491269
break
12501270
else:
12511271
return
12521272

1253-
buffer = self.buffer
1254-
1255-
m = int_from_bytes(buffer[block.start : block.end])
1256-
n = int_from_bytes(buffer[next_block.start : next_block.end])
1273+
m = node.value
1274+
n = next_node.value
12571275

12581276
def boost(k):
12591277
if k > m:
12601278
return False
1261-
attempt = bytearray(buffer)
1262-
attempt[block.start : block.end] = int_to_bytes(m - k, block.length)
1263-
try:
1264-
attempt[next_block.start : next_block.end] = int_to_bytes(
1265-
n + k, next_block.length
1266-
)
1267-
except OverflowError:
1279+
1280+
node_value = m - k
1281+
next_node_value = n + k
1282+
if (not ir_value_permitted(node_value, "integer", node.kwargs)) or (
1283+
not ir_value_permitted(next_node_value, "integer", next_node.kwargs)
1284+
):
12681285
return False
1269-
return self.consider_new_buffer(attempt)
1286+
1287+
return self.consider_new_tree(
1288+
self.nodes[: node.index]
1289+
+ [node.copy(with_value=node_value)]
1290+
+ self.nodes[node.index + 1 : next_node.index]
1291+
+ [next_node.copy(with_value=next_node_value)]
1292+
+ self.nodes[next_node.index + 1 :]
1293+
)
12701294

12711295
find_integer(boost)
12721296

0 commit comments

Comments
 (0)