1- """Deterministic stand-ins for the handful of Hypothesis strategies we need."""
2-
1+ """Deterministic stand-ins for a tiny subset of Hypothesis strategies."""
32from __future__ import annotations
4-
53from dataclasses import dataclass
64from typing import Iterable , List , Sequence
7-
85__all__ = ["Strategy" , "sampled_from" , "lists" , "text" ]
9-
10-
116class Strategy :
12- """Base strategy API matching the expectations of :func:`hypothesis.given`."""
13-
14- def examples (self ) -> Sequence [object ]: # pragma: no cover - interface only
7+ def examples (self ) -> Sequence [object ]:
158 raise NotImplementedError
16-
17-
189@dataclass
1910class SampledFromStrategy (Strategy ):
2011 values : Sequence [object ]
21-
2212 def __post_init__ (self ) -> None :
2313 if not self .values :
2414 self .values = [None ]
25-
2615 def examples (self ) -> Sequence [object ]:
27- # Provide a handful of distinct representatives while preserving order.
2816 unique : List [object ] = []
2917 for candidate in (self .values [0 ], self .values [- 1 ]):
3018 if candidate not in unique :
@@ -33,27 +21,16 @@ def examples(self) -> Sequence[object]:
3321 if midpoint not in unique :
3422 unique .append (midpoint )
3523 return tuple (unique )
36-
3724 def cycle (self , length : int , * , reverse : bool = False , offset : int = 0 ) -> List [object ]:
38- items = list (self .values [::- 1 ] if reverse else self .values )
39- if not items :
40- items = [None ]
41- out : List [object ] = []
42- for i in range (length ):
43- out .append (items [(i + offset ) % len (items )])
44- return out
45-
46-
25+ items = list (self .values [::- 1 ] if reverse else self .values ) or [None ]
26+ return [items [(i + offset ) % len (items )] for i in range (length )]
4727@dataclass
4828class ListStrategy (Strategy ):
4929 inner : Strategy
5030 min_size : int
5131 max_size : int
52-
5332 def examples (self ) -> Sequence [object ]:
54- length = self .min_size
55- if self .max_size < self .min_size :
56- length = self .max_size
33+ length = min (max (self .min_size , 0 ), max (self .max_size , 0 ))
5734 cycle = getattr (self .inner , "cycle" , None )
5835 if callable (cycle ):
5936 base = cycle (length )
@@ -64,13 +41,11 @@ def examples(self) -> Sequence[object]:
6441 base = [(base_values [i % len (base_values )]) for i in range (length )]
6542 rotated = base [::- 1 ]
6643 reversed_cycle = base_values [:length ]
67-
6844 examples : List [List [object ]] = [list (base )]
6945 if rotated and rotated != base :
7046 examples .append (list (rotated ))
7147 if reversed_cycle and reversed_cycle not in examples :
7248 examples .append (list (reversed_cycle ))
73-
7449 if self .max_size > self .min_size :
7550 alt_length = self .max_size
7651 if callable (cycle ):
@@ -80,39 +55,25 @@ def examples(self) -> Sequence[object]:
8055 alt = [(base_values [i % len (base_values )]) for i in range (alt_length )]
8156 if alt :
8257 examples .append (list (alt ))
83-
8458 return tuple (examples )
85-
86-
8759@dataclass
8860class TextStrategy (Strategy ):
8961 alphabet : Strategy
9062 min_size : int
9163 max_size : int
92-
9364 def examples (self ) -> Sequence [object ]:
94- chars = [str (c ) for c in self .alphabet .examples () if str (c )]
95- if not chars :
96- chars = ["" ]
97-
65+ chars = [str (c ) for c in self .alphabet .examples () if str (c )] or ["" ]
9866 examples : List [str ] = ["" ]
9967 if self .min_size > 0 :
100- repeat_count = max (self .min_size , 1 )
101- repeat_count = min (repeat_count , self .max_size )
68+ repeat_count = min (max (self .min_size , 1 ), self .max_size )
10269 examples .append (chars [0 ] * repeat_count )
10370 if len (chars ) > 1 :
10471 joined = "" .join (chars )
10572 examples .append (joined [: self .max_size ])
10673 return tuple (examples )
107-
108-
10974def sampled_from (values : Iterable [object ]) -> SampledFromStrategy :
11075 return SampledFromStrategy (tuple (values ))
111-
112-
11376def lists (inner : Strategy , * , min_size : int , max_size : int ) -> ListStrategy :
11477 return ListStrategy (inner = inner , min_size = min_size , max_size = max_size )
115-
116-
11778def text (* , alphabet : Strategy , min_size : int , max_size : int ) -> TextStrategy :
11879 return TextStrategy (alphabet = alphabet , min_size = min_size , max_size = max_size )
0 commit comments