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