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