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
11import codecs
12import enum
13import math
14import operator
15import random
16import re
17import string
18import sys
19import typing
20import warnings
21from collections.abc import Collection, Hashable, Iterable, Sequence
22from contextvars import ContextVar
23from decimal import Context, Decimal, localcontext
24from fractions import Fraction
25from functools import reduce
26from inspect import Parameter, Signature, isabstract, isclass
27from re import Pattern
28from types import FunctionType, GenericAlias
29from typing import (
30 Annotated,
31 Any,
32 AnyStr,
33 Callable,
34 Literal,
35 NoReturn,
36 Optional,
37 Protocol,
38 TypeVar,
39 Union,
40 cast,
41 get_args,
42 get_origin,
43 overload,
44)
45from uuid import UUID
46
47import attr
48
49from hypothesis._settings import note_deprecation
50from hypothesis.control import (
51 RandomSeeder,
52 cleanup,
53 current_build_context,
54 deprecate_random_in_strategy,
55 note,
56 should_note,
57)
58from hypothesis.errors import (
59 HypothesisSideeffectWarning,
60 HypothesisWarning,
61 InvalidArgument,
62 ResolutionFailed,
63 RewindRecursive,
64 SmallSearchSpaceWarning,
65)
66from hypothesis.internal.cathetus import cathetus
67from hypothesis.internal.charmap import (
68 Categories,
69 CategoryName,
70 as_general_categories,
71 categories as all_categories,
72)
73from hypothesis.internal.compat import (
74 Concatenate,
75 ParamSpec,
76 bit_count,
77 ceil,
78 floor,
79 get_type_hints,
80 is_typed_named_tuple,
81)
82from hypothesis.internal.conjecture.data import ConjectureData
83from hypothesis.internal.conjecture.utils import (
84 calc_label_from_cls,
85 check_sample,
86 identity,
87)
88from hypothesis.internal.entropy import get_seeder_and_restorer
89from hypothesis.internal.floats import float_of
90from hypothesis.internal.reflection import (
91 define_function_signature,
92 get_pretty_function_description,
93 get_signature,
94 is_first_param_referenced_in_function,
95 nicerepr,
96 repr_call,
97 required_args,
98)
99from hypothesis.internal.validation import (
100 check_type,
101 check_valid_integer,
102 check_valid_interval,
103 check_valid_magnitude,
104 check_valid_size,
105 check_valid_sizes,
106 try_convert,
107)
108from hypothesis.strategies._internal import SearchStrategy, check_strategy
109from hypothesis.strategies._internal.collections import (
110 FixedDictStrategy,
111 ListStrategy,
112 TupleStrategy,
113 UniqueListStrategy,
114 UniqueSampledListStrategy,
115 tuples,
116)
117from hypothesis.strategies._internal.deferred import DeferredStrategy
118from hypothesis.strategies._internal.functions import FunctionStrategy
119from hypothesis.strategies._internal.lazy import LazyStrategy, unwrap_strategies
120from hypothesis.strategies._internal.misc import BooleansStrategy, just, none, nothing
121from hypothesis.strategies._internal.numbers import (
122 IntegersStrategy,
123 Real,
124 floats,
125 integers,
126)
127from hypothesis.strategies._internal.recursive import RecursiveStrategy
128from hypothesis.strategies._internal.shared import SharedStrategy
129from hypothesis.strategies._internal.strategies import (
130 Ex,
131 SampledFromStrategy,
132 T,
133 one_of,
134)
135from hypothesis.strategies._internal.strings import (
136 BytesStrategy,
137 OneCharStringStrategy,
138 TextStrategy,
139 _check_is_single_character,
140)
141from hypothesis.strategies._internal.utils import cacheable, defines_strategy
142from hypothesis.utils.conventions import not_set
143from hypothesis.vendor.pretty import RepresentationPrinter
144
145if sys.version_info >= (3, 10):
146 from types import EllipsisType
147elif typing.TYPE_CHECKING: # pragma: no cover
148 from builtins import ellipsis as EllipsisType
149
150else:
151 EllipsisType = type(Ellipsis) # pragma: no cover
152
153
154@cacheable
155@defines_strategy(force_reusable_values=True)
156def booleans() -> SearchStrategy[bool]:
157 """Returns a strategy which generates instances of :class:`python:bool`.
158
159 Examples from this strategy will shrink towards ``False`` (i.e.
160 shrinking will replace ``True`` with ``False`` where possible).
161 """
162 return BooleansStrategy()
163
164
165@overload
166def sampled_from(elements: Sequence[T]) -> SearchStrategy[T]: # pragma: no cover
167 ...
168
169
170@overload
171def sampled_from(elements: type[enum.Enum]) -> SearchStrategy[Any]: # pragma: no cover
172 # `SearchStrategy[Enum]` is unreliable due to metaclass issues.
173 ...
174
175
176@overload
177def sampled_from(
178 elements: Union[type[enum.Enum], Sequence[Any]],
179) -> SearchStrategy[Any]: # pragma: no cover
180 ...
181
182
183@defines_strategy(try_non_lazy=True)
184def sampled_from(
185 elements: Union[type[enum.Enum], Sequence[Any]],
186) -> SearchStrategy[Any]:
187 """Returns a strategy which generates any value present in ``elements``.
188
189 Note that as with :func:`~hypothesis.strategies.just`, values will not be
190 copied and thus you should be careful of using mutable data.
191
192 ``sampled_from`` supports ordered collections, as well as
193 :class:`~python:enum.Enum` objects. :class:`~python:enum.Flag` objects
194 may also generate any combination of their members.
195
196 Examples from this strategy shrink by replacing them with values earlier in
197 the list. So e.g. ``sampled_from([10, 1])`` will shrink by trying to replace
198 1 values with 10, and ``sampled_from([1, 10])`` will shrink by trying to
199 replace 10 values with 1.
200
201 It is an error to sample from an empty sequence, because returning :func:`nothing`
202 makes it too easy to silently drop parts of compound strategies. If you need
203 that behaviour, use ``sampled_from(seq) if seq else nothing()``.
204 """
205 values = check_sample(elements, "sampled_from")
206 try:
207 if isinstance(elements, type) and issubclass(elements, enum.Enum):
208 repr_ = f"sampled_from({elements.__module__}.{elements.__name__})"
209 else:
210 repr_ = f"sampled_from({elements!r})"
211 except Exception: # pragma: no cover
212 repr_ = None
213 if isclass(elements) and issubclass(elements, enum.Flag):
214 # Combinations of enum.Flag members (including empty) are also members. We generate these
215 # dynamically, because static allocation takes O(2^n) memory. LazyStrategy is used for the
216 # ease of force_repr.
217 # Add all named values, both flag bits (== list(elements)) and aliases. The aliases are
218 # necessary for full coverage for flags that would fail enum.NAMED_FLAGS check, and they
219 # are also nice values to shrink to.
220 flags = sorted(
221 set(elements.__members__.values()),
222 key=lambda v: (bit_count(v.value), v.value),
223 )
224 # Finally, try to construct the empty state if it is not named. It's placed at the
225 # end so that we shrink to named values.
226 flags_with_empty = flags
227 if not flags or flags[0].value != 0:
228 try:
229 flags_with_empty = [*flags, elements(0)]
230 except TypeError: # pragma: no cover
231 # Happens on some python versions (at least 3.12) when there are no named values
232 pass
233 inner = [
234 # Consider one or no named flags set, with shrink-to-named-flag behaviour.
235 # Special cases (length zero or one) are handled by the inner sampled_from.
236 sampled_from(flags_with_empty),
237 ]
238 if len(flags) > 1:
239 inner += [
240 # Uniform distribution over number of named flags or combinations set. The overlap
241 # at r=1 is intentional, it may lead to oversampling but gives consistent shrinking
242 # behaviour.
243 integers(min_value=1, max_value=len(flags))
244 .flatmap(lambda r: sets(sampled_from(flags), min_size=r, max_size=r))
245 .map(lambda s: elements(reduce(operator.or_, s))),
246 ]
247 return LazyStrategy(one_of, args=inner, kwargs={}, force_repr=repr_)
248 if not values:
249 if (
250 isinstance(elements, type)
251 and issubclass(elements, enum.Enum)
252 and vars(elements).get("__annotations__")
253 ):
254 # See https://github.com/HypothesisWorks/hypothesis/issues/2923
255 raise InvalidArgument(
256 f"Cannot sample from {elements.__module__}.{elements.__name__} "
257 "because it contains no elements. It does however have annotations, "
258 "so maybe you tried to write an enum as if it was a dataclass?"
259 )
260 raise InvalidArgument("Cannot sample from a length-zero sequence.")
261 if len(values) == 1:
262 return just(values[0])
263 return SampledFromStrategy(values, repr_)
264
265
266@cacheable
267@defines_strategy()
268def lists(
269 elements: SearchStrategy[Ex],
270 *,
271 min_size: int = 0,
272 max_size: Optional[int] = None,
273 unique_by: Union[
274 None,
275 Callable[[Ex], Hashable],
276 tuple[Callable[[Ex], Hashable], ...],
277 ] = None,
278 unique: bool = False,
279) -> SearchStrategy[list[Ex]]:
280 """Returns a list containing values drawn from elements with length in the
281 interval [min_size, max_size] (no bounds in that direction if these are
282 None). If max_size is 0, only the empty list will be drawn.
283
284 If ``unique`` is True (or something that evaluates to True), we compare direct
285 object equality, as if unique_by was ``lambda x: x``. This comparison only
286 works for hashable types.
287
288 If ``unique_by`` is not None it must be a callable or tuple of callables
289 returning a hashable type when given a value drawn from elements. The
290 resulting list will satisfy the condition that for ``i`` != ``j``,
291 ``unique_by(result[i])`` != ``unique_by(result[j])``.
292
293 If ``unique_by`` is a tuple of callables the uniqueness will be respective
294 to each callable.
295
296 For example, the following will produce two columns of integers with both
297 columns being unique respectively.
298
299 .. code-block:: pycon
300
301 >>> twoints = st.tuples(st.integers(), st.integers())
302 >>> st.lists(twoints, unique_by=(lambda x: x[0], lambda x: x[1]))
303
304 Examples from this strategy shrink by trying to remove elements from the
305 list, and by shrinking each individual element of the list.
306 """
307 check_valid_sizes(min_size, max_size)
308 check_strategy(elements, "elements")
309 if unique:
310 if unique_by is not None:
311 raise InvalidArgument(
312 "cannot specify both unique and unique_by "
313 "(you probably only want to set unique_by)"
314 )
315 else:
316 unique_by = identity
317
318 if max_size == 0:
319 return builds(list)
320 if unique_by is not None:
321 if not (callable(unique_by) or isinstance(unique_by, tuple)):
322 raise InvalidArgument(
323 f"{unique_by=} is not a callable or tuple of callables"
324 )
325 if callable(unique_by):
326 unique_by = (unique_by,)
327 if len(unique_by) == 0:
328 raise InvalidArgument("unique_by is empty")
329 for i, f in enumerate(unique_by):
330 if not callable(f):
331 raise InvalidArgument(f"unique_by[{i}]={f!r} is not a callable")
332 # Note that lazy strategies automatically unwrap when passed to a defines_strategy
333 # function.
334 tuple_suffixes = None
335 # the type: ignores in the TupleStrategy and IntegersStrategy cases are
336 # for a mypy bug, which incorrectly narrows `elements` to Never.
337 # https://github.com/python/mypy/issues/16494
338 if (
339 # We're generating a list of tuples unique by the first element, perhaps
340 # via st.dictionaries(), and this will be more efficient if we rearrange
341 # our strategy somewhat to draw the first element then draw add the rest.
342 isinstance(elements, TupleStrategy)
343 and len(elements.element_strategies) >= 1 # type: ignore
344 and len(unique_by) == 1
345 and (
346 # Introspection for either `itemgetter(0)`, or `lambda x: x[0]`
347 (
348 isinstance(unique_by[0], operator.itemgetter)
349 and repr(unique_by[0]) == "operator.itemgetter(0)"
350 )
351 or (
352 isinstance(unique_by[0], FunctionType)
353 and re.fullmatch(
354 get_pretty_function_description(unique_by[0]),
355 r"lambda ([a-z]+): \1\[0\]",
356 )
357 )
358 )
359 ):
360 unique_by = (identity,)
361 tuple_suffixes = TupleStrategy(elements.element_strategies[1:]) # type: ignore
362 elements = elements.element_strategies[0] # type: ignore
363
364 # UniqueSampledListStrategy offers a substantial performance improvement for
365 # unique arrays with few possible elements, e.g. of eight-bit integer types.
366 if (
367 isinstance(elements, IntegersStrategy)
368 and elements.start is not None # type: ignore
369 and elements.end is not None # type: ignore
370 and (elements.end - elements.start) <= 255 # type: ignore
371 ):
372 elements = SampledFromStrategy(
373 sorted(range(elements.start, elements.end + 1), key=abs) # type: ignore
374 if elements.end < 0 or elements.start > 0 # type: ignore
375 else list(range(elements.end + 1)) # type: ignore
376 + list(range(-1, elements.start - 1, -1)) # type: ignore
377 )
378
379 if isinstance(elements, SampledFromStrategy):
380 element_count = len(elements.elements)
381 if min_size > element_count:
382 raise InvalidArgument(
383 f"Cannot create a collection of {min_size=} unique "
384 f"elements with values drawn from only {element_count} distinct "
385 "elements"
386 )
387
388 if max_size is not None:
389 max_size = min(max_size, element_count)
390 else:
391 max_size = element_count
392
393 return UniqueSampledListStrategy(
394 elements=elements,
395 max_size=max_size,
396 min_size=min_size,
397 keys=unique_by,
398 tuple_suffixes=tuple_suffixes,
399 )
400
401 return UniqueListStrategy(
402 elements=elements,
403 max_size=max_size,
404 min_size=min_size,
405 keys=unique_by,
406 tuple_suffixes=tuple_suffixes,
407 )
408 return ListStrategy(elements, min_size=min_size, max_size=max_size)
409
410
411@cacheable
412@defines_strategy()
413def sets(
414 elements: SearchStrategy[Ex],
415 *,
416 min_size: int = 0,
417 max_size: Optional[int] = None,
418) -> SearchStrategy[set[Ex]]:
419 """This has the same behaviour as lists, but returns sets instead.
420
421 Note that Hypothesis cannot tell if values are drawn from elements
422 are hashable until running the test, so you can define a strategy
423 for sets of an unhashable type but it will fail at test time.
424
425 Examples from this strategy shrink by trying to remove elements from the
426 set, and by shrinking each individual element of the set.
427 """
428 return lists(
429 elements=elements, min_size=min_size, max_size=max_size, unique=True
430 ).map(set)
431
432
433@cacheable
434@defines_strategy()
435def frozensets(
436 elements: SearchStrategy[Ex],
437 *,
438 min_size: int = 0,
439 max_size: Optional[int] = None,
440) -> SearchStrategy[frozenset[Ex]]:
441 """This is identical to the sets function but instead returns
442 frozensets."""
443 return lists(
444 elements=elements, min_size=min_size, max_size=max_size, unique=True
445 ).map(frozenset)
446
447
448class PrettyIter:
449 def __init__(self, values):
450 self._values = values
451 self._iter = iter(self._values)
452
453 def __iter__(self):
454 return self._iter
455
456 def __next__(self):
457 return next(self._iter)
458
459 def __repr__(self) -> str:
460 return f"iter({self._values!r})"
461
462
463@defines_strategy()
464def iterables(
465 elements: SearchStrategy[Ex],
466 *,
467 min_size: int = 0,
468 max_size: Optional[int] = None,
469 unique_by: Union[
470 None,
471 Callable[[Ex], Hashable],
472 tuple[Callable[[Ex], Hashable], ...],
473 ] = None,
474 unique: bool = False,
475) -> SearchStrategy[Iterable[Ex]]:
476 """This has the same behaviour as lists, but returns iterables instead.
477
478 Some iterables cannot be indexed (e.g. sets) and some do not have a
479 fixed length (e.g. generators). This strategy produces iterators,
480 which cannot be indexed and do not have a fixed length. This ensures
481 that you do not accidentally depend on sequence behaviour.
482 """
483 return lists(
484 elements=elements,
485 min_size=min_size,
486 max_size=max_size,
487 unique_by=unique_by,
488 unique=unique,
489 ).map(PrettyIter)
490
491
492# this type definition is imprecise, in multiple ways:
493# * mapping and optional can be of different types:
494# s: dict[str | int, int] = st.fixed_dictionaries(
495# {"a": st.integers()}, optional={1: st.integers()}
496# )
497# * the values in either mapping or optional need not all be of the same type:
498# s: dict[str, int | bool] = st.fixed_dictionaries(
499# {"a": st.integers(), "b": st.booleans()}
500# )
501# * the arguments may be of any dict-compatible type, in which case the return
502# value will be of that type instead of dit
503#
504# Overloads may help here, but I doubt we'll be able to satisfy all these
505# constraints.
506#
507# Here's some platonic ideal test cases for revealed_types.py, with the understanding
508# that some may not be achievable:
509#
510# ("fixed_dictionaries({'a': booleans()})", "dict[str, bool]"),
511# ("fixed_dictionaries({'a': booleans(), 'b': integers()})", "dict[str, bool | int]"),
512# ("fixed_dictionaries({}, optional={'a': booleans()})", "dict[str, bool]"),
513# (
514# "fixed_dictionaries({'a': booleans()}, optional={1: booleans()})",
515# "dict[str | int, bool]",
516# ),
517# (
518# "fixed_dictionaries({'a': booleans()}, optional={1: integers()})",
519# "dict[str | int, bool | int]",
520# ),
521
522
523@defines_strategy()
524def fixed_dictionaries(
525 mapping: dict[T, SearchStrategy[Ex]],
526 *,
527 optional: Optional[dict[T, SearchStrategy[Ex]]] = None,
528) -> SearchStrategy[dict[T, Ex]]:
529 """Generates a dictionary of the same type as mapping with a fixed set of
530 keys mapping to strategies. ``mapping`` must be a dict subclass.
531
532 Generated values have all keys present in mapping, in iteration order,
533 with the corresponding values drawn from mapping[key].
534
535 If ``optional`` is passed, the generated value *may or may not* contain each
536 key from ``optional`` and a value drawn from the corresponding strategy.
537 Generated values may contain optional keys in an arbitrary order.
538
539 Examples from this strategy shrink by shrinking each individual value in
540 the generated dictionary, and omitting optional key-value pairs.
541 """
542 check_type(dict, mapping, "mapping")
543 for k, v in mapping.items():
544 check_strategy(v, f"mapping[{k!r}]")
545
546 if optional is not None:
547 check_type(dict, optional, "optional")
548 for k, v in optional.items():
549 check_strategy(v, f"optional[{k!r}]")
550 if type(mapping) != type(optional):
551 raise InvalidArgument(
552 f"Got arguments of different types: "
553 f"mapping={nicerepr(type(mapping))}, "
554 f"optional={nicerepr(type(optional))}"
555 )
556 if set(mapping) & set(optional):
557 raise InvalidArgument(
558 "The following keys were in both mapping and optional, "
559 f"which is invalid: {set(mapping) & set(optional)!r}"
560 )
561
562 return FixedDictStrategy(mapping, optional=optional)
563
564
565@cacheable
566@defines_strategy()
567def dictionaries(
568 keys: SearchStrategy[Ex],
569 values: SearchStrategy[T],
570 *,
571 dict_class: type = dict,
572 min_size: int = 0,
573 max_size: Optional[int] = None,
574) -> SearchStrategy[dict[Ex, T]]:
575 # Describing the exact dict_class to Mypy drops the key and value types,
576 # so we report Dict[K, V] instead of Mapping[Any, Any] for now. Sorry!
577 """Generates dictionaries of type ``dict_class`` with keys drawn from the ``keys``
578 argument and values drawn from the ``values`` argument.
579
580 The size parameters have the same interpretation as for
581 :func:`~hypothesis.strategies.lists`.
582
583 Examples from this strategy shrink by trying to remove keys from the
584 generated dictionary, and by shrinking each generated key and value.
585 """
586 check_valid_sizes(min_size, max_size)
587 if max_size == 0:
588 return fixed_dictionaries(dict_class())
589 check_strategy(keys, "keys")
590 check_strategy(values, "values")
591
592 return lists(
593 tuples(keys, values),
594 min_size=min_size,
595 max_size=max_size,
596 unique_by=operator.itemgetter(0),
597 ).map(dict_class)
598
599
600@cacheable
601@defines_strategy(force_reusable_values=True)
602def characters(
603 *,
604 codec: Optional[str] = None,
605 min_codepoint: Optional[int] = None,
606 max_codepoint: Optional[int] = None,
607 categories: Optional[Collection[CategoryName]] = None,
608 exclude_categories: Optional[Collection[CategoryName]] = None,
609 exclude_characters: Optional[Collection[str]] = None,
610 include_characters: Optional[Collection[str]] = None,
611 # Note: these arguments are deprecated aliases for backwards compatibility
612 blacklist_categories: Optional[Collection[CategoryName]] = None,
613 whitelist_categories: Optional[Collection[CategoryName]] = None,
614 blacklist_characters: Optional[Collection[str]] = None,
615 whitelist_characters: Optional[Collection[str]] = None,
616) -> SearchStrategy[str]:
617 r"""Generates characters, length-one :class:`python:str`\ ings,
618 following specified filtering rules.
619
620 - When no filtering rules are specified, any character can be produced.
621 - If ``min_codepoint`` or ``max_codepoint`` is specified, then only
622 characters having a codepoint in that range will be produced.
623 - If ``categories`` is specified, then only characters from those
624 Unicode categories will be produced. This is a further restriction,
625 characters must also satisfy ``min_codepoint`` and ``max_codepoint``.
626 - If ``exclude_categories`` is specified, then any character from those
627 categories will not be produced. You must not pass both ``categories``
628 and ``exclude_categories``; these arguments are alternative ways to
629 specify exactly the same thing.
630 - If ``include_characters`` is specified, then any additional characters
631 in that list will also be produced.
632 - If ``exclude_characters`` is specified, then any characters in
633 that list will be not be produced. Any overlap between
634 ``include_characters`` and ``exclude_characters`` will raise an
635 exception.
636 - If ``codec`` is specified, only characters in the specified `codec encodings`_
637 will be produced.
638
639 The ``_codepoint`` arguments must be integers between zero and
640 :obj:`python:sys.maxunicode`. The ``_characters`` arguments must be
641 collections of length-one unicode strings, such as a unicode string.
642
643 The ``_categories`` arguments must be used to specify either the
644 one-letter Unicode major category or the two-letter Unicode
645 `general category`_. For example, ``('Nd', 'Lu')`` signifies "Number,
646 decimal digit" and "Letter, uppercase". A single letter ('major category')
647 can be given to match all corresponding categories, for example ``'P'``
648 for characters in any punctuation category.
649
650 We allow codecs from the :mod:`codecs` module and their aliases, platform
651 specific and user-registered codecs if they are available, and
652 `python-specific text encodings`_ (but not text or binary transforms).
653 ``include_characters`` which cannot be encoded using this codec will
654 raise an exception. If non-encodable codepoints or categories are
655 explicitly allowed, the ``codec`` argument will exclude them without
656 raising an exception.
657
658 .. _general category: https://en.wikipedia.org/wiki/Unicode_character_property
659 .. _codec encodings: https://docs.python.org/3/library/codecs.html#encodings-and-unicode
660 .. _python-specific text encodings: https://docs.python.org/3/library/codecs.html#python-specific-encodings
661
662 Examples from this strategy shrink towards the codepoint for ``'0'``,
663 or the first allowable codepoint after it if ``'0'`` is excluded.
664 """
665 check_valid_size(min_codepoint, "min_codepoint")
666 check_valid_size(max_codepoint, "max_codepoint")
667 check_valid_interval(min_codepoint, max_codepoint, "min_codepoint", "max_codepoint")
668 categories = cast(Optional[Categories], categories)
669 if categories is not None and exclude_categories is not None:
670 raise InvalidArgument(
671 f"Pass at most one of {categories=} and {exclude_categories=} - "
672 "these arguments both specify which categories are allowed, so it "
673 "doesn't make sense to use both in a single call."
674 )
675
676 # Handle deprecation of whitelist/blacklist arguments
677 has_old_arg = any(v is not None for k, v in locals().items() if "list" in k)
678 has_new_arg = any(v is not None for k, v in locals().items() if "lude" in k)
679 if has_old_arg and has_new_arg:
680 raise InvalidArgument(
681 "The deprecated blacklist/whitelist arguments cannot be used in "
682 "the same call as their replacement include/exclude arguments."
683 )
684 if blacklist_categories is not None:
685 exclude_categories = blacklist_categories
686 if whitelist_categories is not None:
687 categories = whitelist_categories
688 if blacklist_characters is not None:
689 exclude_characters = blacklist_characters
690 if whitelist_characters is not None:
691 include_characters = whitelist_characters
692
693 if (
694 min_codepoint is None
695 and max_codepoint is None
696 and categories is None
697 and exclude_categories is None
698 and include_characters is not None
699 and codec is None
700 ):
701 raise InvalidArgument(
702 "Nothing is excluded by other arguments, so passing only "
703 f"{include_characters=} would have no effect. "
704 "Also pass categories=(), or use "
705 f"sampled_from({include_characters!r}) instead."
706 )
707 exclude_characters = exclude_characters or ""
708 include_characters = include_characters or ""
709 overlap = set(exclude_characters).intersection(include_characters)
710 if overlap:
711 raise InvalidArgument(
712 f"Characters {sorted(overlap)!r} are present in both "
713 f"{include_characters=} and {exclude_characters=}"
714 )
715 if categories is not None:
716 categories = as_general_categories(categories, "categories")
717 if exclude_categories is not None:
718 exclude_categories = as_general_categories(
719 exclude_categories, "exclude_categories"
720 )
721 if categories is not None and not categories and not include_characters:
722 raise InvalidArgument(
723 "When `categories` is an empty collection and there are "
724 "no characters specified in include_characters, nothing can "
725 "be generated by the characters() strategy."
726 )
727 both_cats = set(exclude_categories or ()).intersection(categories or ())
728 if both_cats:
729 # Note: we check that exactly one of `categories` or `exclude_categories` is
730 # passed above, but retain this older check for the deprecated arguments.
731 raise InvalidArgument(
732 f"Categories {sorted(both_cats)!r} are present in both "
733 f"{categories=} and {exclude_categories=}"
734 )
735 elif exclude_categories is not None:
736 categories = set(all_categories()) - set(exclude_categories)
737 del exclude_categories
738
739 if codec is not None:
740 try:
741 codec = codecs.lookup(codec).name
742 # Check this is not a str-to-str or bytes-to-bytes codec; see
743 # https://docs.python.org/3/library/codecs.html#binary-transforms
744 "".encode(codec)
745 except LookupError:
746 raise InvalidArgument(f"{codec=} is not valid on this system") from None
747 except Exception:
748 raise InvalidArgument(f"{codec=} is not a valid codec") from None
749
750 for char in include_characters:
751 try:
752 char.encode(encoding=codec, errors="strict")
753 except UnicodeEncodeError:
754 raise InvalidArgument(
755 f"Character {char!r} in {include_characters=} "
756 f"cannot be encoded with {codec=}"
757 ) from None
758
759 # ascii and utf-8 are sufficient common that we have faster special handling
760 if codec == "ascii":
761 if (max_codepoint is None) or (max_codepoint > 127):
762 max_codepoint = 127
763 codec = None
764 elif codec == "utf-8":
765 if categories is None:
766 categories = all_categories()
767 categories = tuple(c for c in categories if c != "Cs")
768
769 return OneCharStringStrategy.from_characters_args(
770 categories=categories,
771 exclude_characters=exclude_characters,
772 min_codepoint=min_codepoint,
773 max_codepoint=max_codepoint,
774 include_characters=include_characters,
775 codec=codec,
776 )
777
778
779# Hide the deprecated aliases from documentation and casual inspection
780characters.__signature__ = (__sig := get_signature(characters)).replace( # type: ignore
781 parameters=[p for p in __sig.parameters.values() if "list" not in p.name]
782)
783
784
785@cacheable
786@defines_strategy(force_reusable_values=True)
787def text(
788 alphabet: Union[Collection[str], SearchStrategy[str]] = characters(codec="utf-8"),
789 *,
790 min_size: int = 0,
791 max_size: Optional[int] = None,
792) -> SearchStrategy[str]:
793 """Generates strings with characters drawn from ``alphabet``, which should
794 be a collection of length one strings or a strategy generating such strings.
795
796 The default alphabet strategy can generate the full unicode range but
797 excludes surrogate characters because they are invalid in the UTF-8
798 encoding. You can use :func:`~hypothesis.strategies.characters` without
799 arguments to find surrogate-related bugs such as :bpo:`34454`.
800
801 ``min_size`` and ``max_size`` have the usual interpretations.
802 Note that Python measures string length by counting codepoints: U+00C5
803 ``Å`` is a single character, while U+0041 U+030A ``Å`` is two - the ``A``,
804 and a combining ring above.
805
806 Examples from this strategy shrink towards shorter strings, and with the
807 characters in the text shrinking as per the alphabet strategy.
808 This strategy does not :func:`~python:unicodedata.normalize` examples,
809 so generated strings may be in any or none of the 'normal forms'.
810 """
811 check_valid_sizes(min_size, max_size)
812 if isinstance(alphabet, SearchStrategy):
813 char_strategy = unwrap_strategies(alphabet)
814 if isinstance(char_strategy, SampledFromStrategy):
815 # Check this via the up-front validation logic below, and incidentally
816 # convert into a `characters()` strategy for standard text shrinking.
817 return text(char_strategy.elements, min_size=min_size, max_size=max_size)
818 elif not isinstance(char_strategy, OneCharStringStrategy):
819 char_strategy = char_strategy.map(_check_is_single_character)
820 else:
821 non_string = [c for c in alphabet if not isinstance(c, str)]
822 if non_string:
823 raise InvalidArgument(
824 "The following elements in alphabet are not unicode "
825 f"strings: {non_string!r}"
826 )
827 not_one_char = [c for c in alphabet if len(c) != 1]
828 if not_one_char:
829 raise InvalidArgument(
830 "The following elements in alphabet are not of length one, "
831 f"which leads to violation of size constraints: {not_one_char!r}"
832 )
833 if alphabet in ["ascii", "utf-8"]:
834 warnings.warn(
835 f"st.text({alphabet!r}): it seems like you are trying to use the "
836 f"codec {alphabet!r}. st.text({alphabet!r}) instead generates "
837 f"strings using the literal characters {list(alphabet)!r}. To specify "
838 f"the {alphabet} codec, use st.text(st.characters(codec={alphabet!r})). "
839 "If you intended to use character literals, you can silence this "
840 "warning by reordering the characters.",
841 HypothesisWarning,
842 # this stacklevel is of course incorrect, but breaking out of the
843 # levels of LazyStrategy and validation isn't worthwhile.
844 stacklevel=1,
845 )
846 char_strategy = (
847 characters(categories=(), include_characters=alphabet)
848 if alphabet
849 else nothing()
850 )
851 if (max_size == 0 or char_strategy.is_empty) and not min_size:
852 return just("")
853 # mypy is unhappy with ListStrategy(SearchStrategy[list[Ex]]) and then TextStrategy
854 # setting Ex = str. Mypy is correct to complain because we have an LSP violation
855 # here in the TextStrategy.do_draw override. Would need refactoring to resolve.
856 return TextStrategy(char_strategy, min_size=min_size, max_size=max_size) # type: ignore
857
858
859@overload
860def from_regex(
861 regex: Union[bytes, Pattern[bytes]],
862 *,
863 fullmatch: bool = False,
864) -> SearchStrategy[bytes]: # pragma: no cover
865 ...
866
867
868@overload
869def from_regex(
870 regex: Union[str, Pattern[str]],
871 *,
872 fullmatch: bool = False,
873 alphabet: Union[str, SearchStrategy[str]] = characters(codec="utf-8"),
874) -> SearchStrategy[str]: # pragma: no cover
875 ...
876
877
878@cacheable
879@defines_strategy()
880def from_regex(
881 regex: Union[AnyStr, Pattern[AnyStr]],
882 *,
883 fullmatch: bool = False,
884 alphabet: Union[str, SearchStrategy[str], None] = None,
885) -> SearchStrategy[AnyStr]:
886 r"""Generates strings that contain a match for the given regex (i.e. ones
887 for which :func:`python:re.search` will return a non-None result).
888
889 ``regex`` may be a pattern or :func:`compiled regex <python:re.compile>`.
890 Both byte-strings and unicode strings are supported, and will generate
891 examples of the same type.
892
893 You can use regex flags such as :obj:`python:re.IGNORECASE` or
894 :obj:`python:re.DOTALL` to control generation. Flags can be passed either
895 in compiled regex or inside the pattern with a ``(?iLmsux)`` group.
896
897 Some regular expressions are only partly supported - the underlying
898 strategy checks local matching and relies on filtering to resolve
899 context-dependent expressions. Using too many of these constructs may
900 cause health-check errors as too many examples are filtered out. This
901 mainly includes (positive or negative) lookahead and lookbehind groups.
902
903 If you want the generated string to match the whole regex you should use
904 boundary markers. So e.g. ``r"\A.\Z"`` will return a single character
905 string, while ``"."`` will return any string, and ``r"\A.$"`` will return
906 a single character optionally followed by a ``"\n"``.
907 Alternatively, passing ``fullmatch=True`` will ensure that the whole
908 string is a match, as if you had used the ``\A`` and ``\Z`` markers.
909
910 The ``alphabet=`` argument constrains the characters in the generated
911 string, as for :func:`text`, and is only supported for unicode strings.
912
913 Examples from this strategy shrink towards shorter strings and lower
914 character values, with exact behaviour that may depend on the pattern.
915 """
916 check_type((str, bytes, re.Pattern), regex, "regex")
917 check_type(bool, fullmatch, "fullmatch")
918 pattern = regex.pattern if isinstance(regex, re.Pattern) else regex
919 if alphabet is not None:
920 check_type((str, SearchStrategy), alphabet, "alphabet")
921 if not isinstance(pattern, str):
922 raise InvalidArgument("alphabet= is not supported for bytestrings")
923 alphabet = OneCharStringStrategy.from_alphabet(alphabet)
924 elif isinstance(pattern, str):
925 alphabet = characters(codec="utf-8")
926
927 # TODO: We would like to move this to the top level, but pending some major
928 # refactoring it's hard to do without creating circular imports.
929 from hypothesis.strategies._internal.regex import regex_strategy
930
931 return regex_strategy(regex, fullmatch, alphabet=alphabet)
932
933
934@cacheable
935@defines_strategy(force_reusable_values=True)
936def binary(
937 *,
938 min_size: int = 0,
939 max_size: Optional[int] = None,
940) -> SearchStrategy[bytes]:
941 """Generates :class:`python:bytes`.
942
943 The generated :class:`python:bytes` will have a length of at least ``min_size``
944 and at most ``max_size``. If ``max_size`` is None there is no upper limit.
945
946 Examples from this strategy shrink towards smaller strings and lower byte
947 values.
948 """
949 check_valid_sizes(min_size, max_size)
950 return BytesStrategy(min_size, max_size)
951
952
953@cacheable
954@defines_strategy()
955def randoms(
956 *,
957 note_method_calls: bool = False,
958 use_true_random: bool = False,
959) -> SearchStrategy[random.Random]:
960 """Generates instances of ``random.Random``. The generated Random instances
961 are of a special HypothesisRandom subclass.
962
963 - If ``note_method_calls`` is set to ``True``, Hypothesis will print the
964 randomly drawn values in any falsifying test case. This can be helpful
965 for debugging the behaviour of randomized algorithms.
966 - If ``use_true_random`` is set to ``True`` then values will be drawn from
967 their usual distribution, otherwise they will actually be Hypothesis
968 generated values (and will be shrunk accordingly for any failing test
969 case). Setting ``use_true_random=False`` will tend to expose bugs that
970 would occur with very low probability when it is set to True, and this
971 flag should only be set to True when your code relies on the distribution
972 of values for correctness.
973
974 For managing global state, see the :func:`~hypothesis.strategies.random_module`
975 strategy and :func:`~hypothesis.register_random` function.
976 """
977 check_type(bool, note_method_calls, "note_method_calls")
978 check_type(bool, use_true_random, "use_true_random")
979
980 from hypothesis.strategies._internal.random import RandomStrategy
981
982 return RandomStrategy(
983 use_true_random=use_true_random, note_method_calls=note_method_calls
984 )
985
986
987class RandomModule(SearchStrategy):
988 def do_draw(self, data):
989 # It would be unsafe to do run this method more than once per test case,
990 # because cleanup() runs tasks in FIFO order (at time of writing!).
991 # Fortunately, the random_module() strategy wraps us in shared(), so
992 # it's cached for all but the first of any number of calls.
993 seed = data.draw(integers(0, 2**32 - 1))
994 seed_all, restore_all = get_seeder_and_restorer(seed)
995 seed_all()
996 cleanup(restore_all)
997 return RandomSeeder(seed)
998
999
1000@cacheable
1001@defines_strategy()
1002def random_module() -> SearchStrategy[RandomSeeder]:
1003 """Hypothesis always seeds global PRNGs before running a test, and restores the
1004 previous state afterwards.
1005
1006 If having a fixed seed would unacceptably weaken your tests, and you
1007 cannot use a ``random.Random`` instance provided by
1008 :func:`~hypothesis.strategies.randoms`, this strategy calls
1009 :func:`python:random.seed` with an arbitrary integer and passes you
1010 an opaque object whose repr displays the seed value for debugging.
1011 If ``numpy.random`` is available, that state is also managed, as is anything
1012 managed by :func:`hypothesis.register_random`.
1013
1014 Examples from these strategy shrink to seeds closer to zero.
1015 """
1016 return shared(RandomModule(), key="hypothesis.strategies.random_module()")
1017
1018
1019class BuildsStrategy(SearchStrategy):
1020 def __init__(self, target, args, kwargs):
1021 self.target = target
1022 self.args = args
1023 self.kwargs = kwargs
1024
1025 def do_draw(self, data):
1026 args = [data.draw(a) for a in self.args]
1027 kwargs = {k: data.draw(v) for k, v in self.kwargs.items()}
1028 try:
1029 obj = self.target(*args, **kwargs)
1030 except TypeError as err:
1031 if (
1032 isinstance(self.target, type)
1033 and issubclass(self.target, enum.Enum)
1034 and not (self.args or self.kwargs)
1035 ):
1036 name = self.target.__module__ + "." + self.target.__qualname__
1037 raise InvalidArgument(
1038 f"Calling {name} with no arguments raised an error - "
1039 f"try using sampled_from({name}) instead of builds({name})"
1040 ) from err
1041 if not (self.args or self.kwargs):
1042 from .types import is_a_new_type, is_generic_type
1043
1044 if is_a_new_type(self.target) or is_generic_type(self.target):
1045 raise InvalidArgument(
1046 f"Calling {self.target!r} with no arguments raised an "
1047 f"error - try using from_type({self.target!r}) instead "
1048 f"of builds({self.target!r})"
1049 ) from err
1050 if getattr(self.target, "__no_type_check__", None) is True:
1051 # Note: could use PEP-678 __notes__ here. Migrate over once we're
1052 # using an `exceptiongroup` backport with support for that.
1053 raise TypeError(
1054 "This might be because the @no_type_check decorator prevented "
1055 "Hypothesis from inferring a strategy for some required arguments."
1056 ) from err
1057 raise
1058
1059 current_build_context().record_call(obj, self.target, args, kwargs)
1060 return obj
1061
1062 def validate(self):
1063 tuples(*self.args).validate()
1064 fixed_dictionaries(self.kwargs).validate()
1065
1066 def __repr__(self) -> str:
1067 bits = [get_pretty_function_description(self.target)]
1068 bits.extend(map(repr, self.args))
1069 bits.extend(f"{k}={v!r}" for k, v in self.kwargs.items())
1070 return f"builds({', '.join(bits)})"
1071
1072
1073@cacheable
1074@defines_strategy()
1075def builds(
1076 target: Callable[..., Ex],
1077 /,
1078 *args: SearchStrategy[Any],
1079 **kwargs: Union[SearchStrategy[Any], EllipsisType],
1080) -> SearchStrategy[Ex]:
1081 """Generates values by drawing from ``args`` and ``kwargs`` and passing
1082 them to the callable (provided as the first positional argument) in the
1083 appropriate argument position.
1084
1085 e.g. ``builds(target, integers(), flag=booleans())`` would draw an
1086 integer ``i`` and a boolean ``b`` and call ``target(i, flag=b)``.
1087
1088 If the callable has type annotations, they will be used to infer a strategy
1089 for required arguments that were not passed to builds. You can also tell
1090 builds to infer a strategy for an optional argument by passing ``...``
1091 (:obj:`python:Ellipsis`) as a keyword argument to builds, instead of a strategy for
1092 that argument to the callable.
1093
1094 If the callable is a class defined with :pypi:`attrs`, missing required
1095 arguments will be inferred from the attribute on a best-effort basis,
1096 e.g. by checking :ref:`attrs standard validators <attrs:api-validators>`.
1097 Dataclasses are handled natively by the inference from type hints.
1098
1099 Examples from this strategy shrink by shrinking the argument values to
1100 the callable.
1101 """
1102 if not callable(target):
1103 raise InvalidArgument(
1104 "The first positional argument to builds() must be a callable "
1105 "target to construct."
1106 )
1107
1108 if ... in args: # type: ignore # we only annotated the allowed types
1109 # Avoid an implementation nightmare juggling tuples and worse things
1110 raise InvalidArgument(
1111 "... was passed as a positional argument to "
1112 "builds(), but is only allowed as a keyword arg"
1113 )
1114 required = required_args(target, args, kwargs)
1115 to_infer = {k for k, v in kwargs.items() if v is ...}
1116 if required or to_infer:
1117 if isinstance(target, type) and attr.has(target):
1118 # Use our custom introspection for attrs classes
1119 from hypothesis.strategies._internal.attrs import from_attrs
1120
1121 return from_attrs(target, args, kwargs, required | to_infer)
1122 # Otherwise, try using type hints
1123 hints = get_type_hints(target)
1124 if to_infer - set(hints):
1125 badargs = ", ".join(sorted(to_infer - set(hints)))
1126 raise InvalidArgument(
1127 f"passed ... for {badargs}, but we cannot infer a strategy "
1128 "because these arguments have no type annotation"
1129 )
1130 infer_for = {k: v for k, v in hints.items() if k in (required | to_infer)}
1131 if infer_for:
1132 from hypothesis.strategies._internal.types import _global_type_lookup
1133
1134 for kw, t in infer_for.items():
1135 if t in _global_type_lookup:
1136 kwargs[kw] = from_type(t)
1137 else:
1138 # We defer resolution of these type annotations so that the obvious
1139 # approach to registering recursive types just works. I.e.,
1140 # if we're inside `register_type_strategy(cls, builds(cls, ...))`
1141 # and `...` contains recursion on `cls`. See
1142 # https://github.com/HypothesisWorks/hypothesis/issues/3026
1143 kwargs[kw] = deferred(lambda t=t: from_type(t)) # type: ignore
1144 return BuildsStrategy(target, args, kwargs)
1145
1146
1147@cacheable
1148@defines_strategy(never_lazy=True)
1149def from_type(thing: type[T]) -> SearchStrategy[T]:
1150 """Looks up the appropriate search strategy for the given type.
1151
1152 ``from_type`` is used internally to fill in missing arguments to
1153 :func:`~hypothesis.strategies.builds` and can be used interactively
1154 to explore what strategies are available or to debug type resolution.
1155
1156 You can use :func:`~hypothesis.strategies.register_type_strategy` to
1157 handle your custom types, or to globally redefine certain strategies -
1158 for example excluding NaN from floats, or use timezone-aware instead of
1159 naive time and datetime strategies.
1160
1161 The resolution logic may be changed in a future version, but currently
1162 tries these five options:
1163
1164 1. If ``thing`` is in the default lookup mapping or user-registered lookup,
1165 return the corresponding strategy. The default lookup covers all types
1166 with Hypothesis strategies, including extras where possible.
1167 2. If ``thing`` is from the :mod:`python:typing` module, return the
1168 corresponding strategy (special logic).
1169 3. If ``thing`` has one or more subtypes in the merged lookup, return
1170 the union of the strategies for those types that are not subtypes of
1171 other elements in the lookup.
1172 4. Finally, if ``thing`` has type annotations for all required arguments,
1173 and is not an abstract class, it is resolved via
1174 :func:`~hypothesis.strategies.builds`.
1175 5. Because :mod:`abstract types <python:abc>` cannot be instantiated,
1176 we treat abstract types as the union of their concrete subclasses.
1177 Note that this lookup works via inheritance but not via
1178 :obj:`~python:abc.ABCMeta.register`, so you may still need to use
1179 :func:`~hypothesis.strategies.register_type_strategy`.
1180
1181 There is a valuable recipe for leveraging ``from_type()`` to generate
1182 "everything except" values from a specified type. I.e.
1183
1184 .. code-block:: python
1185
1186 def everything_except(excluded_types):
1187 return (
1188 from_type(type)
1189 .flatmap(from_type)
1190 .filter(lambda x: not isinstance(x, excluded_types))
1191 )
1192
1193 For example, ``everything_except(int)`` returns a strategy that can
1194 generate anything that ``from_type()`` can ever generate, except for
1195 instances of :class:`python:int`, and excluding instances of types
1196 added via :func:`~hypothesis.strategies.register_type_strategy`.
1197
1198 This is useful when writing tests which check that invalid input is
1199 rejected in a certain way.
1200 """
1201 try:
1202 with warnings.catch_warnings():
1203 warnings.simplefilter("error")
1204 return _from_type(thing)
1205 except Exception:
1206 return _from_type_deferred(thing)
1207
1208
1209def _from_type_deferred(thing: type[Ex]) -> SearchStrategy[Ex]:
1210 # This tricky little dance is because we want to show the repr of the actual
1211 # underlying strategy wherever possible, as a form of user education, but
1212 # would prefer to fall back to the default "from_type(...)" repr instead of
1213 # "deferred(...)" for recursive types or invalid arguments.
1214 try:
1215 thing_repr = nicerepr(thing)
1216 if hasattr(thing, "__module__"):
1217 module_prefix = f"{thing.__module__}."
1218 if not thing_repr.startswith(module_prefix):
1219 thing_repr = module_prefix + thing_repr
1220 repr_ = f"from_type({thing_repr})"
1221 except Exception: # pragma: no cover
1222 repr_ = None
1223 return LazyStrategy(
1224 lambda thing: deferred(lambda: _from_type(thing)),
1225 (thing,),
1226 {},
1227 force_repr=repr_,
1228 )
1229
1230
1231_recurse_guard: ContextVar = ContextVar("recurse_guard")
1232
1233
1234def _from_type(thing: type[Ex]) -> SearchStrategy[Ex]:
1235 # TODO: We would like to move this to the top level, but pending some major
1236 # refactoring it's hard to do without creating circular imports.
1237 from hypothesis.strategies._internal import types
1238
1239 def as_strategy(strat_or_callable, thing):
1240 # User-provided strategies need some validation, and callables even more
1241 # of it. We do this in three places, hence the helper function
1242 if not isinstance(strat_or_callable, SearchStrategy):
1243 assert callable(strat_or_callable) # Validated in register_type_strategy
1244 strategy = strat_or_callable(thing)
1245 else:
1246 strategy = strat_or_callable
1247 if strategy is NotImplemented:
1248 return NotImplemented
1249 if not isinstance(strategy, SearchStrategy):
1250 raise ResolutionFailed(
1251 f"Error: {thing} was registered for {nicerepr(strat_or_callable)}, "
1252 f"but returned non-strategy {strategy!r}"
1253 )
1254 if strategy.is_empty:
1255 raise ResolutionFailed(f"Error: {thing!r} resolved to an empty strategy")
1256 return strategy
1257
1258 def from_type_guarded(thing):
1259 """Returns the result of producer, or ... if recursion on thing is encountered"""
1260 try:
1261 recurse_guard = _recurse_guard.get()
1262 except LookupError:
1263 # We can't simply define the contextvar with default=[], as the
1264 # default object would be shared across contexts
1265 _recurse_guard.set(recurse_guard := [])
1266 if thing in recurse_guard:
1267 raise RewindRecursive(thing)
1268 recurse_guard.append(thing)
1269 try:
1270 return _from_type(thing)
1271 except RewindRecursive as rr:
1272 if rr.target != thing:
1273 raise
1274 return ... # defer resolution
1275 finally:
1276 recurse_guard.pop()
1277
1278 # Let registered extra modules handle their own recognized types first, before
1279 # e.g. Unions are resolved
1280 try:
1281 known = thing in types._global_type_lookup
1282 except TypeError:
1283 # thing is not always hashable!
1284 pass
1285 else:
1286 if not known:
1287 for module, resolver in types._global_extra_lookup.items():
1288 if module in sys.modules:
1289 strat = resolver(thing)
1290 if strat is not None:
1291 return strat
1292 if not isinstance(thing, type):
1293 if types.is_a_new_type(thing):
1294 # Check if we have an explicitly registered strategy for this thing,
1295 # resolve it so, and otherwise resolve as for the base type.
1296 if thing in types._global_type_lookup:
1297 strategy = as_strategy(types._global_type_lookup[thing], thing)
1298 if strategy is not NotImplemented:
1299 return strategy
1300 return _from_type(thing.__supertype__)
1301 if types.is_a_type_alias_type(
1302 thing
1303 ): # pragma: no cover # covered by 3.12+ tests
1304 if thing in types._global_type_lookup:
1305 strategy = as_strategy(types._global_type_lookup[thing], thing)
1306 if strategy is not NotImplemented:
1307 return strategy
1308 return _from_type(thing.__value__)
1309 # Unions are not instances of `type` - but we still want to resolve them!
1310 if types.is_a_union(thing):
1311 args = sorted(thing.__args__, key=types.type_sorting_key)
1312 return one_of([_from_type(t) for t in args])
1313 if thing in types.LiteralStringTypes: # pragma: no cover
1314 # We can't really cover this because it needs either
1315 # typing-extensions or python3.11+ typing.
1316 # `LiteralString` from runtime's point of view is just a string.
1317 # Fallback to regular text.
1318 return text()
1319 # We also have a special case for TypeVars.
1320 # They are represented as instances like `~T` when they come here.
1321 # We need to work with their type instead.
1322 if isinstance(thing, TypeVar) and type(thing) in types._global_type_lookup:
1323 strategy = as_strategy(types._global_type_lookup[type(thing)], thing)
1324 if strategy is not NotImplemented:
1325 return strategy
1326 if not types.is_a_type(thing):
1327 if isinstance(thing, str):
1328 # See https://github.com/HypothesisWorks/hypothesis/issues/3016
1329 raise InvalidArgument(
1330 f"Got {thing!r} as a type annotation, but the forward-reference "
1331 "could not be resolved from a string to a type. Consider using "
1332 "`from __future__ import annotations` instead of forward-reference "
1333 "strings."
1334 )
1335 raise InvalidArgument(f"{thing=} must be a type") # pragma: no cover
1336 if thing in types.NON_RUNTIME_TYPES:
1337 # Some code like `st.from_type(TypeAlias)` does not make sense.
1338 # Because there are types in python that do not exist in runtime.
1339 raise InvalidArgument(
1340 f"Could not resolve {thing!r} to a strategy, "
1341 f"because there is no such thing as a runtime instance of {thing!r}"
1342 )
1343 # Now that we know `thing` is a type, the first step is to check for an
1344 # explicitly registered strategy. This is the best (and hopefully most
1345 # common) way to resolve a type to a strategy. Note that the value in the
1346 # lookup may be a strategy or a function from type -> strategy; and we
1347 # convert empty results into an explicit error.
1348 try:
1349 if thing in types._global_type_lookup:
1350 strategy = as_strategy(types._global_type_lookup[thing], thing)
1351 if strategy is not NotImplemented:
1352 return strategy
1353 elif (
1354 isinstance(thing, GenericAlias)
1355 and (to := get_origin(thing)) in types._global_type_lookup
1356 ):
1357 strategy = as_strategy(types._global_type_lookup[to], thing)
1358 if strategy is not NotImplemented:
1359 return strategy
1360 except TypeError: # pragma: no cover
1361 # This was originally due to a bizarre divergence in behaviour on Python 3.9.0:
1362 # typing.Callable[[], foo] has __args__ = (foo,) but collections.abc.Callable
1363 # has __args__ = ([], foo); and as a result is non-hashable.
1364 # We've kept it because we turn out to have more type errors from... somewhere.
1365 # FIXME: investigate that, maybe it should be fixed more precisely?
1366 pass
1367 if (hasattr(typing, "_TypedDictMeta") and type(thing) is typing._TypedDictMeta) or (
1368 hasattr(types.typing_extensions, "_TypedDictMeta") # type: ignore
1369 and type(thing) is types.typing_extensions._TypedDictMeta # type: ignore
1370 ): # pragma: no cover
1371
1372 def _get_annotation_arg(key, annotation_type):
1373 try:
1374 return get_args(annotation_type)[0]
1375 except IndexError:
1376 raise InvalidArgument(
1377 f"`{key}: {annotation_type.__name__}` is not a valid type annotation"
1378 ) from None
1379
1380 # Taken from `Lib/typing.py` and modified:
1381 def _get_typeddict_qualifiers(key, annotation_type):
1382 qualifiers = []
1383 while True:
1384 annotation_origin = types.extended_get_origin(annotation_type)
1385 if annotation_origin is Annotated:
1386 if annotation_args := get_args(annotation_type):
1387 annotation_type = annotation_args[0]
1388 else:
1389 break
1390 elif annotation_origin in types.RequiredTypes:
1391 qualifiers.append(types.RequiredTypes)
1392 annotation_type = _get_annotation_arg(key, annotation_type)
1393 elif annotation_origin in types.NotRequiredTypes:
1394 qualifiers.append(types.NotRequiredTypes)
1395 annotation_type = _get_annotation_arg(key, annotation_type)
1396 elif annotation_origin in types.ReadOnlyTypes:
1397 qualifiers.append(types.ReadOnlyTypes)
1398 annotation_type = _get_annotation_arg(key, annotation_type)
1399 else:
1400 break
1401 return set(qualifiers), annotation_type
1402
1403 # The __optional_keys__ attribute may or may not be present, but if there's no
1404 # way to tell and we just have to assume that everything is required.
1405 # See https://github.com/python/cpython/pull/17214 for details.
1406 optional = set(getattr(thing, "__optional_keys__", ()))
1407 required = set(
1408 getattr(thing, "__required_keys__", get_type_hints(thing).keys())
1409 )
1410 anns = {}
1411 for k, v in get_type_hints(thing).items():
1412 qualifiers, v = _get_typeddict_qualifiers(k, v)
1413 # We ignore `ReadOnly` type for now, only unwrap it.
1414 if types.RequiredTypes in qualifiers:
1415 optional.discard(k)
1416 required.add(k)
1417 if types.NotRequiredTypes in qualifiers:
1418 optional.add(k)
1419 required.discard(k)
1420
1421 anns[k] = from_type_guarded(v)
1422 if anns[k] is ...:
1423 anns[k] = _from_type_deferred(v)
1424
1425 if not required.isdisjoint(optional): # pragma: no cover
1426 # It is impossible to cover, because `typing.py` or `typing-extensions`
1427 # won't allow creating incorrect TypedDicts,
1428 # this is just a sanity check from our side.
1429 raise InvalidArgument(
1430 f"Required keys overlap with optional keys in a TypedDict:"
1431 f" {required=}, {optional=}"
1432 )
1433 if (
1434 (not anns)
1435 and thing.__annotations__
1436 and ".<locals>." in getattr(thing, "__qualname__", "")
1437 ):
1438 raise InvalidArgument("Failed to retrieve type annotations for local type")
1439 return fixed_dictionaries( # type: ignore
1440 mapping={k: v for k, v in anns.items() if k in required},
1441 optional={k: v for k, v in anns.items() if k in optional},
1442 )
1443
1444 # If there's no explicitly registered strategy, maybe a subtype of thing
1445 # is registered - if so, we can resolve it to the subclass strategy.
1446 # We'll start by checking if thing is from from the typing module,
1447 # because there are several special cases that don't play well with
1448 # subclass and instance checks.
1449 if isinstance(thing, types.typing_root_type) or (
1450 isinstance(get_origin(thing), type) and get_args(thing)
1451 ):
1452 return types.from_typing_type(thing)
1453 # If it's not from the typing module, we get all registered types that are
1454 # a subclass of `thing` and are not themselves a subtype of any other such
1455 # type. For example, `Number -> integers() | floats()`, but bools() is
1456 # not included because bool is a subclass of int as well as Number.
1457 strategies = [
1458 s
1459 for s in (
1460 as_strategy(v, thing)
1461 for k, v in sorted(types._global_type_lookup.items(), key=repr)
1462 if isinstance(k, type)
1463 and issubclass(k, thing)
1464 and sum(types.try_issubclass(k, typ) for typ in types._global_type_lookup)
1465 == 1
1466 )
1467 if s is not NotImplemented
1468 ]
1469 if any(not s.is_empty for s in strategies):
1470 return one_of(strategies)
1471 # If we don't have a strategy registered for this type or any subtype, we
1472 # may be able to fall back on type annotations.
1473 if issubclass(thing, enum.Enum):
1474 return sampled_from(thing)
1475 # Finally, try to build an instance by calling the type object. Unlike builds(),
1476 # this block *does* try to infer strategies for arguments with default values.
1477 # That's because of the semantic different; builds() -> "call this with ..."
1478 # so we only infer when *not* doing so would be an error; from_type() -> "give
1479 # me arbitrary instances" so the greater variety is acceptable.
1480 # And if it's *too* varied, express your opinions with register_type_strategy()
1481 if not isabstract(thing):
1482 # If we know that builds(thing) will fail, give a better error message
1483 required = required_args(thing)
1484 if required and not (
1485 required.issubset(get_type_hints(thing))
1486 or attr.has(thing)
1487 or is_typed_named_tuple(thing) # weird enough that we have a specific check
1488 ):
1489 raise ResolutionFailed(
1490 f"Could not resolve {thing!r} to a strategy; consider "
1491 "using register_type_strategy"
1492 )
1493 try:
1494 hints = get_type_hints(thing)
1495 params = get_signature(thing).parameters
1496 except Exception:
1497 params = {} # type: ignore
1498
1499 posonly_args = []
1500 kwargs = {}
1501 for k, p in params.items():
1502 if (
1503 p.kind in (p.POSITIONAL_ONLY, p.POSITIONAL_OR_KEYWORD, p.KEYWORD_ONLY)
1504 and k in hints
1505 and k != "return"
1506 ):
1507 ps = from_type_guarded(hints[k])
1508 if p.default is not Parameter.empty and ps is not ...:
1509 ps = just(p.default) | ps
1510 if p.kind is Parameter.POSITIONAL_ONLY:
1511 # builds() doesn't infer strategies for positional args, so:
1512 if ps is ...: # pragma: no cover # rather fiddly to test
1513 if p.default is Parameter.empty:
1514 raise ResolutionFailed(
1515 f"Could not resolve {thing!r} to a strategy; "
1516 "consider using register_type_strategy"
1517 )
1518 ps = just(p.default)
1519 posonly_args.append(ps)
1520 else:
1521 kwargs[k] = ps
1522 if (
1523 params
1524 and not (posonly_args or kwargs)
1525 and not issubclass(thing, BaseException)
1526 ):
1527 from_type_repr = repr_call(from_type, (thing,), {})
1528 builds_repr = repr_call(builds, (thing,), {})
1529 warnings.warn(
1530 f"{from_type_repr} resolved to {builds_repr}, because we could not "
1531 "find any (non-varargs) arguments. Use st.register_type_strategy() "
1532 "to resolve to a strategy which can generate more than one value, "
1533 "or silence this warning.",
1534 SmallSearchSpaceWarning,
1535 stacklevel=2,
1536 )
1537 return builds(thing, *posonly_args, **kwargs)
1538 # And if it's an abstract type, we'll resolve to a union of subclasses instead.
1539 subclasses = thing.__subclasses__()
1540 if not subclasses:
1541 raise ResolutionFailed(
1542 f"Could not resolve {thing!r} to a strategy, because it is an abstract "
1543 "type without any subclasses. Consider using register_type_strategy"
1544 )
1545 subclass_strategies: SearchStrategy = nothing()
1546 for sc in subclasses:
1547 try:
1548 subclass_strategies |= _from_type(sc)
1549 except Exception:
1550 pass
1551 if subclass_strategies.is_empty:
1552 # We're unable to resolve subclasses now, but we might be able to later -
1553 # so we'll just go back to the mixed distribution.
1554 return sampled_from(subclasses).flatmap(_from_type)
1555 return subclass_strategies
1556
1557
1558@cacheable
1559@defines_strategy(force_reusable_values=True)
1560def fractions(
1561 min_value: Optional[Union[Real, str]] = None,
1562 max_value: Optional[Union[Real, str]] = None,
1563 *,
1564 max_denominator: Optional[int] = None,
1565) -> SearchStrategy[Fraction]:
1566 """Returns a strategy which generates Fractions.
1567
1568 If ``min_value`` is not None then all generated values are no less than
1569 ``min_value``. If ``max_value`` is not None then all generated values are no
1570 greater than ``max_value``. ``min_value`` and ``max_value`` may be anything accepted
1571 by the :class:`~fractions.Fraction` constructor.
1572
1573 If ``max_denominator`` is not None then the denominator of any generated
1574 values is no greater than ``max_denominator``. Note that ``max_denominator`` must
1575 be None or a positive integer.
1576
1577 Examples from this strategy shrink towards smaller denominators, then
1578 closer to zero.
1579 """
1580 min_value = try_convert(Fraction, min_value, "min_value")
1581 max_value = try_convert(Fraction, max_value, "max_value")
1582 # These assertions tell Mypy what happened in try_convert
1583 assert min_value is None or isinstance(min_value, Fraction)
1584 assert max_value is None or isinstance(max_value, Fraction)
1585
1586 check_valid_interval(min_value, max_value, "min_value", "max_value")
1587 check_valid_integer(max_denominator, "max_denominator")
1588
1589 if max_denominator is not None:
1590 if max_denominator < 1:
1591 raise InvalidArgument(f"{max_denominator=} must be >= 1")
1592 if min_value is not None and min_value.denominator > max_denominator:
1593 raise InvalidArgument(
1594 f"The {min_value=} has a denominator greater than the "
1595 f"{max_denominator=}"
1596 )
1597 if max_value is not None and max_value.denominator > max_denominator:
1598 raise InvalidArgument(
1599 f"The {max_value=} has a denominator greater than the "
1600 f"{max_denominator=}"
1601 )
1602
1603 if min_value is not None and min_value == max_value:
1604 return just(min_value)
1605
1606 def dm_func(denom):
1607 """Take denom, construct numerator strategy, and build fraction."""
1608 # Four cases of algebra to get integer bounds and scale factor.
1609 min_num, max_num = None, None
1610 if max_value is None and min_value is None:
1611 pass
1612 elif min_value is None:
1613 max_num = denom * max_value.numerator
1614 denom *= max_value.denominator
1615 elif max_value is None:
1616 min_num = denom * min_value.numerator
1617 denom *= min_value.denominator
1618 else:
1619 low = min_value.numerator * max_value.denominator
1620 high = max_value.numerator * min_value.denominator
1621 scale = min_value.denominator * max_value.denominator
1622 # After calculating our integer bounds and scale factor, we remove
1623 # the gcd to avoid drawing more bytes for the example than needed.
1624 # Note that `div` can be at most equal to `scale`.
1625 div = math.gcd(scale, math.gcd(low, high))
1626 min_num = denom * low // div
1627 max_num = denom * high // div
1628 denom *= scale // div
1629
1630 return builds(
1631 Fraction, integers(min_value=min_num, max_value=max_num), just(denom)
1632 )
1633
1634 if max_denominator is None:
1635 return integers(min_value=1).flatmap(dm_func)
1636
1637 return (
1638 integers(1, max_denominator)
1639 .flatmap(dm_func)
1640 .map(lambda f: f.limit_denominator(max_denominator))
1641 )
1642
1643
1644def _as_finite_decimal(
1645 value: Union[Real, str, None], name: str, allow_infinity: Optional[bool]
1646) -> Optional[Decimal]:
1647 """Convert decimal bounds to decimals, carefully."""
1648 assert name in ("min_value", "max_value")
1649 if value is None:
1650 return None
1651 if not isinstance(value, Decimal):
1652 with localcontext(Context()): # ensure that default traps are enabled
1653 value = try_convert(Decimal, value, name)
1654 assert isinstance(value, Decimal)
1655 if value.is_finite():
1656 return value
1657 if value.is_infinite() and (value < 0 if "min" in name else value > 0):
1658 if allow_infinity or allow_infinity is None:
1659 return None
1660 raise InvalidArgument(f"{allow_infinity=}, but {name}={value!r}")
1661 # This could be infinity, quiet NaN, or signalling NaN
1662 raise InvalidArgument(f"Invalid {name}={value!r}")
1663
1664
1665@cacheable
1666@defines_strategy(force_reusable_values=True)
1667def decimals(
1668 min_value: Optional[Union[Real, str]] = None,
1669 max_value: Optional[Union[Real, str]] = None,
1670 *,
1671 allow_nan: Optional[bool] = None,
1672 allow_infinity: Optional[bool] = None,
1673 places: Optional[int] = None,
1674) -> SearchStrategy[Decimal]:
1675 """Generates instances of :class:`python:decimal.Decimal`, which may be:
1676
1677 - A finite rational number, between ``min_value`` and ``max_value``.
1678 - Not a Number, if ``allow_nan`` is True. None means "allow NaN, unless
1679 ``min_value`` and ``max_value`` are not None".
1680 - Positive or negative infinity, if ``max_value`` and ``min_value``
1681 respectively are None, and ``allow_infinity`` is not False. None means
1682 "allow infinity, unless excluded by the min and max values".
1683
1684 Note that where floats have one ``NaN`` value, Decimals have four: signed,
1685 and either *quiet* or *signalling*. See `the decimal module docs
1686 <https://docs.python.org/3/library/decimal.html#special-values>`_ for
1687 more information on special values.
1688
1689 If ``places`` is not None, all finite values drawn from the strategy will
1690 have that number of digits after the decimal place.
1691
1692 Examples from this strategy do not have a well defined shrink order but
1693 try to maximize human readability when shrinking.
1694 """
1695 # Convert min_value and max_value to Decimal values, and validate args
1696 check_valid_integer(places, "places")
1697 if places is not None and places < 0:
1698 raise InvalidArgument(f"{places=} may not be negative")
1699 min_value = _as_finite_decimal(min_value, "min_value", allow_infinity)
1700 max_value = _as_finite_decimal(max_value, "max_value", allow_infinity)
1701 check_valid_interval(min_value, max_value, "min_value", "max_value")
1702 if allow_infinity and (None not in (min_value, max_value)):
1703 raise InvalidArgument("Cannot allow infinity between finite bounds")
1704 # Set up a strategy for finite decimals. Note that both floating and
1705 # fixed-point decimals require careful handling to remain isolated from
1706 # any external precision context - in short, we always work out the
1707 # required precision for lossless operation and use context methods.
1708 if places is not None:
1709 # Fixed-point decimals are basically integers with a scale factor
1710 def ctx(val):
1711 """Return a context in which this value is lossless."""
1712 precision = ceil(math.log10(abs(val) or 1)) + places + 1
1713 return Context(prec=max([precision, 1]))
1714
1715 def int_to_decimal(val):
1716 context = ctx(val)
1717 return context.quantize(context.multiply(val, factor), factor)
1718
1719 factor = Decimal(10) ** -places
1720 min_num, max_num = None, None
1721 if min_value is not None:
1722 min_num = ceil(ctx(min_value).divide(min_value, factor))
1723 if max_value is not None:
1724 max_num = floor(ctx(max_value).divide(max_value, factor))
1725 if min_num is not None and max_num is not None and min_num > max_num:
1726 raise InvalidArgument(
1727 f"There are no decimals with {places} places between "
1728 f"{min_value=} and {max_value=}"
1729 )
1730 strat = integers(min_num, max_num).map(int_to_decimal)
1731 else:
1732 # Otherwise, they're like fractions featuring a power of ten
1733 def fraction_to_decimal(val):
1734 precision = (
1735 ceil(math.log10(abs(val.numerator) or 1) + math.log10(val.denominator))
1736 + 1
1737 )
1738 return Context(prec=precision or 1).divide(
1739 Decimal(val.numerator), val.denominator
1740 )
1741
1742 strat = fractions(min_value, max_value).map(fraction_to_decimal)
1743 # Compose with sampled_from for infinities and NaNs as appropriate
1744 special: list[Decimal] = []
1745 if allow_nan or (allow_nan is None and (None in (min_value, max_value))):
1746 special.extend(map(Decimal, ("NaN", "-NaN", "sNaN", "-sNaN")))
1747 if allow_infinity or (allow_infinity is None and max_value is None):
1748 special.append(Decimal("Infinity"))
1749 if allow_infinity or (allow_infinity is None and min_value is None):
1750 special.append(Decimal("-Infinity"))
1751 return strat | (sampled_from(special) if special else nothing())
1752
1753
1754@defines_strategy(never_lazy=True)
1755def recursive(
1756 base: SearchStrategy[Ex],
1757 extend: Callable[[SearchStrategy[Any]], SearchStrategy[T]],
1758 *,
1759 max_leaves: int = 100,
1760) -> SearchStrategy[Union[T, Ex]]:
1761 """base: A strategy to start from.
1762
1763 extend: A function which takes a strategy and returns a new strategy.
1764
1765 max_leaves: The maximum number of elements to be drawn from base on a given
1766 run.
1767
1768 This returns a strategy ``S`` such that ``S = extend(base | S)``. That is,
1769 values may be drawn from base, or from any strategy reachable by mixing
1770 applications of | and extend.
1771
1772 An example may clarify: ``recursive(booleans(), lists)`` would return a
1773 strategy that may return arbitrarily nested and mixed lists of booleans.
1774 So e.g. ``False``, ``[True]``, ``[False, []]``, and ``[[[[True]]]]`` are
1775 all valid values to be drawn from that strategy.
1776
1777 Examples from this strategy shrink by trying to reduce the amount of
1778 recursion and by shrinking according to the shrinking behaviour of base
1779 and the result of extend.
1780
1781 """
1782
1783 return RecursiveStrategy(base, extend, max_leaves)
1784
1785
1786class PermutationStrategy(SearchStrategy):
1787 def __init__(self, values):
1788 self.values = values
1789
1790 def do_draw(self, data):
1791 # Reversed Fisher-Yates shuffle: swap each element with itself or with
1792 # a later element. This shrinks i==j for each element, i.e. to no
1793 # change. We don't consider the last element as it's always a no-op.
1794 result = list(self.values)
1795 for i in range(len(result) - 1):
1796 j = data.draw_integer(i, len(result) - 1)
1797 result[i], result[j] = result[j], result[i]
1798 return result
1799
1800
1801@defines_strategy()
1802def permutations(values: Sequence[T]) -> SearchStrategy[list[T]]:
1803 """Return a strategy which returns permutations of the ordered collection
1804 ``values``.
1805
1806 Examples from this strategy shrink by trying to become closer to the
1807 original order of values.
1808 """
1809 values = check_sample(values, "permutations")
1810 if not values:
1811 return builds(list)
1812
1813 return PermutationStrategy(values)
1814
1815
1816class CompositeStrategy(SearchStrategy):
1817 def __init__(self, definition, args, kwargs):
1818 self.definition = definition
1819 self.args = args
1820 self.kwargs = kwargs
1821
1822 def do_draw(self, data):
1823 return self.definition(data.draw, *self.args, **self.kwargs)
1824
1825 def calc_label(self) -> int:
1826 return calc_label_from_cls(self.definition)
1827
1828
1829class DrawFn(Protocol):
1830 """This type only exists so that you can write type hints for functions
1831 decorated with :func:`@composite <hypothesis.strategies.composite>`.
1832
1833 .. code-block:: python
1834
1835 def draw(strategy: SearchStrategy[Ex], label: object = None) -> Ex: ...
1836
1837 @composite
1838 def list_and_index(draw: DrawFn) -> tuple[int, str]:
1839 i = draw(integers()) # type of `i` inferred as 'int'
1840 s = draw(text()) # type of `s` inferred as 'str'
1841 return i, s
1842 """
1843
1844 def __init__(self):
1845 raise TypeError("Protocols cannot be instantiated") # pragma: no cover
1846
1847 # Protocol overrides our signature for __init__,
1848 # so we override it right back to make the docs look nice.
1849 __signature__: Signature = Signature(parameters=[])
1850
1851 # We define this as a callback protocol because a simple typing.Callable is
1852 # insufficient to fully represent the interface, due to the optional `label`
1853 # parameter.
1854 def __call__(self, strategy: SearchStrategy[Ex], label: object = None) -> Ex:
1855 raise NotImplementedError
1856
1857
1858def _composite(f):
1859 # Wrapped below, using ParamSpec if available
1860 if isinstance(f, (classmethod, staticmethod)):
1861 special_method = type(f)
1862 f = f.__func__
1863 else:
1864 special_method = None
1865
1866 sig = get_signature(f)
1867 params = tuple(sig.parameters.values())
1868
1869 if not (params and "POSITIONAL" in params[0].kind.name):
1870 raise InvalidArgument(
1871 "Functions wrapped with composite must take at least one "
1872 "positional argument."
1873 )
1874 if params[0].default is not sig.empty:
1875 raise InvalidArgument("A default value for initial argument will never be used")
1876 if not (f is typing._overload_dummy or is_first_param_referenced_in_function(f)):
1877 note_deprecation(
1878 "There is no reason to use @st.composite on a function which "
1879 "does not call the provided draw() function internally.",
1880 since="2022-07-17",
1881 has_codemod=False,
1882 )
1883 if get_origin(sig.return_annotation) is SearchStrategy:
1884 ret_repr = repr(sig.return_annotation).replace("hypothesis.strategies.", "st.")
1885 warnings.warn(
1886 f"Return-type annotation is `{ret_repr}`, but the decorated "
1887 "function should return a value (not a strategy)",
1888 HypothesisWarning,
1889 stacklevel=3 if sys.version_info[:2] > (3, 9) else 5, # ugh
1890 )
1891 if params[0].kind.name != "VAR_POSITIONAL":
1892 params = params[1:]
1893 newsig = sig.replace(
1894 parameters=params,
1895 return_annotation=(
1896 SearchStrategy
1897 if sig.return_annotation is sig.empty
1898 else SearchStrategy[sig.return_annotation]
1899 ),
1900 )
1901
1902 @defines_strategy()
1903 @define_function_signature(f.__name__, f.__doc__, newsig)
1904 def accept(*args, **kwargs):
1905 return CompositeStrategy(f, args, kwargs)
1906
1907 accept.__module__ = f.__module__
1908 accept.__signature__ = newsig
1909 if special_method is not None:
1910 return special_method(accept)
1911 return accept
1912
1913
1914composite_doc = """
1915Defines a strategy that is built out of potentially arbitrarily many other
1916strategies.
1917
1918@composite provides a callable ``draw`` as the first parameter to the decorated
1919function, which can be used to dynamically draw a value from any strategy. For
1920example:
1921
1922.. code-block:: python
1923
1924 from hypothesis import strategies as st, given
1925
1926 @st.composite
1927 def values(draw):
1928 n1 = draw(st.integers())
1929 n2 = draw(st.integers(min_value=n1))
1930 return (n1, n2)
1931
1932 @given(values())
1933 def f(value):
1934 (n1, n2) = value
1935 assert n1 <= n2
1936
1937@composite cannot mix test code and generation code. If you need that, use
1938|st.data|.
1939
1940If :func:`@composite <hypothesis.strategies.composite>` is used to decorate a
1941method or classmethod, the ``draw`` argument must come before ``self`` or
1942``cls``. While we therefore recommend writing strategies as standalone functions
1943and using |st.register_type_strategy| to associate them with a class, methods
1944are supported and the ``@composite`` decorator may be applied either before or
1945after ``@classmethod`` or ``@staticmethod``. See :issue:`2578` and :pull:`2634`
1946for more details.
1947
1948Examples from this strategy shrink by shrinking the output of each draw call.
1949"""
1950if typing.TYPE_CHECKING or ParamSpec is not None:
1951 P = ParamSpec("P")
1952
1953 def composite(
1954 f: Callable[Concatenate[DrawFn, P], Ex],
1955 ) -> Callable[P, SearchStrategy[Ex]]:
1956 return _composite(f)
1957
1958else: # pragma: no cover
1959
1960 @cacheable
1961 def composite(f: Callable[..., Ex]) -> Callable[..., SearchStrategy[Ex]]:
1962 return _composite(f)
1963
1964
1965composite.__doc__ = composite_doc
1966
1967
1968@defines_strategy(force_reusable_values=True)
1969@cacheable
1970def complex_numbers(
1971 *,
1972 min_magnitude: Real = 0,
1973 max_magnitude: Optional[Real] = None,
1974 allow_infinity: Optional[bool] = None,
1975 allow_nan: Optional[bool] = None,
1976 allow_subnormal: bool = True,
1977 width: Literal[32, 64, 128] = 128,
1978) -> SearchStrategy[complex]:
1979 """Returns a strategy that generates :class:`~python:complex`
1980 numbers.
1981
1982 This strategy draws complex numbers with constrained magnitudes.
1983 The ``min_magnitude`` and ``max_magnitude`` parameters should be
1984 non-negative :class:`~python:numbers.Real` numbers; a value
1985 of ``None`` corresponds an infinite upper bound.
1986
1987 If ``min_magnitude`` is nonzero or ``max_magnitude`` is finite, it
1988 is an error to enable ``allow_nan``. If ``max_magnitude`` is finite,
1989 it is an error to enable ``allow_infinity``.
1990
1991 ``allow_infinity``, ``allow_nan``, and ``allow_subnormal`` are
1992 applied to each part of the complex number separately, as for
1993 :func:`~hypothesis.strategies.floats`.
1994
1995 The magnitude constraints are respected up to a relative error
1996 of (around) floating-point epsilon, due to implementation via
1997 the system ``sqrt`` function.
1998
1999 The ``width`` argument specifies the maximum number of bits of precision
2000 required to represent the entire generated complex number.
2001 Valid values are 32, 64 or 128, which correspond to the real and imaginary
2002 components each having width 16, 32 or 64, respectively.
2003 Passing ``width=64`` will still use the builtin 128-bit
2004 :class:`~python:complex` class, but always for values which can be
2005 exactly represented as two 32-bit floats.
2006
2007 Examples from this strategy shrink by shrinking their real and
2008 imaginary parts, as :func:`~hypothesis.strategies.floats`.
2009
2010 If you need to generate complex numbers with particular real and
2011 imaginary parts or relationships between parts, consider using
2012 :func:`builds(complex, ...) <hypothesis.strategies.builds>` or
2013 :func:`@composite <hypothesis.strategies.composite>` respectively.
2014 """
2015 check_valid_magnitude(min_magnitude, "min_magnitude")
2016 check_valid_magnitude(max_magnitude, "max_magnitude")
2017 check_valid_interval(min_magnitude, max_magnitude, "min_magnitude", "max_magnitude")
2018 if max_magnitude == math.inf:
2019 max_magnitude = None
2020
2021 if allow_infinity is None:
2022 allow_infinity = bool(max_magnitude is None)
2023 elif allow_infinity and max_magnitude is not None:
2024 raise InvalidArgument(f"Cannot have {allow_infinity=} with {max_magnitude=}")
2025 if allow_nan is None:
2026 allow_nan = bool(min_magnitude == 0 and max_magnitude is None)
2027 elif allow_nan and not (min_magnitude == 0 and max_magnitude is None):
2028 raise InvalidArgument(
2029 f"Cannot have {allow_nan=}, {min_magnitude=}, {max_magnitude=}"
2030 )
2031 check_type(bool, allow_subnormal, "allow_subnormal")
2032 if width not in (32, 64, 128):
2033 raise InvalidArgument(
2034 f"{width=}, but must be 32, 64 or 128 (other complex dtypes "
2035 "such as complex192 or complex256 are not supported)"
2036 # For numpy, these types would be supported (but not by CPython):
2037 # https://numpy.org/doc/stable/reference/arrays.scalars.html#complex-floating-point-types
2038 )
2039 component_width = width // 2
2040 allow_kw = {
2041 "allow_nan": allow_nan,
2042 "allow_infinity": allow_infinity,
2043 # If we have a nonzero normal min_magnitude and draw a zero imaginary part,
2044 # then allow_subnormal=True would be an error with the min_value to the floats()
2045 # strategy for the real part. We therefore replace True with None.
2046 "allow_subnormal": None if allow_subnormal else allow_subnormal,
2047 "width": component_width,
2048 }
2049
2050 if min_magnitude == 0 and max_magnitude is None:
2051 # In this simple but common case, there are no constraints on the
2052 # magnitude and therefore no relationship between the real and
2053 # imaginary parts.
2054 return builds(complex, floats(**allow_kw), floats(**allow_kw)) # type: ignore
2055
2056 @composite
2057 def constrained_complex(draw):
2058 # We downcast drawn floats to the desired (component) width so we
2059 # guarantee the resulting complex values are representable. Note
2060 # truncating the mantissa bits with float_of() cannot increase the
2061 # magnitude of a float, so we are guaranteed to stay within the allowed
2062 # range. See https://github.com/HypothesisWorks/hypothesis/issues/3573
2063
2064 # Draw the imaginary part, and determine the maximum real part given
2065 # this and the max_magnitude
2066 if max_magnitude is None:
2067 zi = draw(floats(**allow_kw))
2068 rmax = None
2069 else:
2070 zi = draw(
2071 floats(
2072 -float_of(max_magnitude, component_width),
2073 float_of(max_magnitude, component_width),
2074 **allow_kw,
2075 )
2076 )
2077 rmax = float_of(cathetus(max_magnitude, zi), component_width)
2078 # Draw the real part from the allowed range given the imaginary part
2079 if min_magnitude == 0 or math.fabs(zi) >= min_magnitude:
2080 zr = draw(floats(None if rmax is None else -rmax, rmax, **allow_kw))
2081 else:
2082 rmin = float_of(cathetus(min_magnitude, zi), component_width)
2083 zr = draw(floats(rmin, rmax, **allow_kw))
2084 # Order of conditions carefully tuned so that for a given pair of
2085 # magnitude arguments, we always either draw or do not draw the bool
2086 # (crucial for good shrinking behaviour) but only invert when needed.
2087 if min_magnitude > 0 and draw(booleans()) and math.fabs(zi) <= min_magnitude:
2088 zr = -zr
2089 return complex(zr, zi)
2090
2091 return constrained_complex()
2092
2093
2094@defines_strategy(never_lazy=True)
2095def shared(
2096 base: SearchStrategy[Ex],
2097 *,
2098 key: Optional[Hashable] = None,
2099) -> SearchStrategy[Ex]:
2100 """Returns a strategy that draws a single shared value per run, drawn from
2101 base. Any two shared instances with the same key will share the same value,
2102 otherwise the identity of this strategy will be used. That is:
2103
2104 >>> s = integers() # or any other strategy
2105 >>> x = shared(s)
2106 >>> y = shared(s)
2107
2108 In the above x and y may draw different (or potentially the same) values.
2109 In the following they will always draw the same:
2110
2111 >>> x = shared(s, key="hi")
2112 >>> y = shared(s, key="hi")
2113
2114 Examples from this strategy shrink as per their base strategy.
2115 """
2116 return SharedStrategy(base, key)
2117
2118
2119@composite
2120def _maybe_nil_uuids(draw, uuid):
2121 # Equivalent to `random_uuids | just(...)`, with a stronger bias to the former.
2122 if draw(data()).conjecture_data.draw_boolean(1 / 64):
2123 return UUID("00000000-0000-0000-0000-000000000000")
2124 return uuid
2125
2126
2127@cacheable
2128@defines_strategy(force_reusable_values=True)
2129def uuids(
2130 *, version: Optional[Literal[1, 2, 3, 4, 5]] = None, allow_nil: bool = False
2131) -> SearchStrategy[UUID]:
2132 """Returns a strategy that generates :class:`UUIDs <uuid.UUID>`.
2133
2134 If the optional version argument is given, value is passed through
2135 to :class:`~python:uuid.UUID` and only UUIDs of that version will
2136 be generated.
2137
2138 If ``allow_nil`` is True, generate the nil UUID much more often.
2139 Otherwise, all returned values from this will be unique, so e.g. if you do
2140 ``lists(uuids())`` the resulting list will never contain duplicates.
2141
2142 Examples from this strategy don't have any meaningful shrink order.
2143 """
2144 check_type(bool, allow_nil, "allow_nil")
2145 if version not in (None, 1, 2, 3, 4, 5):
2146 raise InvalidArgument(
2147 f"{version=}, but version must be in "
2148 "(None, 1, 2, 3, 4, 5) to pass to the uuid.UUID constructor."
2149 )
2150 random_uuids = shared(
2151 randoms(use_true_random=True), key="hypothesis.strategies.uuids.generator"
2152 ).map(lambda r: UUID(version=version, int=r.getrandbits(128)))
2153
2154 if allow_nil:
2155 if version is not None:
2156 raise InvalidArgument("The nil UUID is not of any version")
2157 return random_uuids.flatmap(_maybe_nil_uuids)
2158 return random_uuids
2159
2160
2161class RunnerStrategy(SearchStrategy):
2162 def __init__(self, default):
2163 self.default = default
2164
2165 def do_draw(self, data):
2166 runner = getattr(data, "hypothesis_runner", not_set)
2167 if runner is not_set:
2168 if self.default is not_set:
2169 raise InvalidArgument(
2170 "Cannot use runner() strategy with no "
2171 "associated runner or explicit default."
2172 )
2173 else:
2174 return self.default
2175 else:
2176 return runner
2177
2178
2179@defines_strategy(force_reusable_values=True)
2180def runner(*, default: Any = not_set) -> SearchStrategy[Any]:
2181 """A strategy for getting "the current test runner", whatever that may be.
2182 The exact meaning depends on the entry point, but it will usually be the
2183 associated 'self' value for it.
2184
2185 If you are using this in a rule for stateful testing, this strategy
2186 will return the instance of the :class:`~hypothesis.stateful.RuleBasedStateMachine`
2187 that the rule is running for.
2188
2189 If there is no current test runner and a default is provided, return
2190 that default. If no default is provided, raises InvalidArgument.
2191
2192 Examples from this strategy do not shrink (because there is only one).
2193 """
2194 return RunnerStrategy(default)
2195
2196
2197class DataObject:
2198 """This type only exists so that you can write type hints for tests using
2199 the :func:`~hypothesis.strategies.data` strategy. Do not use it directly!
2200 """
2201
2202 # Note that "only exists" here really means "is only exported to users",
2203 # but we want to treat it as "semi-stable", not document it as "public API".
2204
2205 def __init__(self, data: ConjectureData) -> None:
2206 self.count = 0
2207 self.conjecture_data = data
2208
2209 __signature__ = Signature() # hide internals from Sphinx introspection
2210
2211 def __repr__(self) -> str:
2212 return "data(...)"
2213
2214 def draw(self, strategy: SearchStrategy[Ex], label: Any = None) -> Ex:
2215 """Like :obj:`~hypothesis.strategies.DrawFn`."""
2216 check_strategy(strategy, "strategy")
2217 self.count += 1
2218 desc = f"Draw {self.count}{'' if label is None else f' ({label})'}"
2219 with deprecate_random_in_strategy("{}from {!r}", desc, strategy):
2220 result = self.conjecture_data.draw(strategy, observe_as=f"generate:{desc}")
2221
2222 # optimization to avoid needless printer.pretty
2223 if should_note():
2224 printer = RepresentationPrinter(context=current_build_context())
2225 printer.text(f"{desc}: ")
2226 if self.conjecture_data.provider.avoid_realization:
2227 printer.text("<symbolic>")
2228 else:
2229 printer.pretty(result)
2230 note(printer.getvalue())
2231 return result
2232
2233
2234class DataStrategy(SearchStrategy):
2235 supports_find = False
2236
2237 def do_draw(self, data):
2238 if not hasattr(data, "hypothesis_shared_data_strategy"):
2239 data.hypothesis_shared_data_strategy = DataObject(data)
2240 return data.hypothesis_shared_data_strategy
2241
2242 def __repr__(self) -> str:
2243 return "data()"
2244
2245 def map(self, f):
2246 self.__not_a_first_class_strategy("map")
2247
2248 def filter(self, condition: Callable[[Ex], Any]) -> NoReturn:
2249 self.__not_a_first_class_strategy("filter")
2250
2251 def flatmap(self, f):
2252 self.__not_a_first_class_strategy("flatmap")
2253
2254 def example(self) -> NoReturn:
2255 self.__not_a_first_class_strategy("example")
2256
2257 def __not_a_first_class_strategy(self, name: str) -> NoReturn:
2258 raise InvalidArgument(
2259 f"Cannot call {name} on a DataStrategy. You should probably "
2260 "be using @composite for whatever it is you're trying to do."
2261 )
2262
2263
2264@cacheable
2265@defines_strategy(never_lazy=True)
2266def data() -> SearchStrategy[DataObject]:
2267 """
2268 Provides an object ``data`` with a ``data.draw`` function which acts like
2269 the ``draw`` callable provided by |st.composite|, in that it can be used
2270 to dynamically draw values from strategies. |st.data| is more powerful
2271 than |st.composite|, because it allows you to mix generation and test code.
2272
2273 Here's an example of dynamically generating values using |st.data|:
2274
2275 .. code-block:: python
2276
2277 from hypothesis import strategies as st, given
2278
2279 @given(st.data())
2280 def test_values(data):
2281 n1 = data.draw(st.integers())
2282 n2 = data.draw(st.integers(min_value=n1))
2283 assert n1 + 1 <= n2
2284
2285 If the test fails, each draw will be printed with the falsifying example.
2286 e.g. the above is wrong (it has a boundary condition error), so will print:
2287
2288 .. code-block:: pycon
2289
2290 Falsifying example: test_values(data=data(...))
2291 Draw 1: 0
2292 Draw 2: 0
2293
2294 Optionally, you can provide a label to identify values generated by each call
2295 to ``data.draw()``. These labels can be used to identify values in the
2296 output of a falsifying example.
2297
2298 For instance:
2299
2300 .. code-block:: python
2301
2302 @given(st.data())
2303 def test_draw_sequentially(data):
2304 x = data.draw(st.integers(), label="First number")
2305 y = data.draw(st.integers(min_value=x), label="Second number")
2306 assert x < y
2307
2308 will produce:
2309
2310 .. code-block:: pycon
2311
2312 Falsifying example: test_draw_sequentially(data=data(...))
2313 Draw 1 (First number): 0
2314 Draw 2 (Second number): 0
2315
2316 Examples from this strategy shrink by shrinking the output of each draw call.
2317 """
2318 return DataStrategy()
2319
2320
2321def register_type_strategy(
2322 custom_type: type[Ex],
2323 strategy: Union[SearchStrategy[Ex], Callable[[type[Ex]], SearchStrategy[Ex]]],
2324) -> None:
2325 """Add an entry to the global type-to-strategy lookup.
2326
2327 This lookup is used in :func:`~hypothesis.strategies.builds` and
2328 :func:`@given <hypothesis.given>`.
2329
2330 :func:`~hypothesis.strategies.builds` will be used automatically for
2331 classes with type annotations on ``__init__`` , so you only need to
2332 register a strategy if one or more arguments need to be more tightly
2333 defined than their type-based default, or if you want to supply a strategy
2334 for an argument with a default value.
2335
2336 ``strategy`` may be a search strategy, or a function that takes a type and
2337 returns a strategy (useful for generic types). The function may return
2338 :data:`NotImplemented` to conditionally not provide a strategy for the type
2339 (the type will still be resolved by other methods, if possible, as if the
2340 function was not registered).
2341
2342 Note that you may not register a parametrised generic type (such as
2343 ``MyCollection[int]``) directly, because the resolution logic does not
2344 handle this case correctly. Instead, you may register a *function* for
2345 ``MyCollection`` and `inspect the type parameters within that function
2346 <https://stackoverflow.com/q/48572831>`__.
2347 """
2348 # TODO: We would like to move this to the top level, but pending some major
2349 # refactoring it's hard to do without creating circular imports.
2350 from hypothesis.strategies._internal import types
2351
2352 if not types.is_a_type(custom_type):
2353 raise InvalidArgument(f"{custom_type=} must be a type")
2354 if custom_type in types.NON_RUNTIME_TYPES:
2355 raise InvalidArgument(
2356 f"{custom_type=} is not allowed to be registered, "
2357 f"because there is no such thing as a runtime instance of {custom_type!r}"
2358 )
2359 if not (isinstance(strategy, SearchStrategy) or callable(strategy)):
2360 raise InvalidArgument(
2361 f"{strategy=} must be a SearchStrategy, or a function that takes "
2362 "a generic type and returns a specific SearchStrategy"
2363 )
2364 if isinstance(strategy, SearchStrategy):
2365 with warnings.catch_warnings():
2366 warnings.simplefilter("error", HypothesisSideeffectWarning)
2367
2368 # Calling is_empty forces materialization of lazy strategies. If this is done at import
2369 # time, lazy strategies will warn about it; here, we force that warning to raise to
2370 # avoid the materialization. Ideally, we'd just check if the strategy is lazy, but the
2371 # lazy strategy may be wrapped underneath another strategy so that's complicated.
2372 try:
2373 if strategy.is_empty:
2374 raise InvalidArgument(f"{strategy=} must not be empty")
2375 except HypothesisSideeffectWarning: # pragma: no cover
2376 pass
2377 if types.has_type_arguments(custom_type):
2378 raise InvalidArgument(
2379 f"Cannot register generic type {custom_type!r}, because it has type "
2380 "arguments which would not be handled. Instead, register a function "
2381 f"for {get_origin(custom_type)!r} which can inspect specific type "
2382 "objects and return a strategy."
2383 )
2384 if (
2385 "pydantic.generics" in sys.modules
2386 and issubclass(custom_type, sys.modules["pydantic.generics"].GenericModel)
2387 and not re.search(r"[A-Za-z_]+\[.+\]", repr(custom_type))
2388 and callable(strategy)
2389 ): # pragma: no cover
2390 # See https://github.com/HypothesisWorks/hypothesis/issues/2940
2391 raise InvalidArgument(
2392 f"Cannot register a function for {custom_type!r}, because parametrized "
2393 "`pydantic.generics.GenericModel` subclasses aren't actually generic "
2394 "types at runtime. In this case, you should register a strategy "
2395 "directly for each parametrized form that you anticipate using."
2396 )
2397
2398 types._global_type_lookup[custom_type] = strategy
2399 from_type.__clear_cache() # type: ignore
2400
2401
2402@cacheable
2403@defines_strategy(never_lazy=True)
2404def deferred(definition: Callable[[], SearchStrategy[Ex]]) -> SearchStrategy[Ex]:
2405 """A deferred strategy allows you to write a strategy that references other
2406 strategies that have not yet been defined. This allows for the easy
2407 definition of recursive and mutually recursive strategies.
2408
2409 The definition argument should be a zero-argument function that returns a
2410 strategy. It will be evaluated the first time the strategy is used to
2411 produce an example.
2412
2413 Example usage:
2414
2415 >>> import hypothesis.strategies as st
2416 >>> x = st.deferred(lambda: st.booleans() | st.tuples(x, x))
2417 >>> x.example()
2418 (((False, (True, True)), (False, True)), (True, True))
2419 >>> x.example()
2420 True
2421
2422 Mutual recursion also works fine:
2423
2424 >>> a = st.deferred(lambda: st.booleans() | b)
2425 >>> b = st.deferred(lambda: st.tuples(a, a))
2426 >>> a.example()
2427 True
2428 >>> b.example()
2429 (False, (False, ((False, True), False)))
2430
2431 Examples from this strategy shrink as they normally would from the strategy
2432 returned by the definition.
2433 """
2434 return DeferredStrategy(definition)
2435
2436
2437def domains() -> SearchStrategy[str]:
2438 import hypothesis.provisional
2439
2440 return hypothesis.provisional.domains()
2441
2442
2443@defines_strategy(force_reusable_values=True)
2444def emails(
2445 *, domains: SearchStrategy[str] = LazyStrategy(domains, (), {})
2446) -> SearchStrategy[str]:
2447 """A strategy for generating email addresses as unicode strings. The
2448 address format is specified in :rfc:`5322#section-3.4.1`. Values shrink
2449 towards shorter local-parts and host domains.
2450
2451 If ``domains`` is given then it must be a strategy that generates domain
2452 names for the emails, defaulting to :func:`~hypothesis.provisional.domains`.
2453
2454 This strategy is useful for generating "user data" for tests, as
2455 mishandling of email addresses is a common source of bugs.
2456 """
2457 local_chars = string.ascii_letters + string.digits + "!#$%&'*+-/=^_`{|}~"
2458 local_part = text(local_chars, min_size=1, max_size=64)
2459 # TODO: include dot-atoms, quoted strings, escaped chars, etc in local part
2460 return builds("{}@{}".format, local_part, domains).filter(
2461 lambda addr: len(addr) <= 254
2462 )
2463
2464
2465def _functions(*, like, returns, pure):
2466 # Wrapped up to use ParamSpec below
2467 check_type(bool, pure, "pure")
2468 if not callable(like):
2469 raise InvalidArgument(
2470 "The first argument to functions() must be a callable to imitate, "
2471 f"but got non-callable like={nicerepr(like)!r}"
2472 )
2473 if returns in (None, ...):
2474 # Passing `None` has never been *documented* as working, but it still
2475 # did from May 2020 to Jan 2022 so we'll avoid breaking it without cause.
2476 hints = get_type_hints(like)
2477 returns = from_type(hints.get("return", type(None)))
2478 check_strategy(returns, "returns")
2479 return FunctionStrategy(like, returns, pure)
2480
2481
2482if typing.TYPE_CHECKING or ParamSpec is not None:
2483
2484 @overload
2485 def functions(
2486 *, pure: bool = ...
2487 ) -> SearchStrategy[Callable[[], None]]: # pragma: no cover
2488 ...
2489
2490 @overload
2491 def functions(
2492 *,
2493 like: Callable[P, T],
2494 pure: bool = ...,
2495 ) -> SearchStrategy[Callable[P, T]]: # pragma: no cover
2496 ...
2497
2498 @overload
2499 def functions(
2500 *,
2501 returns: SearchStrategy[T],
2502 pure: bool = ...,
2503 ) -> SearchStrategy[Callable[[], T]]: # pragma: no cover
2504 ...
2505
2506 @overload
2507 def functions(
2508 *,
2509 like: Callable[P, Any],
2510 returns: SearchStrategy[T],
2511 pure: bool = ...,
2512 ) -> SearchStrategy[Callable[P, T]]: # pragma: no cover
2513 ...
2514
2515 @defines_strategy()
2516 def functions(*, like=lambda: None, returns=..., pure=False):
2517 # We shouldn't need overloads here, but mypy disallows default args for
2518 # generics: https://github.com/python/mypy/issues/3737
2519 """functions(*, like=lambda: None, returns=..., pure=False)
2520
2521 A strategy for functions, which can be used in callbacks.
2522
2523 The generated functions will mimic the interface of ``like``, which must
2524 be a callable (including a class, method, or function). The return value
2525 for the function is drawn from the ``returns`` argument, which must be a
2526 strategy. If ``returns`` is not passed, we attempt to infer a strategy
2527 from the return-type annotation if present, falling back to :func:`~none`.
2528
2529 If ``pure=True``, all arguments passed to the generated function must be
2530 hashable, and if passed identical arguments the original return value will
2531 be returned again - *not* regenerated, so beware mutable values.
2532
2533 If ``pure=False``, generated functions do not validate their arguments, and
2534 may return a different value if called again with the same arguments.
2535
2536 Generated functions can only be called within the scope of the ``@given``
2537 which created them. This strategy does not support ``.example()``.
2538 """
2539 return _functions(like=like, returns=returns, pure=pure)
2540
2541else: # pragma: no cover
2542
2543 @defines_strategy()
2544 def functions(
2545 *,
2546 like: Callable[..., Any] = lambda: None,
2547 returns: Union[SearchStrategy[Any], EllipsisType] = ...,
2548 pure: bool = False,
2549 ) -> SearchStrategy[Callable[..., Any]]:
2550 """functions(*, like=lambda: None, returns=..., pure=False)
2551
2552 A strategy for functions, which can be used in callbacks.
2553
2554 The generated functions will mimic the interface of ``like``, which must
2555 be a callable (including a class, method, or function). The return value
2556 for the function is drawn from the ``returns`` argument, which must be a
2557 strategy. If ``returns`` is not passed, we attempt to infer a strategy
2558 from the return-type annotation if present, falling back to :func:`~none`.
2559
2560 If ``pure=True``, all arguments passed to the generated function must be
2561 hashable, and if passed identical arguments the original return value will
2562 be returned again - *not* regenerated, so beware mutable values.
2563
2564 If ``pure=False``, generated functions do not validate their arguments, and
2565 may return a different value if called again with the same arguments.
2566
2567 Generated functions can only be called within the scope of the ``@given``
2568 which created them. This strategy does not support ``.example()``.
2569 """
2570 return _functions(like=like, returns=returns, pure=pure)
2571
2572
2573@composite
2574def slices(draw: Any, size: int) -> slice:
2575 """Generates slices that will select indices up to the supplied size
2576
2577 Generated slices will have start and stop indices that range from -size to size - 1
2578 and will step in the appropriate direction. Slices should only produce an empty selection
2579 if the start and end are the same.
2580
2581 Examples from this strategy shrink toward 0 and smaller values
2582 """
2583 check_valid_size(size, "size")
2584 if size == 0:
2585 step = draw(none() | integers().filter(bool))
2586 return slice(None, None, step)
2587 # For slices start is inclusive and stop is exclusive
2588 start = draw(integers(0, size - 1) | none())
2589 stop = draw(integers(0, size) | none())
2590
2591 # Limit step size to be reasonable
2592 if start is None and stop is None:
2593 max_step = size
2594 elif start is None:
2595 max_step = stop
2596 elif stop is None:
2597 max_step = start
2598 else:
2599 max_step = abs(start - stop)
2600
2601 step = draw(integers(1, max_step or 1))
2602
2603 if (draw(booleans()) and start == stop) or (stop or 0) < (start or 0):
2604 step *= -1
2605
2606 if draw(booleans()) and start is not None:
2607 start -= size
2608 if draw(booleans()) and stop is not None:
2609 stop -= size
2610 if (not draw(booleans())) and step == 1:
2611 step = None
2612
2613 return slice(start, stop, step)