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