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