Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/hypothesis/internal/conjecture/shrinking/integer.py: 29%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

42 statements  

1# This file is part of Hypothesis, which may be found at 

2# https://github.com/HypothesisWorks/hypothesis/ 

3# 

4# Copyright the Hypothesis Authors. 

5# Individual contributors are listed in AUTHORS.rst and the git log. 

6# 

7# This Source Code Form is subject to the terms of the Mozilla Public License, 

8# v. 2.0. If a copy of the MPL was not distributed with this file, You can 

9# obtain one at https://mozilla.org/MPL/2.0/. 

10 

11from hypothesis.internal.conjecture.junkdrawer import find_integer 

12from hypothesis.internal.conjecture.shrinking.common import Shrinker 

13 

14""" 

15This module implements a shrinker for non-negative integers. 

16""" 

17 

18 

19class Integer(Shrinker): 

20 """Attempts to find a smaller integer. Guaranteed things to try ``0``, 

21 

22 ``1``, ``initial - 1``, ``initial - 2``. Plenty of optimisations beyond 

23 that but those are the guaranteed ones. 

24 """ 

25 

26 def short_circuit(self): 

27 for i in range(2): 

28 if self.consider(i): 

29 return True 

30 self.mask_high_bits() 

31 if self.size > 8: 

32 # see if we can squeeze the integer into a single byte. 

33 self.consider(self.current >> (self.size - 8)) 

34 self.consider(self.current & 0xFF) 

35 return self.current == 2 

36 

37 def check_invariants(self, value): 

38 assert value >= 0 

39 

40 def left_is_better(self, left, right): 

41 return left < right 

42 

43 def run_step(self): 

44 self.shift_right() 

45 self.shrink_by_multiples(2) 

46 self.shrink_by_multiples(1) 

47 

48 def shift_right(self): 

49 base = self.current 

50 find_integer(lambda k: k <= self.size and self.consider(base >> k)) 

51 

52 def mask_high_bits(self): 

53 base = self.current 

54 n = base.bit_length() 

55 

56 @find_integer 

57 def try_mask(k): 

58 if k >= n: 

59 return False 

60 mask = (1 << (n - k)) - 1 

61 return self.consider(mask & base) 

62 

63 @property 

64 def size(self): 

65 return self.current.bit_length() 

66 

67 def shrink_by_multiples(self, k): 

68 base = self.current 

69 

70 @find_integer 

71 def shrunk(n): 

72 attempt = base - n * k 

73 return attempt >= 0 and self.consider(attempt) 

74 

75 return shrunk > 0