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

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

54 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 collections.abc import Callable 

12from typing import TYPE_CHECKING, Any, NoReturn 

13 

14from hypothesis.internal.conjecture.data import ConjectureData 

15from hypothesis.internal.reflection import get_pretty_function_description 

16from hypothesis.strategies._internal.strategies import ( 

17 Ex, 

18 RecurT, 

19 SampledFromStrategy, 

20 SearchStrategy, 

21 T, 

22 is_hashable, 

23) 

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

25from hypothesis.utils.conventions import UniqueIdentifier 

26 

27if TYPE_CHECKING: 

28 from typing_extensions import Never 

29 

30 

31class JustStrategy(SampledFromStrategy[Ex]): 

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

33 

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

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

36 

37 The important difference from a SampledFromStrategy with only one 

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

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

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

41 for both JustStrategy and SampledFromStrategy. 

42 """ 

43 

44 @property 

45 def value(self) -> Ex: 

46 return self.elements[0] 

47 

48 def __repr__(self) -> str: 

49 suffix = "".join( 

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

51 for name, f in self._transformations 

52 ) 

53 if self.value is None: 

54 return "none()" + suffix 

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

56 

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

58 return is_hashable(self.value) 

59 

60 def do_filtered_draw(self, data: ConjectureData) -> Ex | UniqueIdentifier: 

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

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

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

64 return self._transform(self.value) 

65 

66 

67@defines_strategy(eager=True) 

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

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

70 

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

72 

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

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

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

76 

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

78 """ 

79 return JustStrategy([value]) 

80 

81 

82@defines_strategy(force_reusable_values=True) 

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

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

85 

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

87 one). 

88 """ 

89 return just(None) 

90 

91 

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

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

94 return True 

95 

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

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

98 # data as invalid immediately because is_empty is True. 

99 raise NotImplementedError("This should never happen") 

100 

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

102 return True 

103 

104 def __repr__(self) -> str: 

105 return "nothing()" 

106 

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

108 return self 

109 

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

111 return self 

112 

113 def flatmap( 

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

115 ) -> "SearchStrategy[Never]": 

116 return self 

117 

118 

119NOTHING = Nothing() 

120 

121 

122@cacheable 

123@defines_strategy(eager=True) 

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

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

126 an attempt to draw. 

127 

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

129 """ 

130 return NOTHING 

131 

132 

133class BooleansStrategy(SearchStrategy[bool]): 

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

135 return data.draw_boolean() 

136 

137 def __repr__(self) -> str: 

138 return "booleans()"