|
20 | 20 | prefix_selection_order,
|
21 | 21 | random_selection_order,
|
22 | 22 | )
|
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 | +) |
24 | 30 | from hypothesis.internal.conjecture.dfa import ConcreteDFA
|
25 | 31 | from hypothesis.internal.conjecture.floats import is_simple
|
26 | 32 | from hypothesis.internal.conjecture.junkdrawer import (
|
@@ -1241,32 +1247,50 @@ def redistribute_block_pairs(self, chooser):
|
1241 | 1247 | to exceed some bound, lowering one of them requires raising the
|
1242 | 1248 | other. This pass enables that."""
|
1243 | 1249 |
|
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 | + ) |
1245 | 1253 |
|
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()): |
1249 | 1269 | break
|
1250 | 1270 | else:
|
1251 | 1271 | return
|
1252 | 1272 |
|
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 |
1257 | 1275 |
|
1258 | 1276 | def boost(k):
|
1259 | 1277 | if k > m:
|
1260 | 1278 | 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 | + ): |
1268 | 1285 | 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 | + ) |
1270 | 1294 |
|
1271 | 1295 | find_integer(boost)
|
1272 | 1296 |
|
|
0 commit comments