Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/hypothesis/strategies/_internal/misc.py: 70%

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

53 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 typing import TYPE_CHECKING, Any, Callable, NoReturn, Union 

12 

13from hypothesis.internal.conjecture.data import ConjectureData 

14from hypothesis.internal.reflection import get_pretty_function_description 

15from hypothesis.strategies._internal.strategies import ( 

16 Ex, 

17 RecurT, 

18 SampledFromStrategy, 

19 SearchStrategy, 

20 T, 

21 is_hashable, 

22) 

23from hypothesis.strategies._internal.utils import cacheable, defines_strategy 

24from hypothesis.utils.conventions import UniqueIdentifier 

25 

26if TYPE_CHECKING: 

27 from typing_extensions import Never 

28 

29 

30class JustStrategy(SampledFromStrategy[Ex]): 

31 """A strategy which always returns a single fixed value. 

32 

33 It's implemented as a length-one SampledFromStrategy so that all our 

34 special-case logic for filtering and sets applies also to just(x). 

35 

36 The important difference from a SampledFromStrategy with only one 

37 element to choose is that JustStrategy *never* touches the underlying 

38 choice sequence, i.e. drawing neither reads from nor writes to `data`. 

39 This is a reasonably important optimisation (or semantic distinction!) 

40 for both JustStrategy and SampledFromStrategy. 

41 """ 

42 

43 @property 

44 def value(self) -> Ex: 

45 return self.elements[0] 

46 

47 def __repr__(self) -> str: 

48 suffix = "".join( 

49 f".{name}({get_pretty_function_description(f)})" 

50 for name, f in self._transformations 

51 ) 

52 if self.value is None: 

53 return "none()" + suffix 

54 return f"just({get_pretty_function_description(self.value)}){suffix}" 

55 

56 def calc_is_cacheable(self, recur: RecurT) -> bool: 

57 return is_hashable(self.value) 

58 

59 def do_filtered_draw(self, data: ConjectureData) -> Union[Ex, UniqueIdentifier]: 

60 # The parent class's `do_draw` implementation delegates directly to 

61 # `do_filtered_draw`, which we can greatly simplify in this case since 

62 # we have exactly one value. (This also avoids drawing any data.) 

63 return self._transform(self.value) 

64 

65 

66@defines_strategy(never_lazy=True) 

67def just(value: T) -> SearchStrategy[T]: 

68 """Return a strategy which only generates ``value``. 

69 

70 Note: ``value`` is not copied. Be wary of using mutable values. 

71 

72 If ``value`` is the result of a callable, you can use 

73 :func:`builds(callable) <hypothesis.strategies.builds>` instead 

74 of ``just(callable())`` to get a fresh value each time. 

75 

76 Examples from this strategy do not shrink (because there is only one). 

77 """ 

78 return JustStrategy([value]) 

79 

80 

81@defines_strategy(force_reusable_values=True) 

82def none() -> SearchStrategy[None]: 

83 """Return a strategy which only generates None. 

84 

85 Examples from this strategy do not shrink (because there is only 

86 one). 

87 """ 

88 return just(None) 

89 

90 

91class Nothing(SearchStrategy["Never"]): 

92 def calc_is_empty(self, recur: RecurT) -> bool: 

93 return True 

94 

95 def do_draw(self, data: ConjectureData) -> NoReturn: 

96 # This method should never be called because draw() will mark the 

97 # data as invalid immediately because is_empty is True. 

98 raise NotImplementedError("This should never happen") 

99 

100 def calc_has_reusable_values(self, recur: RecurT) -> bool: 

101 return True 

102 

103 def __repr__(self) -> str: 

104 return "nothing()" 

105 

106 def map(self, pack: Callable[[Any], Any]) -> SearchStrategy["Never"]: 

107 return self 

108 

109 def filter(self, condition: Callable[[Any], Any]) -> "SearchStrategy[Never]": 

110 return self 

111 

112 def flatmap( 

113 self, expand: Callable[[Any], "SearchStrategy[Any]"] 

114 ) -> "SearchStrategy[Never]": 

115 return self 

116 

117 

118NOTHING = Nothing() 

119 

120 

121@cacheable 

122@defines_strategy(never_lazy=True) 

123def nothing() -> SearchStrategy["Never"]: 

124 """This strategy never successfully draws a value and will always reject on 

125 an attempt to draw. 

126 

127 Examples from this strategy do not shrink (because there are none). 

128 """ 

129 return NOTHING 

130 

131 

132class BooleansStrategy(SearchStrategy[bool]): 

133 def do_draw(self, data: ConjectureData) -> bool: 

134 return data.draw_boolean() 

135 

136 def __repr__(self) -> str: 

137 return "booleans()"