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