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
11"""The settings module configures runtime options for Hypothesis.
12
13Either an explicit settings object can be used or the default object on
14this module can be modified.
15"""
16
17import contextlib
18import datetime
19import inspect
20import os
21import warnings
22from collections.abc import Collection, Generator, Sequence
23from enum import Enum, EnumMeta, IntEnum, unique
24from typing import (
25 TYPE_CHECKING,
26 Any,
27 ClassVar,
28 Optional,
29 TypeVar,
30 Union,
31)
32
33from hypothesis.errors import (
34 HypothesisDeprecationWarning,
35 InvalidArgument,
36)
37from hypothesis.internal.conjecture.providers import AVAILABLE_PROVIDERS
38from hypothesis.internal.reflection import get_pretty_function_description
39from hypothesis.internal.validation import check_type, try_convert
40from hypothesis.utils.conventions import not_set
41from hypothesis.utils.dynamicvariables import DynamicVariable
42
43if TYPE_CHECKING:
44 from hypothesis.database import ExampleDatabase
45
46__all__ = ["settings"]
47
48T = TypeVar("T")
49all_settings: list[str] = [
50 "max_examples",
51 "derandomize",
52 "database",
53 "verbosity",
54 "phases",
55 "stateful_step_count",
56 "report_multiple_bugs",
57 "suppress_health_check",
58 "deadline",
59 "print_blob",
60 "backend",
61]
62
63
64@unique
65class Verbosity(IntEnum):
66 """Options for the |settings.verbosity| argument to |@settings|."""
67
68 quiet = 0
69 """
70 Hypothesis will not print any output, not even the final falsifying example.
71 """
72
73 normal = 1
74 """
75 Standard verbosity. Hypothesis will print the falsifying example, alongside
76 any notes made with |note| (only for the falsfying example).
77 """
78
79 verbose = 2
80 """
81 Increased verbosity. In addition to everything in |Verbosity.normal|, Hypothesis
82 will print each example as it tries it, as well as any notes made with |note|
83 for every example. Hypothesis will also print shrinking attempts.
84 """
85
86 debug = 3
87 """
88 Even more verbosity. Useful for debugging Hypothesis internals. You probably
89 don't want this.
90 """
91
92 def __repr__(self) -> str:
93 return f"Verbosity.{self.name}"
94
95
96@unique
97class Phase(IntEnum):
98 """Options for the |settings.phases| argument to |@settings|."""
99
100 explicit = 0
101 """
102 Controls whether explicit examples are run.
103 """
104
105 reuse = 1
106 """
107 Controls whether previous examples will be reused.
108 """
109
110 generate = 2
111 """
112 Controls whether new examples will be generated.
113 """
114
115 target = 3
116 """
117 Controls whether examples will be mutated for targeting.
118 """
119
120 shrink = 4
121 """
122 Controls whether examples will be shrunk.
123 """
124
125 explain = 5
126 """
127 Controls whether Hypothesis attempts to explain test failures.
128
129 The explain phase has two parts, each of which is best-effort - if Hypothesis
130 can't find a useful explanation, we'll just print the minimal failing example.
131 """
132
133 def __repr__(self) -> str:
134 return f"Phase.{self.name}"
135
136
137class HealthCheckMeta(EnumMeta):
138 def __iter__(self):
139 deprecated = (HealthCheck.return_value, HealthCheck.not_a_test_method)
140 return iter(x for x in super().__iter__() if x not in deprecated)
141
142
143@unique
144class HealthCheck(Enum, metaclass=HealthCheckMeta):
145 """Arguments for :attr:`~hypothesis.settings.suppress_health_check`.
146
147 Each member of this enum is a specific health check to suppress.
148
149 Hypothesis' health checks are designed to detect and warn you about performance
150 problems where your tests are slow, inefficient, or generating very large examples.
151
152 If this is expected, e.g. when generating large arrays or dataframes, you can selectively
153 disable them with the :obj:`~hypothesis.settings.suppress_health_check` setting.
154 The argument for this parameter is a list with elements drawn from any of
155 the class-level attributes of the HealthCheck class.
156 Using a value of ``list(HealthCheck)`` will disable all health checks.
157 """
158
159 def __repr__(self) -> str:
160 return f"{self.__class__.__name__}.{self.name}"
161
162 @classmethod
163 def all(cls) -> list["HealthCheck"]:
164 # Skipping of deprecated attributes is handled in HealthCheckMeta.__iter__
165 note_deprecation(
166 "`HealthCheck.all()` is deprecated; use `list(HealthCheck)` instead.",
167 since="2023-04-16",
168 has_codemod=True,
169 stacklevel=1,
170 )
171 return list(HealthCheck)
172
173 data_too_large = 1
174 """Checks if too many examples are aborted for being too large.
175
176 This is measured by the number of random choices that Hypothesis makes
177 in order to generate something, not the size of the generated object.
178 For example, choosing a 100MB object from a predefined list would take
179 only a few bits, while generating 10KB of JSON from scratch might trigger
180 this health check.
181 """
182
183 filter_too_much = 2
184 """Check for when the test is filtering out too many examples, either
185 through use of |assume| or |.filter|, or occasionally for Hypothesis
186 internal reasons."""
187
188 too_slow = 3
189 """Check for when your data generation is extremely slow and likely to hurt
190 testing."""
191
192 return_value = 5
193 """Deprecated; we always error if a test returns a non-None value."""
194
195 large_base_example = 7
196 """Checks if the natural example to shrink towards is very large."""
197
198 not_a_test_method = 8
199 """Deprecated; we always error if |@given| is applied
200 to a method defined by :class:`python:unittest.TestCase` (i.e. not a test)."""
201
202 function_scoped_fixture = 9
203 """Checks if |@given| has been applied to a test
204 with a pytest function-scoped fixture. Function-scoped fixtures run once
205 for the whole function, not once per example, and this is usually not what
206 you want.
207
208 Because of this limitation, tests that need to set up or reset
209 state for every example need to do so manually within the test itself,
210 typically using an appropriate context manager.
211
212 Suppress this health check only in the rare case that you are using a
213 function-scoped fixture that does not need to be reset between individual
214 examples, but for some reason you cannot use a wider fixture scope
215 (e.g. session scope, module scope, class scope).
216
217 This check requires the :ref:`Hypothesis pytest plugin<pytest-plugin>`,
218 which is enabled by default when running Hypothesis inside pytest."""
219
220 differing_executors = 10
221 """Checks if |@given| has been applied to a test
222 which is executed by different :ref:`executors<custom-function-execution>`.
223 If your test function is defined as a method on a class, that class will be
224 your executor, and subclasses executing an inherited test is a common way
225 for things to go wrong.
226
227 The correct fix is often to bring the executor instance under the control
228 of hypothesis by explicit parametrization over, or sampling from,
229 subclasses, or to refactor so that |@given| is
230 specified on leaf subclasses."""
231
232 nested_given = 11
233 """Checks if |@given| is used inside another
234 |@given|. This results in quadratic generation and
235 shrinking behavior, and can usually be expressed more cleanly by using
236 :func:`~hypothesis.strategies.data` to replace the inner
237 |@given|.
238
239 Nesting @given can be appropriate if you set appropriate limits for the
240 quadratic behavior and cannot easily reexpress the inner function with
241 :func:`~hypothesis.strategies.data`. To suppress this health check, set
242 ``suppress_health_check=[HealthCheck.nested_given]`` on the outer
243 |@given|. Setting it on the inner
244 |@given| has no effect. If you have more than one
245 level of nesting, add a suppression for this health check to every
246 |@given| except the innermost one.
247 """
248
249
250class duration(datetime.timedelta):
251 """A timedelta specifically measured in milliseconds."""
252
253 def __repr__(self) -> str:
254 ms = self.total_seconds() * 1000
255 return f"timedelta(milliseconds={int(ms) if ms == int(ms) else ms!r})"
256
257
258def is_in_ci() -> bool:
259 # GitHub Actions, Travis CI and AppVeyor have "CI"
260 # Azure Pipelines has "TF_BUILD"
261 # GitLab CI has "GITLAB_CI"
262 return "CI" in os.environ or "TF_BUILD" in os.environ or "GITLAB_CI" in os.environ
263
264
265default_variable = DynamicVariable[Optional["settings"]](None)
266
267
268def _validate_choices(name: str, value: T, *, choices: Sequence[object]) -> T:
269 if value not in choices:
270 msg = f"Invalid {name}, {value!r}. Valid choices: {choices!r}"
271 raise InvalidArgument(msg)
272 return value
273
274
275def _validate_max_examples(max_examples: int) -> int:
276 check_type(int, max_examples, name="max_examples")
277 if max_examples < 1:
278 raise InvalidArgument(
279 f"max_examples={max_examples!r} must be at least one. If you want "
280 "to disable generation entirely, use phases=[Phase.explicit] instead."
281 )
282 return max_examples
283
284
285def _validate_database(
286 database: Optional["ExampleDatabase"],
287) -> Optional["ExampleDatabase"]:
288 from hypothesis.database import ExampleDatabase
289
290 if database is None or isinstance(database, ExampleDatabase):
291 return database
292 raise InvalidArgument(
293 "Arguments to the database setting must be None or an instance of "
294 "ExampleDatabase. Use one of the database classes in "
295 "hypothesis.database"
296 )
297
298
299def _validate_phases(phases: Collection[Phase]) -> Sequence[Phase]:
300 phases = tuple(phases)
301 for phase in phases:
302 if not isinstance(phase, Phase):
303 raise InvalidArgument(f"{phase!r} is not a valid phase")
304 return tuple(phase for phase in list(Phase) if phase in phases)
305
306
307def _validate_stateful_step_count(stateful_step_count: int) -> int:
308 check_type(int, stateful_step_count, name="stateful_step_count")
309 if stateful_step_count < 1:
310 raise InvalidArgument(
311 f"stateful_step_count={stateful_step_count!r} must be at least one."
312 )
313 return stateful_step_count
314
315
316def _validate_suppress_health_check(suppressions):
317 suppressions = try_convert(tuple, suppressions, "suppress_health_check")
318 for health_check in suppressions:
319 if not isinstance(health_check, HealthCheck):
320 raise InvalidArgument(
321 f"Non-HealthCheck value {health_check!r} of type {type(health_check).__name__} "
322 "is invalid in suppress_health_check."
323 )
324 if health_check in (HealthCheck.return_value, HealthCheck.not_a_test_method):
325 note_deprecation(
326 f"The {health_check.name} health check is deprecated, because this is always an error.",
327 since="2023-03-15",
328 has_codemod=False,
329 stacklevel=2,
330 )
331 return suppressions
332
333
334def _validate_deadline(
335 x: Union[int, float, datetime.timedelta, None],
336) -> Optional[duration]:
337 if x is None:
338 return x
339 invalid_deadline_error = InvalidArgument(
340 f"deadline={x!r} (type {type(x).__name__}) must be a timedelta object, "
341 "an integer or float number of milliseconds, or None to disable the "
342 "per-test-case deadline."
343 )
344 if isinstance(x, (int, float)):
345 if isinstance(x, bool):
346 raise invalid_deadline_error
347 try:
348 x = duration(milliseconds=x)
349 except OverflowError:
350 raise InvalidArgument(
351 f"deadline={x!r} is invalid, because it is too large to represent "
352 "as a timedelta. Use deadline=None to disable deadlines."
353 ) from None
354 if isinstance(x, datetime.timedelta):
355 if x <= datetime.timedelta(0):
356 raise InvalidArgument(
357 f"deadline={x!r} is invalid, because it is impossible to meet a "
358 "deadline <= 0. Use deadline=None to disable deadlines."
359 )
360 return duration(seconds=x.total_seconds())
361 raise invalid_deadline_error
362
363
364def _validate_backend(backend: str) -> str:
365 if backend not in AVAILABLE_PROVIDERS:
366 if backend == "crosshair": # pragma: no cover
367 install = '`pip install "hypothesis[crosshair]"` and try again.'
368 raise InvalidArgument(f"backend={backend!r} is not available. {install}")
369 raise InvalidArgument(
370 f"backend={backend!r} is not available - maybe you need to install a plugin?"
371 f"\n Installed backends: {sorted(AVAILABLE_PROVIDERS)!r}"
372 )
373 return backend
374
375
376class settingsMeta(type):
377 def __init__(cls, *args, **kwargs):
378 super().__init__(*args, **kwargs)
379
380 @property
381 def default(cls) -> Optional["settings"]:
382 v = default_variable.value
383 if v is not None:
384 return v
385 if getattr(settings, "_current_profile", None) is not None:
386 assert settings._current_profile is not None
387 settings.load_profile(settings._current_profile)
388 assert default_variable.value is not None
389 return default_variable.value
390
391 def __setattr__(cls, name: str, value: object) -> None:
392 if name == "default":
393 raise AttributeError(
394 "Cannot assign to the property settings.default - "
395 "consider using settings.load_profile instead."
396 )
397 elif not name.startswith("_"):
398 raise AttributeError(
399 f"Cannot assign hypothesis.settings.{name}={value!r} - the settings "
400 "class is immutable. You can change the global default "
401 "settings with settings.load_profile, or use @settings(...) "
402 "to decorate your test instead."
403 )
404 super().__setattr__(name, value)
405
406 def __repr__(cls):
407 return "hypothesis.settings"
408
409
410class settings(metaclass=settingsMeta):
411 """
412 A settings object controls the following aspects of test behavior:
413 |~settings.max_examples|, |~settings.derandomize|, |~settings.database|,
414 |~settings.verbosity|, |~settings.phases|, |~settings.stateful_step_count|,
415 |~settings.report_multiple_bugs|, |~settings.suppress_health_check|,
416 |~settings.deadline|, |~settings.print_blob|, and |~settings.backend|.
417
418 A settings object can be applied as a decorator to a test function, in which
419 case that test function will use those settings. A test may only have one
420 settings object applied to it. A settings object can also be passed to
421 |settings.register_profile| or as a parent to another |settings|.
422
423 Attribute inheritance
424 ---------------------
425
426 Settings objects are immutable once created. When a settings object is created,
427 it uses the value specified for each attribute. Any attribute which is
428 not specified will inherit from its value in the ``parent`` settings object.
429 If ``parent`` is not passed, any attributes which are not specified will inherit
430 from the currently active settings profile instead.
431
432 For instance, ``settings(max_examples=10)`` will have a ``max_examples`` of ``10``,
433 and the value of all other attributes will be equal to its value in the
434 currently active settings profile.
435
436 A settings object is immutable once created. Changes made from activating a new
437 settings profile with |settings.load_profile| will be reflected in
438 settings objects created after the profile was made active, but not in existing
439 settings objects.
440
441 Built-in profiles
442 -----------------
443
444 While you can register additional profiles with |settings.register_profile|,
445 Hypothesis comes with two built-in profiles: ``default`` and ``ci``.
446
447 The ``default`` profile is active by default, unless one of the ``CI``,
448 ``TF_BUILD``, or ``GITLAB_CI`` environment variables are set (to any value),
449 in which case the ``CI`` profile will be active by default.
450
451 The attributes of the currently active settings profile can be retrieved with
452 ``settings()`` (so ``settings().max_examples`` is the currently active default
453 for |settings.max_examples|).
454
455 The settings attributes for the built-in profiles are as follows:
456
457 .. code-block:: python
458
459 default = settings.register_profile(
460 "default",
461 max_examples=100,
462 derandomize=False,
463 database=not_set, # see settings.database for details
464 verbosity=Verbosity.normal,
465 phases=tuple(Phase),
466 stateful_step_count=50,
467 report_multiple_bugs=True,
468 suppress_health_check=(),
469 deadline=duration(milliseconds=200),
470 print_blob=False,
471 backend="hypothesis",
472 )
473
474 ci = settings.register_profile(
475 "ci",
476 parent=default,
477 derandomize=True,
478 deadline=None,
479 database=None,
480 print_blob=True,
481 suppress_health_check=[HealthCheck.too_slow],
482 )
483
484 You can configure either of the built-in profiles with |settings.register_profile|:
485
486 .. code-block:: python
487
488 # run more examples in CI
489 settings.register_profile(
490 "ci",
491 settings.get_profile("ci"),
492 max_examples=1000,
493 )
494 """
495
496 _profiles: ClassVar[dict[str, "settings"]] = {}
497 _current_profile: ClassVar[Optional[str]] = None
498
499 def __init__(
500 self,
501 parent: Optional["settings"] = None,
502 *,
503 # This looks pretty strange, but there's good reason: we want Mypy to detect
504 # bad calls downstream, but not to freak out about the `= not_set` part even
505 # though it's not semantically valid to pass that as an argument value.
506 # The intended use is "like **kwargs, but more tractable for tooling".
507 max_examples: int = not_set, # type: ignore
508 derandomize: bool = not_set, # type: ignore
509 database: Optional["ExampleDatabase"] = not_set, # type: ignore
510 verbosity: "Verbosity" = not_set, # type: ignore
511 phases: Collection["Phase"] = not_set, # type: ignore
512 stateful_step_count: int = not_set, # type: ignore
513 report_multiple_bugs: bool = not_set, # type: ignore
514 suppress_health_check: Collection["HealthCheck"] = not_set, # type: ignore
515 deadline: Union[int, float, datetime.timedelta, None] = not_set, # type: ignore
516 print_blob: bool = not_set, # type: ignore
517 backend: str = not_set, # type: ignore
518 ) -> None:
519 self._in_definition = True
520
521 if parent is not None:
522 check_type(settings, parent, "parent")
523 if derandomize not in (not_set, False):
524 if database not in (not_set, None): # type: ignore
525 raise InvalidArgument(
526 "derandomize=True implies database=None, so passing "
527 f"{database=} too is invalid."
528 )
529 database = None
530
531 # fallback is None if we're creating the default settings object, and
532 # the parent (or default settings object) otherwise
533 self._fallback = parent or settings.default
534 self._max_examples = (
535 self._fallback.max_examples # type: ignore
536 if max_examples is not_set # type: ignore
537 else _validate_max_examples(max_examples)
538 )
539 self._derandomize = (
540 self._fallback.derandomize # type: ignore
541 if derandomize is not_set # type: ignore
542 else _validate_choices("derandomize", derandomize, choices=[True, False])
543 )
544 if database is not not_set: # type: ignore
545 database = _validate_database(database)
546 self._database = database
547 self._cached_database = None
548 self._verbosity = (
549 self._fallback.verbosity # type: ignore
550 if verbosity is not_set # type: ignore
551 else _validate_choices("verbosity", verbosity, choices=tuple(Verbosity))
552 )
553 self._phases = (
554 self._fallback.phases # type: ignore
555 if phases is not_set # type: ignore
556 else _validate_phases(phases)
557 )
558 self._stateful_step_count = (
559 self._fallback.stateful_step_count # type: ignore
560 if stateful_step_count is not_set # type: ignore
561 else _validate_stateful_step_count(stateful_step_count)
562 )
563 self._report_multiple_bugs = (
564 self._fallback.report_multiple_bugs # type: ignore
565 if report_multiple_bugs is not_set # type: ignore
566 else _validate_choices(
567 "report_multiple_bugs", report_multiple_bugs, choices=[True, False]
568 )
569 )
570 self._suppress_health_check = (
571 self._fallback.suppress_health_check # type: ignore
572 if suppress_health_check is not_set # type: ignore
573 else _validate_suppress_health_check(suppress_health_check)
574 )
575 self._deadline = (
576 self._fallback.deadline # type: ignore
577 if deadline is not_set
578 else _validate_deadline(deadline)
579 )
580 self._print_blob = (
581 self._fallback.print_blob # type: ignore
582 if print_blob is not_set # type: ignore
583 else _validate_choices("print_blob", print_blob, choices=[True, False])
584 )
585 self._backend = (
586 self._fallback.backend # type: ignore
587 if backend is not_set # type: ignore
588 else _validate_backend(backend)
589 )
590
591 self._in_definition = False
592
593 @property
594 def max_examples(self):
595 """
596 Once this many satisfying examples have been considered without finding any
597 counter-example, Hypothesis will stop looking.
598
599 Note that we might call your test function fewer times if we find a bug early
600 or can tell that we've exhausted the search space; or more if we discard some
601 examples due to use of .filter(), assume(), or a few other things that can
602 prevent the test case from completing successfully.
603
604 The default value is chosen to suit a workflow where the test will be part of
605 a suite that is regularly executed locally or on a CI server, balancing total
606 running time against the chance of missing a bug.
607
608 If you are writing one-off tests, running tens of thousands of examples is
609 quite reasonable as Hypothesis may miss uncommon bugs with default settings.
610 For very complex code, we have observed Hypothesis finding novel bugs after
611 *several million* examples while testing :pypi:`SymPy <sympy>`.
612 If you are running more than 100k examples for a test, consider using our
613 :ref:`integration for coverage-guided fuzzing <fuzz_one_input>` - it really
614 shines when given minutes or hours to run.
615
616 The default max examples is ``100``.
617 """
618 return self._max_examples
619
620 @property
621 def derandomize(self):
622 """
623 If True, seed Hypothesis' random number generator using a hash of the test
624 function, so that every run will test the same set of examples until you
625 update Hypothesis, Python, or the test function.
626
627 This allows you to `check for regressions and look for bugs
628 <https://blog.nelhage.com/post/two-kinds-of-testing/>`__ using separate
629 settings profiles - for example running
630 quick deterministic tests on every commit, and a longer non-deterministic
631 nightly testing run.
632
633 The default is ``False``. If running on CI, the default is ``True`` instead.
634 """
635 return self._derandomize
636
637 @property
638 def database(self):
639 """
640 An instance of |ExampleDatabase| that will be used to save examples to
641 and load previous examples from.
642
643 If not set, a |DirectoryBasedExampleDatabase| is created in the current
644 working directory under ``.hypothesis/examples``. If this location is
645 unusable, e.g. due to the lack of read or write permissions, Hypothesis
646 will emit a warning and fall back to an |InMemoryExampleDatabase|.
647
648 If ``None``, no storage will be used.
649
650 See the :ref:`database documentation <database>` for a list of database
651 classes, and how to define custom database classes.
652 """
653 from hypothesis.database import _db_for_path
654
655 # settings.database has two conflicting requirements:
656 # * The default settings should respect changes to set_hypothesis_home_dir
657 # in-between accesses
658 # * `s.database is s.database` should be true, except for the default settings
659 #
660 # We therefore cache s.database for everything except the default settings,
661 # which always recomputes dynamically.
662 if self._fallback is None:
663 # if self._fallback is None, we are the default settings, at which point
664 # we should recompute the database dynamically
665 assert self._database is not_set
666 return _db_for_path(not_set)
667
668 # otherwise, we cache the database
669 if self._cached_database is None:
670 self._cached_database = (
671 self._fallback.database if self._database is not_set else self._database
672 )
673 return self._cached_database
674
675 @property
676 def verbosity(self):
677 """
678 Control the verbosity level of Hypothesis messages.
679
680 To see what's going on while Hypothesis runs your tests, you can turn
681 up the verbosity setting.
682
683 .. code-block:: pycon
684
685 >>> from hypothesis import settings, Verbosity
686 >>> from hypothesis.strategies import lists, integers
687 >>> @given(lists(integers()))
688 ... @settings(verbosity=Verbosity.verbose)
689 ... def f(x):
690 ... assert not any(x)
691 ... f()
692 Trying example: []
693 Falsifying example: [-1198601713, -67, 116, -29578]
694 Shrunk example to [-1198601713]
695 Shrunk example to [-128]
696 Shrunk example to [32]
697 Shrunk example to [1]
698 [1]
699
700 The four levels are |Verbosity.quiet|, |Verbosity.normal|,
701 |Verbosity.verbose|, and |Verbosity.debug|. |Verbosity.normal| is the
702 default. For |Verbosity.quiet|, Hypothesis will not print anything out,
703 not even the final falsifying example. |Verbosity.debug| is basically
704 |Verbosity.verbose| but a bit more so. You probably don't want it.
705
706 If you are using :pypi:`pytest`, you may also need to :doc:`disable
707 output capturing for passing tests <pytest:how-to/capture-stdout-stderr>`
708 to see verbose output as tests run.
709 """
710 return self._verbosity
711
712 @property
713 def phases(self):
714 """
715 Control which phases should be run.
716
717 Hypothesis divides tests into logically distinct phases.
718
719 - |Phase.explicit|: Running explicit examples from |@example|.
720 - |Phase.reuse|: Running examples from the database which previously failed.
721 - |Phase.generate|: Generating new random examples.
722 - |Phase.target|: Mutating examples for :ref:`targeted property-based
723 testing <targeted>`. Requires |Phase.generate|.
724 - |Phase.shrink|: Shrinking failing examples.
725 - |Phase.explain|: Attempting to explain why a failure occurred.
726 Requires |Phase.shrink|.
727
728 Following the first failure, Hypothesis will (usually, depending on
729 which |Phase| is enabled) track which lines of code are always run on
730 failing but never on passing inputs. On 3.12+, this uses
731 :mod:`sys.monitoring`, while 3.11 and earlier uses :func:`python:sys.settrace`.
732 For python 3.11 and earlier, we therefore automatically disable the explain
733 phase on PyPy, or if you are using :pypi:`coverage` or a debugger. If
734 there are no clearly suspicious lines of code, :pep:`we refuse the
735 temptation to guess <20>`.
736
737 After shrinking to a minimal failing example, Hypothesis will try to find
738 parts of the example -- e.g. separate args to |@given|
739 -- which can vary freely without changing the result
740 of that minimal failing example. If the automated experiments run without
741 finding a passing variation, we leave a comment in the final report:
742
743 .. code-block:: python
744
745 test_x_divided_by_y(
746 x=0, # or any other generated value
747 y=0,
748 )
749
750 Just remember that the *lack* of an explanation sometimes just means that
751 Hypothesis couldn't efficiently find one, not that no explanation (or
752 simpler failing example) exists.
753
754
755 The phases setting provides you with fine grained control over which of
756 these run, with each phase corresponding to a value on the |Phase| enum.
757
758 The phases argument accepts a collection with any subset of these. e.g.
759 ``settings(phases=[Phase.generate, Phase.shrink])`` will generate new examples
760 and shrink them, but will not run explicit examples or reuse previous failures,
761 while ``settings(phases=[Phase.explicit])`` will only run the explicit
762 examples.
763 """
764
765 return self._phases
766
767 @property
768 def stateful_step_count(self):
769 """
770 The maximum number of times to call an additional |@rule| method in
771 :ref:`stateful testing <stateful>` before we give up on finding a bug.
772
773 Note that this setting is effectively multiplicative with max_examples,
774 as each example will run for a maximum of ``stateful_step_count`` steps.
775
776 The default stateful step count is ``50``.
777 """
778 return self._stateful_step_count
779
780 @property
781 def report_multiple_bugs(self):
782 """
783 Because Hypothesis runs the test many times, it can sometimes find multiple
784 bugs in a single run. Reporting all of them at once is usually very useful,
785 but replacing the exceptions can occasionally clash with debuggers.
786 If disabled, only the exception with the smallest minimal example is raised.
787
788 The default value is ``True``.
789 """
790 return self._report_multiple_bugs
791
792 @property
793 def suppress_health_check(self):
794 """
795 A list of |HealthCheck| items to disable.
796 """
797 return self._suppress_health_check
798
799 @property
800 def deadline(self):
801 """
802 The maximum allowed duration of an individual test case, in milliseconds.
803 You can pass an integer, float, or timedelta. If ``None``, the deadline
804 is disabled entirely.
805
806 We treat the deadline as a soft limit in some cases, where that would
807 avoid flakiness due to timing variability.
808
809 The default deadline is 200 milliseconds. If running on CI, the default is
810 ``None`` instead.
811 """
812 return self._deadline
813
814 @property
815 def print_blob(self):
816 """
817 If set to ``True``, Hypothesis will print code for failing examples that
818 can be used with |@reproduce_failure| to reproduce the failing example.
819
820 The default value is ``False``. If running on CI, the default is ``True`` instead.
821 """
822 return self._print_blob
823
824 @property
825 def backend(self):
826 """
827 .. warning::
828
829 EXPERIMENTAL AND UNSTABLE - see :ref:`alternative-backends`.
830
831 The importable name of a backend which Hypothesis should use to generate
832 primitive types. We support heuristic-random, solver-based, and fuzzing-based
833 backends.
834 """
835 return self._backend
836
837 def __call__(self, test: T) -> T:
838 """Make the settings object (self) an attribute of the test.
839
840 The settings are later discovered by looking them up on the test itself.
841 """
842 # Aliasing as Any avoids mypy errors (attr-defined) when accessing and
843 # setting custom attributes on the decorated function or class.
844 _test: Any = test
845
846 # Using the alias here avoids a mypy error (return-value) later when
847 # ``test`` is returned, because this check results in type refinement.
848 if not callable(_test):
849 raise InvalidArgument(
850 "settings objects can be called as a decorator with @given, "
851 f"but decorated {test=} is not callable."
852 )
853 if inspect.isclass(test):
854 from hypothesis.stateful import RuleBasedStateMachine
855
856 if issubclass(_test, RuleBasedStateMachine):
857 attr_name = "_hypothesis_internal_settings_applied"
858 if getattr(test, attr_name, False):
859 raise InvalidArgument(
860 "Applying the @settings decorator twice would "
861 "overwrite the first version; merge their arguments "
862 "instead."
863 )
864 setattr(test, attr_name, True)
865 _test.TestCase.settings = self
866 return test # type: ignore
867 else:
868 raise InvalidArgument(
869 "@settings(...) can only be used as a decorator on "
870 "functions, or on subclasses of RuleBasedStateMachine."
871 )
872 if hasattr(_test, "_hypothesis_internal_settings_applied"):
873 # Can't use _hypothesis_internal_use_settings as an indicator that
874 # @settings was applied, because @given also assigns that attribute.
875 descr = get_pretty_function_description(test)
876 raise InvalidArgument(
877 f"{descr} has already been decorated with a settings object.\n"
878 f" Previous: {_test._hypothesis_internal_use_settings!r}\n"
879 f" This: {self!r}"
880 )
881
882 _test._hypothesis_internal_use_settings = self
883 _test._hypothesis_internal_settings_applied = True
884 return test
885
886 def __setattr__(self, name: str, value: object) -> None:
887 if not name.startswith("_") and not self._in_definition:
888 raise AttributeError("settings objects are immutable")
889 return super().__setattr__(name, value)
890
891 def __repr__(self) -> str:
892 bits = sorted(
893 f"{name}={getattr(self, name)!r}"
894 for name in all_settings
895 if (name != "backend" or len(AVAILABLE_PROVIDERS) > 1) # experimental
896 )
897 return "settings({})".format(", ".join(bits))
898
899 def show_changed(self) -> str:
900 bits = []
901 for name in all_settings:
902 value = getattr(self, name)
903 if value != getattr(default, name):
904 bits.append(f"{name}={value!r}")
905 return ", ".join(sorted(bits, key=len))
906
907 @staticmethod
908 def register_profile(
909 name: str,
910 parent: Optional["settings"] = None,
911 **kwargs: Any,
912 ) -> None:
913 """
914 Register a settings object as a settings profile, under the name ``name``.
915 The ``parent`` and ``kwargs`` arguments to this method are as for
916 |settings|.
917
918 If a settings profile already exists under ``name``, it will be overwritten.
919 Registering a profile with the same name as the currently active profile
920 will cause those changes to take effect in the active profile immediately,
921 and do not require reloading the profile.
922
923 Registered settings profiles can be retrieved later by name with
924 |settings.get_profile|.
925 """
926 check_type(str, name, "name")
927 # if we just pass the parent and no kwargs, like
928 # settings.register_profile(settings(max_examples=10))
929 # then optimize out the pointless intermediate settings object which
930 # would just forward everything to the parent.
931 settings._profiles[name] = (
932 parent
933 if parent is not None and not kwargs
934 else settings(parent=parent, **kwargs)
935 )
936 if settings._current_profile == name:
937 settings.load_profile(name)
938
939 @staticmethod
940 def get_profile(name: str) -> "settings":
941 """
942 Returns the settings profile registered under ``name``. If no settings
943 profile is registered under ``name``, raises |InvalidArgument|.
944 """
945 check_type(str, name, "name")
946 try:
947 return settings._profiles[name]
948 except KeyError:
949 raise InvalidArgument(f"Profile {name!r} is not registered") from None
950
951 @staticmethod
952 def load_profile(name: str) -> None:
953 """
954 Makes the settings profile registered under ``name`` the active profile.
955
956 If no settings profile is registered under ``name``, raises |InvalidArgument|.
957 """
958 check_type(str, name, "name")
959 settings._current_profile = name
960 default_variable.value = settings.get_profile(name)
961
962
963@contextlib.contextmanager
964def local_settings(s: settings) -> Generator[settings, None, None]:
965 with default_variable.with_value(s):
966 yield s
967
968
969def note_deprecation(
970 message: str, *, since: str, has_codemod: bool, stacklevel: int = 0
971) -> None:
972 if since != "RELEASEDAY":
973 date = datetime.date.fromisoformat(since)
974 assert datetime.date(2021, 1, 1) <= date
975 if has_codemod:
976 message += (
977 "\n The `hypothesis codemod` command-line tool can automatically "
978 "refactor your code to fix this warning."
979 )
980 warnings.warn(HypothesisDeprecationWarning(message), stacklevel=2 + stacklevel)
981
982
983default = settings(
984 max_examples=100,
985 derandomize=False,
986 database=not_set, # type: ignore
987 verbosity=Verbosity.normal,
988 phases=tuple(Phase),
989 stateful_step_count=50,
990 report_multiple_bugs=True,
991 suppress_health_check=(),
992 deadline=duration(milliseconds=200),
993 print_blob=False,
994 backend="hypothesis",
995)
996settings.register_profile("default", default)
997settings.load_profile("default")
998
999assert settings.default is not None
1000
1001CI = settings(
1002 derandomize=True,
1003 deadline=None,
1004 database=None,
1005 print_blob=True,
1006 suppress_health_check=[HealthCheck.too_slow],
1007)
1008
1009settings.register_profile("ci", CI)
1010
1011
1012if is_in_ci(): # pragma: no cover # covered in ci, but not locally
1013 settings.load_profile("ci")
1014
1015assert settings.default is not None
1016
1017
1018# Check that the kwonly args to settings.__init__ is the same as the set of
1019# defined settings - in case we've added or remove something from one but
1020# not the other.
1021assert set(all_settings) == {
1022 p.name
1023 for p in inspect.signature(settings.__init__).parameters.values()
1024 if p.kind == inspect.Parameter.KEYWORD_ONLY
1025}