Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/hypothesis/_settings.py: 72%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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/.
11"""The settings module configures runtime options for Hypothesis.
13Either an explicit settings object can be used or the default object on
14this module can be modified.
15"""
17import contextlib
18import datetime
19import inspect
20import os
21from collections.abc import Collection, Generator, Sequence
22from enum import Enum, EnumMeta, unique
23from functools import total_ordering
24from typing import (
25 TYPE_CHECKING,
26 Any,
27 ClassVar,
28 Optional,
29 TypeVar,
30)
32from hypothesis.errors import (
33 InvalidArgument,
34)
35from hypothesis.internal.conjecture.providers import AVAILABLE_PROVIDERS
36from hypothesis.internal.reflection import get_pretty_function_description
37from hypothesis.internal.validation import check_type, try_convert
38from hypothesis.utils.conventions import not_set
39from hypothesis.utils.deprecation import note_deprecation
40from hypothesis.utils.dynamicvariables import DynamicVariable
42if TYPE_CHECKING:
43 from hypothesis.database import ExampleDatabase
45__all__ = ["settings"]
47T = TypeVar("T")
48all_settings: list[str] = [
49 "max_examples",
50 "derandomize",
51 "database",
52 "verbosity",
53 "phases",
54 "stateful_step_count",
55 "report_multiple_bugs",
56 "suppress_health_check",
57 "deadline",
58 "print_blob",
59 "backend",
60]
63@unique
64@total_ordering
65class Verbosity(Enum):
66 """Options for the |settings.verbosity| argument to |@settings|."""
68 quiet = "quiet"
69 """
70 Hypothesis will not print any output, not even the |minimal failing test case|.
71 """
73 normal = "normal"
74 """
75 Standard verbosity. Hypothesis will print the |minimal failing test case|, alongside
76 any notes made with |note| (only for the minimal failing test case).
77 """
79 verbose = "verbose"
80 """
81 Increased verbosity. In addition to everything in |Verbosity.normal|, Hypothesis
82 will:
84 * Print each |test case| as it tries it
85 * Print any notes made with |note| for each test case
86 * Print each shrinking attempt
87 * Print all explicit failing examples when using |@example|, instead of only
88 the simplest one
89 """
91 debug = "debug"
92 """
93 Even more verbosity. Useful for debugging Hypothesis internals. You probably
94 don't want this.
95 """
97 @classmethod
98 def _missing_(cls, value):
99 # deprecation pathway for integer values. Can be removed in Hypothesis 7.
100 if isinstance(value, int) and not isinstance(value, bool):
101 int_to_name = {0: "quiet", 1: "normal", 2: "verbose", 3: "debug"}
102 if value in int_to_name:
103 note_deprecation(
104 f"Passing Verbosity({value}) as an integer is deprecated. "
105 "Hypothesis now treats Verbosity values as strings, not integers. "
106 f"Use Verbosity.{int_to_name[value]} instead.",
107 since="2025-11-05",
108 has_codemod=False,
109 stacklevel=2,
110 )
111 return cls(int_to_name[value])
112 return None
114 def __repr__(self) -> str:
115 return f"Verbosity.{self.name}"
117 @staticmethod
118 def _int_value(value: "Verbosity") -> int:
119 # we would just map Verbosity keys, except it's not hashable
120 mapping = {
121 Verbosity.quiet.name: 0,
122 Verbosity.normal.name: 1,
123 Verbosity.verbose.name: 2,
124 Verbosity.debug.name: 3,
125 }
126 # make sure we don't forget any new verbosity members
127 assert list(mapping.keys()) == [verbosity.name for verbosity in Verbosity]
128 return mapping[value.name]
130 def __eq__(self, other: Any) -> bool:
131 if isinstance(other, Verbosity):
132 return super().__eq__(other)
133 return Verbosity._int_value(self) == other
135 def __gt__(self, other: Any) -> bool:
136 value1 = Verbosity._int_value(self)
137 value2 = Verbosity._int_value(other) if isinstance(other, Verbosity) else other
138 return value1 > value2
141@unique
142class Phase(Enum):
143 """Options for the |settings.phases| argument to |@settings|."""
145 explicit = "explicit"
146 """
147 Controls whether |explicit examples| are run.
148 """
150 reuse = "reuse"
151 """
152 Controls whether previous test cases will be reused.
153 """
155 generate = "generate"
156 """
157 Controls whether new test cases will be generated.
158 """
160 target = "target"
161 """
162 Controls whether test cases will be mutated for targeting.
163 """
165 shrink = "shrink"
166 """
167 Controls whether failing test cases will be shrunk.
168 """
170 explain = "explain"
171 """
172 Controls whether Hypothesis attempts to explain test failures.
174 The explain phase has two parts, each of which is best-effort - if Hypothesis
175 can't find a useful explanation, we'll just print the |minimal failing test case|.
176 """
178 @classmethod
179 def _missing_(cls, value):
180 # deprecation pathway for integer values. Can be removed in Hypothesis 7.
181 if isinstance(value, int) and not isinstance(value, bool):
182 int_to_name = {
183 0: "explicit",
184 1: "reuse",
185 2: "generate",
186 3: "target",
187 4: "shrink",
188 5: "explain",
189 }
190 if value in int_to_name:
191 note_deprecation(
192 f"Passing Phase({value}) as an integer is deprecated. "
193 "Hypothesis now treats Phase values as strings, not integers. "
194 f"Use Phase.{int_to_name[value]} instead.",
195 since="2025-11-05",
196 has_codemod=False,
197 stacklevel=2,
198 )
199 return cls(int_to_name[value])
200 return None
202 def __repr__(self) -> str:
203 return f"Phase.{self.name}"
206class HealthCheckMeta(EnumMeta):
207 def __iter__(self):
208 deprecated = (HealthCheck.return_value, HealthCheck.not_a_test_method)
209 return iter(x for x in super().__iter__() if x not in deprecated)
212@unique
213class HealthCheck(Enum, metaclass=HealthCheckMeta):
214 """
215 A |HealthCheck| is proactively raised by Hypothesis when Hypothesis detects
216 that your test has performance problems, which may result in less rigorous
217 testing than you expect. For example, if your test takes a long time to generate
218 inputs, or filters away too many inputs using |assume| or |filter|, Hypothesis
219 will raise a corresponding health check.
221 A health check is a proactive warning, not an error. We encourage suppressing
222 health checks where you have evaluated they will not pose a problem, or where
223 you have evaluated that fixing the underlying issue is not worthwhile.
225 With the exception of |HealthCheck.function_scoped_fixture| and
226 |HealthCheck.differing_executors|, all health checks warn about performance
227 problems, not correctness errors.
229 Disabling health checks
230 -----------------------
232 Health checks can be disabled by |settings.suppress_health_check|. To suppress
233 all health checks, you can pass ``suppress_health_check=list(HealthCheck)``.
235 .. seealso::
237 See also the :doc:`/how-to/suppress-healthchecks` how-to.
239 Correctness health checks
240 -------------------------
242 Some health checks report potential correctness errors, rather than performance
243 problems.
245 * |HealthCheck.function_scoped_fixture| indicates that a function-scoped
246 pytest fixture is used by an |@given| test. Many Hypothesis users expect
247 function-scoped fixtures to reset once per input, but they actually reset once
248 per test. We proactively raise |HealthCheck.function_scoped_fixture| to
249 ensure you have considered this case.
250 * |HealthCheck.differing_executors| indicates that the same |@given| test has
251 been executed multiple times with multiple distinct executors.
253 We recommend treating these particular health checks with more care, as
254 suppressing them may result in an unsound test.
255 """
257 @classmethod
258 def _missing_(cls, value):
259 # deprecation pathway for integer values. Can be removed in Hypothesis 7.
260 if isinstance(value, int) and not isinstance(value, bool):
261 int_to_name = {
262 1: "data_too_large",
263 2: "filter_too_much",
264 3: "too_slow",
265 5: "return_value",
266 7: "large_base_example",
267 8: "not_a_test_method",
268 9: "function_scoped_fixture",
269 10: "differing_executors",
270 11: "nested_given",
271 }
272 if value in int_to_name:
273 note_deprecation(
274 f"Passing HealthCheck({value}) as an integer is deprecated. "
275 "Hypothesis now treats HealthCheck values as strings, not integers. "
276 f"Use HealthCheck.{int_to_name[value]} instead.",
277 since="2025-11-05",
278 has_codemod=False,
279 stacklevel=2,
280 )
281 return cls(int_to_name[value])
282 return None
284 def __repr__(self) -> str:
285 return f"{self.__class__.__name__}.{self.name}"
287 @classmethod
288 def all(cls) -> list["HealthCheck"]:
289 # Skipping of deprecated attributes is handled in HealthCheckMeta.__iter__
290 note_deprecation(
291 "`HealthCheck.all()` is deprecated; use `list(HealthCheck)` instead.",
292 since="2023-04-16",
293 has_codemod=True,
294 stacklevel=1,
295 )
296 return list(HealthCheck)
298 data_too_large = "data_too_large"
299 """Checks if too many test cases are aborted for being too large.
301 This is measured by the number of random choices that Hypothesis makes
302 in order to generate something, not the size of the generated object.
303 For example, choosing a 100MB object from a predefined list would take
304 only a few bits, while generating 10KB of JSON from scratch might trigger
305 this health check.
306 """
308 filter_too_much = "filter_too_much"
309 """Check for when the test is filtering out too many test cases, either
310 through use of |assume| or |.filter|, or occasionally for Hypothesis
311 internal reasons."""
313 too_slow = "too_slow"
314 """
315 Check for when input generation is very slow. Since Hypothesis generates 100
316 (by default) inputs per test execution, a slowdown in generating each input
317 can result in very slow tests overall.
318 """
320 return_value = "return_value"
321 """Deprecated; we always error if a test returns a non-None value."""
323 large_base_example = "large_base_example"
324 """
325 Checks if the smallest natural input to your test is very large. This makes
326 it difficult for Hypothesis to generate good inputs, especially when trying to
327 shrink failing inputs.
328 """
330 not_a_test_method = "not_a_test_method"
331 """Deprecated; we always error if |@given| is applied
332 to a method defined by :class:`python:unittest.TestCase` (i.e. not a test)."""
334 function_scoped_fixture = "function_scoped_fixture"
335 """Checks if |@given| has been applied to a test
336 with a pytest function-scoped fixture. Function-scoped fixtures run once
337 for the whole function, not once per test case, and this is usually not what
338 you want.
340 Because of this limitation, tests that need to set up or reset
341 state for every test case need to do so manually within the test itself,
342 typically using an appropriate context manager.
344 Suppress this health check only in the rare case that you are using a
345 function-scoped fixture that does not need to be reset between individual
346 test cases, but for some reason you cannot use a wider fixture scope
347 (e.g. session scope, module scope, class scope).
349 This check requires the :ref:`Hypothesis pytest plugin<pytest-plugin>`,
350 which is enabled by default when running Hypothesis inside pytest."""
352 differing_executors = "differing_executors"
353 """Checks if |@given| has been applied to a test
354 which is executed by different :ref:`executors<custom-function-execution>`.
355 If your test function is defined as a method on a class, that class will be
356 your executor, and subclasses executing an inherited test is a common way
357 for things to go wrong.
359 The correct fix is often to bring the executor instance under the control
360 of hypothesis by explicit parametrization over, or sampling from,
361 subclasses, or to refactor so that |@given| is
362 specified on leaf subclasses."""
364 nested_given = "nested_given"
365 """Checks if |@given| is used inside another
366 |@given|. This results in quadratic generation and
367 shrinking behavior, and can usually be expressed more cleanly by using
368 :func:`~hypothesis.strategies.data` to replace the inner
369 |@given|.
371 Nesting @given can be appropriate if you set appropriate limits for the
372 quadratic behavior and cannot easily reexpress the inner function with
373 :func:`~hypothesis.strategies.data`. To suppress this health check, set
374 ``suppress_health_check=[HealthCheck.nested_given]`` on the outer
375 |@given|. Setting it on the inner
376 |@given| has no effect. If you have more than one
377 level of nesting, add a suppression for this health check to every
378 |@given| except the innermost one.
379 """
382class duration(datetime.timedelta):
383 """A timedelta specifically measured in milliseconds."""
385 def __repr__(self) -> str:
386 ms = self.total_seconds() * 1000
387 return f"timedelta(milliseconds={int(ms) if ms == int(ms) else ms!r})"
390# see https://adamj.eu/tech/2020/03/09/detect-if-your-tests-are-running-on-ci
391# initially from https://github.com/tox-dev/tox/blob/e911788a/src/tox/util/ci.py
392_CI_VARS = {
393 "CI": None, # various, including GitHub Actions, Travis CI, and AppVeyor
394 # see https://github.com/tox-dev/tox/issues/3442
395 "__TOX_ENVIRONMENT_VARIABLE_ORIGINAL_CI": None,
396 "TF_BUILD": "true", # Azure Pipelines
397 "bamboo.buildKey": None, # Bamboo
398 "BUILDKITE": "true", # Buildkite
399 "CIRCLECI": "true", # Circle CI
400 "CIRRUS_CI": "true", # Cirrus CI
401 "CODEBUILD_BUILD_ID": None, # CodeBuild
402 "GITHUB_ACTIONS": "true", # GitHub Actions
403 "GITLAB_CI": None, # GitLab CI
404 "HEROKU_TEST_RUN_ID": None, # Heroku CI
405 "TEAMCITY_VERSION": None, # TeamCity
406}
409def is_in_ci() -> bool:
410 return any(
411 key in os.environ and (value is None or os.environ[key] == value)
412 for key, value in _CI_VARS.items()
413 )
416default_variable = DynamicVariable[Optional["settings"]](None)
419def _validate_choices(name: str, value: T, *, choices: Sequence[object]) -> T:
420 if value not in choices:
421 msg = f"Invalid {name}, {value!r}. Valid choices: {choices!r}"
422 raise InvalidArgument(msg)
423 return value
426def _validate_enum_value(cls: Any, value: object, *, name: str) -> Any:
427 try:
428 return cls(value)
429 except ValueError:
430 raise InvalidArgument(
431 f"{name}={value} is not a valid value. The options "
432 f"are: {', '.join(repr(m.name) for m in cls)}"
433 ) from None
436def _validate_max_examples(max_examples: int) -> int:
437 check_type(int, max_examples, name="max_examples")
438 if max_examples < 1:
439 raise InvalidArgument(
440 f"max_examples={max_examples!r} must be at least one. If you want "
441 "to disable generation entirely, use phases=[Phase.explicit] instead."
442 )
443 return max_examples
446def _validate_database(
447 database: Optional["ExampleDatabase"],
448) -> Optional["ExampleDatabase"]:
449 from hypothesis.database import ExampleDatabase
451 if database is None or isinstance(database, ExampleDatabase):
452 return database
453 raise InvalidArgument(
454 "Arguments to the database setting must be None or an instance of "
455 "ExampleDatabase. Use one of the database classes in "
456 "hypothesis.database"
457 )
460def _validate_phases(phases: Collection[Phase]) -> Sequence[Phase]:
461 phases = try_convert(tuple, phases, "phases")
462 phases = tuple(
463 _validate_enum_value(Phase, phase, name="phases") for phase in phases
464 )
465 # sort by definition order
466 return tuple(phase for phase in list(Phase) if phase in phases)
469def _validate_stateful_step_count(stateful_step_count: int) -> int:
470 check_type(int, stateful_step_count, name="stateful_step_count")
471 if stateful_step_count < 1:
472 raise InvalidArgument(
473 f"stateful_step_count={stateful_step_count!r} must be at least one."
474 )
475 return stateful_step_count
478def _validate_suppress_health_check(suppressions: object) -> tuple[HealthCheck, ...]:
479 suppressions = try_convert(tuple, suppressions, "suppress_health_check")
480 for health_check in suppressions:
481 if health_check in (HealthCheck.return_value, HealthCheck.not_a_test_method):
482 note_deprecation(
483 f"The {health_check.name} health check is deprecated, because this is always an error.",
484 since="2023-03-15",
485 has_codemod=False,
486 stacklevel=2,
487 )
488 return tuple(
489 _validate_enum_value(HealthCheck, health_check, name="suppress_health_check")
490 for health_check in suppressions
491 )
494def _validate_deadline(
495 deadline: int | float | datetime.timedelta | None,
496) -> duration | None:
497 if deadline is None:
498 return deadline
499 invalid_deadline_error = InvalidArgument(
500 f"deadline={deadline!r} (type {type(deadline).__name__}) must be a timedelta object, "
501 "an integer or float number of milliseconds, or None to disable the "
502 "per-test-case deadline."
503 )
504 if isinstance(deadline, (int, float)):
505 if isinstance(deadline, bool):
506 raise invalid_deadline_error
507 try:
508 deadline = duration(milliseconds=deadline)
509 except OverflowError:
510 raise InvalidArgument(
511 f"deadline={deadline!r} is invalid, because it is too large to represent "
512 "as a timedelta. Use deadline=None to disable deadlines."
513 ) from None
514 if isinstance(deadline, datetime.timedelta):
515 if deadline <= datetime.timedelta(0):
516 raise InvalidArgument(
517 f"deadline={deadline!r} is invalid, because it is impossible to meet a "
518 "deadline <= 0. Use deadline=None to disable deadlines."
519 )
520 return duration(seconds=deadline.total_seconds())
521 raise invalid_deadline_error
524def _validate_backend(backend: str) -> str:
525 if backend not in AVAILABLE_PROVIDERS:
526 if backend == "crosshair": # pragma: no cover
527 install = '`pip install "hypothesis[crosshair]"` and try again.'
528 raise InvalidArgument(f"backend={backend!r} is not available. {install}")
529 raise InvalidArgument(
530 f"backend={backend!r} is not available - maybe you need to install a plugin?"
531 f"\n Installed backends: {sorted(AVAILABLE_PROVIDERS)!r}"
532 )
533 return backend
536class settingsMeta(type):
537 def __init__(cls, *args, **kwargs):
538 super().__init__(*args, **kwargs)
540 @property
541 def default(cls) -> Optional["settings"]:
542 v = default_variable.value
543 if v is not None:
544 return v
545 if getattr(settings, "_current_profile", None) is not None:
546 assert settings._current_profile is not None
547 settings.load_profile(settings._current_profile)
548 assert default_variable.value is not None
549 return default_variable.value
551 def __setattr__(cls, name: str, value: object) -> None:
552 if name == "default":
553 raise AttributeError(
554 "Cannot assign to the property settings.default - "
555 "consider using settings.load_profile instead."
556 )
557 elif not name.startswith("_"):
558 raise AttributeError(
559 f"Cannot assign hypothesis.settings.{name}={value!r} - the settings "
560 "class is immutable. You can change the global default "
561 "settings with settings.load_profile, or use @settings(...) "
562 "to decorate your test instead."
563 )
564 super().__setattr__(name, value)
566 def __repr__(cls):
567 return "hypothesis.settings"
570class settings(metaclass=settingsMeta):
571 """
572 A settings object controls the following aspects of test behavior:
573 |~settings.max_examples|, |~settings.derandomize|, |~settings.database|,
574 |~settings.verbosity|, |~settings.phases|, |~settings.stateful_step_count|,
575 |~settings.report_multiple_bugs|, |~settings.suppress_health_check|,
576 |~settings.deadline|, |~settings.print_blob|, and |~settings.backend|.
578 A settings object can be applied as a decorator to a test function, in which
579 case that test function will use those settings. A test may only have one
580 settings object applied to it. A settings object can also be passed to
581 |settings.register_profile| or as a parent to another |settings|.
583 Attribute inheritance
584 ---------------------
586 Settings objects are immutable once created. When a settings object is created,
587 it uses the value specified for each attribute. Any attribute which is
588 not specified will inherit from its value in the ``parent`` settings object.
589 If ``parent`` is not passed, any attributes which are not specified will inherit
590 from the current settings profile instead.
592 For instance, ``settings(max_examples=10)`` will have a ``max_examples`` of ``10``,
593 and the value of all other attributes will be equal to its value in the
594 current settings profile.
596 Changes made from activating a new settings profile with |settings.load_profile|
597 will be reflected in settings objects created after the profile was loaded,
598 but not in existing settings objects.
600 .. _builtin-profiles:
602 Built-in profiles
603 -----------------
605 While you can register additional profiles with |settings.register_profile|,
606 Hypothesis comes with two built-in profiles: ``default`` and ``ci``.
608 By default, the ``default`` profile is active. If the ``CI`` environment
609 variable is set to any value, the ``ci`` profile is active by default. Hypothesis
610 also automatically detects various vendor-specific CI environment variables.
612 The attributes of the currently active settings profile can be retrieved with
613 ``settings()`` (so ``settings().max_examples`` is the currently active default
614 for |settings.max_examples|).
616 The settings attributes for the built-in profiles are as follows:
618 .. code-block:: python
620 default = settings.register_profile(
621 "default",
622 max_examples=100,
623 derandomize=False,
624 database=not_set, # see settings.database for default behavior
625 verbosity=Verbosity.normal,
626 phases=tuple(Phase),
627 stateful_step_count=50,
628 report_multiple_bugs=True,
629 suppress_health_check=(),
630 deadline=duration(milliseconds=200),
631 print_blob=False,
632 backend="hypothesis",
633 )
635 ci = settings.register_profile(
636 "ci",
637 parent=default,
638 derandomize=True,
639 deadline=None,
640 database=None,
641 print_blob=True,
642 suppress_health_check=[HealthCheck.too_slow],
643 )
645 You can replace either of the built-in profiles with |settings.register_profile|:
647 .. code-block:: python
649 # run more examples in CI
650 settings.register_profile(
651 "ci",
652 settings.get_profile("ci"),
653 max_examples=1000,
654 )
655 """
657 _profiles: ClassVar[dict[str, "settings"]] = {}
658 _current_profile: ClassVar[str | None] = None
660 def __init__(
661 self,
662 parent: Optional["settings"] = None,
663 *,
664 # This looks pretty strange, but there's good reason: we want Mypy to detect
665 # bad calls downstream, but not to freak out about the `= not_set` part even
666 # though it's not semantically valid to pass that as an argument value.
667 # The intended use is "like **kwargs, but more tractable for tooling".
668 max_examples: int = not_set, # type: ignore
669 derandomize: bool = not_set, # type: ignore
670 database: Optional["ExampleDatabase"] = not_set, # type: ignore
671 verbosity: "Verbosity" = not_set, # type: ignore
672 phases: Collection["Phase"] = not_set, # type: ignore
673 stateful_step_count: int = not_set, # type: ignore
674 report_multiple_bugs: bool = not_set, # type: ignore
675 suppress_health_check: Collection["HealthCheck"] = not_set, # type: ignore
676 deadline: int | float | datetime.timedelta | None = not_set, # type: ignore
677 print_blob: bool = not_set, # type: ignore
678 backend: str = not_set, # type: ignore
679 ) -> None:
680 self._in_definition = True
682 if parent is not None:
683 check_type(settings, parent, "parent")
684 if derandomize not in (not_set, False):
685 if database not in (not_set, None): # type: ignore
686 raise InvalidArgument(
687 "derandomize=True implies database=None, so passing "
688 f"{database=} too is invalid."
689 )
690 database = None
692 # fallback is None if we're creating the default settings object, and
693 # the parent (or default settings object) otherwise
694 self._fallback = parent or settings.default
695 self._max_examples = (
696 self._fallback.max_examples # type: ignore
697 if max_examples is not_set # type: ignore
698 else _validate_max_examples(max_examples)
699 )
700 self._derandomize = (
701 self._fallback.derandomize # type: ignore
702 if derandomize is not_set # type: ignore
703 else _validate_choices("derandomize", derandomize, choices=[True, False])
704 )
705 if database is not not_set: # type: ignore
706 database = _validate_database(database)
707 self._database = database
708 self._cached_database = None
709 self._verbosity = (
710 self._fallback.verbosity # type: ignore
711 if verbosity is not_set # type: ignore
712 else _validate_enum_value(Verbosity, verbosity, name="verbosity")
713 )
714 self._phases = (
715 self._fallback.phases # type: ignore
716 if phases is not_set # type: ignore
717 else _validate_phases(phases)
718 )
719 self._stateful_step_count = (
720 self._fallback.stateful_step_count # type: ignore
721 if stateful_step_count is not_set # type: ignore
722 else _validate_stateful_step_count(stateful_step_count)
723 )
724 self._report_multiple_bugs = (
725 self._fallback.report_multiple_bugs # type: ignore
726 if report_multiple_bugs is not_set # type: ignore
727 else _validate_choices(
728 "report_multiple_bugs", report_multiple_bugs, choices=[True, False]
729 )
730 )
731 self._suppress_health_check = (
732 self._fallback.suppress_health_check # type: ignore
733 if suppress_health_check is not_set # type: ignore
734 else _validate_suppress_health_check(suppress_health_check)
735 )
736 self._deadline = (
737 self._fallback.deadline # type: ignore
738 if deadline is not_set # type: ignore
739 else _validate_deadline(deadline)
740 )
741 self._print_blob = (
742 self._fallback.print_blob # type: ignore
743 if print_blob is not_set # type: ignore
744 else _validate_choices("print_blob", print_blob, choices=[True, False])
745 )
746 self._backend = (
747 self._fallback.backend # type: ignore
748 if backend is not_set # type: ignore
749 else _validate_backend(backend)
750 )
752 self._in_definition = False
754 @property
755 def max_examples(self):
756 """
757 Once this many satisfying |test cases| have been considered without finding
758 any failing test case, Hypothesis will stop looking.
760 .. note::
762 Historically, Hypothesis referred to test cases as "examples", including in
763 this setting name. We now refer to them as test cases throughout our
764 documentation and codebase.
766 This setting is an exception: to avoid ecosystem churn, this setting will
767 continue to be called ``max_examples``. Conceptually, it is better thought of
768 as "max test cases".
770 Note that we might call your test function fewer times if we find a bug early
771 or can tell that we've exhausted the search space; or more if we discard some
772 test cases due to use of .filter(), assume(), or a few other things that can
773 prevent the test case from completing successfully.
775 The default value is chosen to suit a workflow where the test will be part of
776 a suite that is regularly executed locally or on a CI server, balancing total
777 running time against the chance of missing a bug.
779 If you are writing one-off tests, running tens of thousands of test cases is
780 quite reasonable as Hypothesis may miss uncommon bugs with default settings.
781 For very complex code, we have observed Hypothesis finding novel bugs after
782 *several million* test cases while testing :pypi:`SymPy <sympy>`.
783 If you are running more than 100k test cases for a test, consider using our
784 :ref:`integration for coverage-guided fuzzing <fuzz_one_input>` - it really
785 shines when given minutes or hours to run.
787 The default max examples is ``100``.
789 .. note::
791 See :doc:`../explanation/test-case-count` for details on how |max_examples|
792 interacts with other parts of Hypothesis.
793 """
794 return self._max_examples
796 @property
797 def derandomize(self):
798 """
799 If True, seed Hypothesis' random number generator using a hash of the test
800 function, so that every run will test the same set of test cases until you
801 update Hypothesis, Python, or the test function.
803 This allows you to `check for regressions and look for bugs
804 <https://blog.nelhage.com/post/two-kinds-of-testing/>`__ using separate
805 settings profiles - for example running
806 quick deterministic tests on every commit, and a longer non-deterministic
807 nightly testing run.
809 The default is ``False``. If running on CI, the default is ``True`` instead.
810 """
811 return self._derandomize
813 @property
814 def database(self):
815 """
816 An instance of |ExampleDatabase| in which we will save failing |test cases|,
817 and from which we will load previous failing test cases.
819 If not set, a |DirectoryBasedExampleDatabase| is created in the current
820 working directory under ``.hypothesis/examples``. If this location is
821 unusable, e.g. due to the lack of read or write permissions, Hypothesis
822 will emit a warning and fall back to an |InMemoryExampleDatabase|.
824 If ``None``, no storage will be used.
826 See the :ref:`database documentation <database>` for a list of database
827 classes, and how to define custom database classes.
828 """
829 from hypothesis.database import _db_for_path
831 # settings.database has two conflicting requirements:
832 # * The default settings should respect changes to set_hypothesis_home_dir
833 # in-between accesses
834 # * `s.database is s.database` should be true, except for the default settings
835 #
836 # We therefore cache s.database for everything except the default settings,
837 # which always recomputes dynamically.
838 if self._fallback is None:
839 # if self._fallback is None, we are the default settings, at which point
840 # we should recompute the database dynamically
841 assert self._database is not_set
842 return _db_for_path(not_set)
844 # otherwise, we cache the database
845 if self._cached_database is None:
846 self._cached_database = (
847 self._fallback.database if self._database is not_set else self._database
848 )
849 return self._cached_database
851 @property
852 def verbosity(self):
853 """
854 Control the verbosity level of Hypothesis messages.
856 To see what's going on while Hypothesis runs your tests, you can turn
857 up the verbosity setting.
859 .. code-block:: pycon
861 >>> from hypothesis import settings, Verbosity
862 >>> from hypothesis.strategies import lists, integers
863 >>> @given(lists(integers()))
864 ... @settings(verbosity=Verbosity.verbose)
865 ... def f(x):
866 ... assert not any(x)
867 ... f()
868 Test case: []
869 Failing test case: [-1198601713, -67, 116, -29578]
870 Shrunk test case to [-1198601713]
871 Shrunk test case to [-128]
872 Shrunk test case to [32]
873 Shrunk test case to [1]
874 [1]
876 The four levels are |Verbosity.quiet|, |Verbosity.normal|,
877 |Verbosity.verbose|, and |Verbosity.debug|. |Verbosity.normal| is the
878 default. For |Verbosity.quiet|, Hypothesis will not print anything out,
879 not even the |minimal failing test case|. |Verbosity.debug| is basically
880 |Verbosity.verbose| but a bit more so. You probably don't want it.
882 Verbosity can be passed either as a |Verbosity| enum value, or as the
883 corresponding string value, or as the corresponding integer value. For
884 example:
886 .. code-block:: python
888 # these three are equivalent
889 settings(verbosity=Verbosity.verbose)
890 settings(verbosity="verbose")
892 If you are using :pypi:`pytest`, you may also need to :doc:`disable
893 output capturing for passing tests <pytest:how-to/capture-stdout-stderr>`
894 to see verbose output as tests run.
895 """
896 return self._verbosity
898 @property
899 def phases(self):
900 """
901 Control which phases should be run.
903 Hypothesis divides tests into logically distinct phases.
905 - |Phase.explicit|: Running |explicit examples| from |@example|.
906 - |Phase.reuse|: Running |test cases| from the database which previously failed.
907 - |Phase.generate|: Generating new random test cases.
908 - |Phase.target|: Mutating test cases for :ref:`targeted property-based
909 testing <targeted>`. Requires |Phase.generate|.
910 - |Phase.shrink|: Shrinking |failing test cases|.
911 - |Phase.explain|: Attempting to explain why a failure occurred.
912 Requires |Phase.shrink|.
914 The phases argument accepts a collection with any subset of these. E.g.
915 ``settings(phases=[Phase.generate, Phase.shrink])`` will generate new test cases
916 and shrink them, but will not run explicit examples or reuse previous failures,
917 while ``settings(phases=[Phase.explicit])`` will only run explicit examples
918 from |@example|.
920 Phases can be passed either as a |Phase| enum value, or as the corresponding
921 string value. For example:
923 .. code-block:: python
925 # these two are equivalent
926 settings(phases=[Phase.explicit])
927 settings(phases=["explicit"])
929 Following the first failure, Hypothesis will (usually, depending on
930 which |Phase| is enabled) track which lines of code are always run on
931 failing but never on passing inputs. On 3.12+, this uses
932 :mod:`sys.monitoring`, while 3.11 and earlier uses :func:`python:sys.settrace`.
933 For python 3.11 and earlier, we therefore automatically disable the explain
934 phase on PyPy, or if you are using :pypi:`coverage` or a debugger. If
935 there are no clearly suspicious lines of code, :pep:`we refuse the
936 temptation to guess <20>`.
938 After shrinking to a minimal failing test case, Hypothesis will try to find
939 parts of the test case -- e.g. separate args to |@given|
940 -- which can vary freely without changing the result
941 of that minimal failing test case. If the automated experiments run without
942 finding a passing variation, we leave a comment in the final report:
944 .. code-block:: python
946 test_x_divided_by_y(
947 x=0, # or any other generated value
948 y=0,
949 )
951 Just remember that the *lack* of an explanation sometimes just means that
952 Hypothesis couldn't efficiently find one, not that no explanation (or
953 simpler failing test case) exists.
954 """
956 return self._phases
958 @property
959 def stateful_step_count(self):
960 """
961 The maximum number of times to call an additional |@rule| method in
962 :ref:`stateful testing <stateful>` before we give up on finding a bug.
964 Note that this setting is effectively multiplicative with max_examples,
965 as each test case will run for a maximum of ``stateful_step_count`` steps.
967 The default stateful step count is ``50``.
968 """
969 return self._stateful_step_count
971 @property
972 def report_multiple_bugs(self):
973 """
974 Because Hypothesis runs the test many times, it can sometimes find multiple
975 bugs in a single run. Reporting all of them at once is usually very useful,
976 but replacing the exceptions can occasionally clash with debuggers.
977 If disabled, only the exception with the smallest minimal example is raised.
979 The default value is ``True``.
980 """
981 return self._report_multiple_bugs
983 @property
984 def suppress_health_check(self):
985 """
986 Suppress the given |HealthCheck| exceptions. Those health checks will not
987 be raised by Hypothesis. To suppress all health checks, you can pass
988 ``suppress_health_check=list(HealthCheck)``.
990 Health checks can be passed either as a |HealthCheck| enum value, or as
991 the corresponding string value. For example:
993 .. code-block:: python
995 # these two are equivalent
996 settings(suppress_health_check=[HealthCheck.filter_too_much])
997 settings(suppress_health_check=["filter_too_much"])
999 Health checks are proactive warnings, not correctness errors, so we
1000 encourage suppressing health checks where you have evaluated they will
1001 not pose a problem, or where you have evaluated that fixing the underlying
1002 issue is not worthwhile.
1004 .. seealso::
1006 See also the :doc:`/how-to/suppress-healthchecks` how-to.
1007 """
1008 return self._suppress_health_check
1010 @property
1011 def deadline(self):
1012 """
1013 The maximum allowed duration of an individual |test case|, in milliseconds.
1014 You can pass an integer, float, or timedelta. If ``None``, the deadline
1015 is disabled entirely.
1017 We treat the deadline as a soft limit in some cases, where that would
1018 avoid flakiness due to timing variability.
1020 The default deadline is 200 milliseconds. If running on CI, the default is
1021 ``None`` instead.
1022 """
1023 return self._deadline
1025 @property
1026 def print_blob(self):
1027 """
1028 If set to ``True``, Hypothesis will print code for |failing test cases| that
1029 can be used with |@reproduce_failure| to reproduce the failing test case.
1031 The default value is ``False``. If running on CI, the default is ``True`` instead.
1032 """
1033 return self._print_blob
1035 @property
1036 def backend(self):
1037 """
1038 .. warning::
1040 EXPERIMENTAL AND UNSTABLE - see :ref:`alternative-backends`.
1042 The importable name of a backend which Hypothesis should use to generate
1043 primitive types. We support heuristic-random, solver-based, and fuzzing-based
1044 backends.
1045 """
1046 return self._backend
1048 def __call__(self, test: T) -> T:
1049 """Make the settings object (self) an attribute of the test.
1051 The settings are later discovered by looking them up on the test itself.
1052 """
1053 # Aliasing as Any avoids mypy errors (attr-defined) when accessing and
1054 # setting custom attributes on the decorated function or class.
1055 _test: Any = test
1057 # Using the alias here avoids a mypy error (return-value) later when
1058 # ``test`` is returned, because this check results in type refinement.
1059 if not callable(_test):
1060 raise InvalidArgument(
1061 "settings objects can be called as a decorator with @given, "
1062 f"but decorated {test=} is not callable."
1063 )
1064 if inspect.isclass(test):
1065 from hypothesis.stateful import RuleBasedStateMachine
1067 if issubclass(_test, RuleBasedStateMachine):
1068 attr_name = "_hypothesis_internal_settings_applied"
1069 if getattr(test, attr_name, False):
1070 raise InvalidArgument(
1071 "Applying the @settings decorator twice would "
1072 "overwrite the first version; merge their arguments "
1073 "instead."
1074 )
1075 setattr(test, attr_name, True)
1076 _test.TestCase.settings = self
1077 return test
1078 else:
1079 raise InvalidArgument(
1080 "@settings(...) can only be used as a decorator on "
1081 "functions, or on subclasses of RuleBasedStateMachine."
1082 )
1083 if hasattr(_test, "_hypothesis_internal_settings_applied"):
1084 # Can't use _hypothesis_internal_use_settings as an indicator that
1085 # @settings was applied, because @given also assigns that attribute.
1086 descr = get_pretty_function_description(test)
1087 raise InvalidArgument(
1088 f"{descr} has already been decorated with a settings object.\n"
1089 f" Previous: {_test._hypothesis_internal_use_settings!r}\n"
1090 f" This: {self!r}"
1091 )
1093 _test._hypothesis_internal_use_settings = self
1094 _test._hypothesis_internal_settings_applied = True
1095 return test
1097 def __setattr__(self, name: str, value: object) -> None:
1098 if not name.startswith("_") and not self._in_definition:
1099 raise AttributeError("settings objects are immutable")
1100 return super().__setattr__(name, value)
1102 def __repr__(self) -> str:
1103 bits = sorted(
1104 f"{name}={getattr(self, name)!r}"
1105 for name in all_settings
1106 if (name != "backend" or len(AVAILABLE_PROVIDERS) > 1) # experimental
1107 )
1108 return "settings({})".format(", ".join(bits))
1110 def show_changed(self) -> str:
1111 bits = []
1112 for name in all_settings:
1113 value = getattr(self, name)
1114 if value != getattr(default, name):
1115 bits.append(f"{name}={value!r}")
1116 return ", ".join(sorted(bits, key=len))
1118 @staticmethod
1119 def register_profile(
1120 name: str,
1121 parent: Optional["settings"] = None,
1122 **kwargs: Any,
1123 ) -> None:
1124 """
1125 Register a settings object as a settings profile, under the name ``name``.
1126 The ``parent`` and ``kwargs`` arguments to this method are as for
1127 |settings|.
1129 If a settings profile already exists under ``name``, it will be overwritten.
1130 Registering a profile with the same name as the currently active profile
1131 will cause those changes to take effect in the active profile immediately,
1132 and do not require reloading the profile.
1134 Registered settings profiles can be retrieved later by name with
1135 |settings.get_profile|.
1136 """
1137 check_type(str, name, "name")
1139 if (
1140 default_variable.value
1141 and settings._current_profile
1142 and default_variable.value != settings._profiles[settings._current_profile]
1143 ):
1144 note_deprecation(
1145 "Cannot register a settings profile when the current settings differ "
1146 "from the current profile (usually due to an @settings decorator). "
1147 "Register profiles at module level instead.",
1148 since="2025-11-15",
1149 has_codemod=False,
1150 )
1152 # if we just pass the parent and no kwargs, like
1153 # settings.register_profile(settings(max_examples=10))
1154 # then optimize out the pointless intermediate settings object which
1155 # would just forward everything to the parent.
1156 settings._profiles[name] = (
1157 parent
1158 if parent is not None and not kwargs
1159 else settings(parent=parent, **kwargs)
1160 )
1161 if settings._current_profile == name:
1162 settings.load_profile(name)
1164 @staticmethod
1165 def get_profile(name: str) -> "settings":
1166 """
1167 Returns the settings profile registered under ``name``. If no settings
1168 profile is registered under ``name``, raises |InvalidArgument|.
1169 """
1170 check_type(str, name, "name")
1171 try:
1172 return settings._profiles[name]
1173 except KeyError:
1174 raise InvalidArgument(f"Profile {name!r} is not registered") from None
1176 @staticmethod
1177 def load_profile(name: str) -> None:
1178 """
1179 Makes the settings profile registered under ``name`` the active profile.
1181 If no settings profile is registered under ``name``, raises |InvalidArgument|.
1182 """
1183 check_type(str, name, "name")
1184 settings._current_profile = name
1185 default_variable.value = settings.get_profile(name)
1187 @staticmethod
1188 def get_current_profile_name() -> str:
1189 """
1190 The name of the current settings profile. For example:
1192 .. code-block:: python
1194 >>> settings.load_profile("myprofile")
1195 >>> settings.get_current_profile_name()
1196 'myprofile'
1197 """
1198 assert settings._current_profile is not None
1199 return settings._current_profile
1202@contextlib.contextmanager
1203def local_settings(s: settings) -> Generator[settings, None, None]:
1204 with default_variable.with_value(s):
1205 yield s
1208default = settings(
1209 max_examples=100,
1210 derandomize=False,
1211 database=not_set, # type: ignore
1212 verbosity=Verbosity.normal,
1213 phases=tuple(Phase),
1214 stateful_step_count=50,
1215 report_multiple_bugs=True,
1216 suppress_health_check=(),
1217 deadline=duration(milliseconds=200),
1218 print_blob=False,
1219 backend="hypothesis",
1220)
1221settings.register_profile("default", default)
1222settings.load_profile("default")
1224assert settings.default is not None
1226CI = settings(
1227 derandomize=True,
1228 deadline=None,
1229 database=None,
1230 print_blob=True,
1231 suppress_health_check=[HealthCheck.too_slow],
1232)
1234settings.register_profile("ci", CI)
1237if is_in_ci(): # pragma: no cover # covered in ci, but not locally
1238 settings.load_profile("ci")
1240assert settings.default is not None
1243# Check that the kwonly args to settings.__init__ is the same as the set of
1244# defined settings - in case we've added or remove something from one but
1245# not the other.
1246assert set(all_settings) == {
1247 p.name
1248 for p in inspect.signature(settings.__init__).parameters.values()
1249 if p.kind == inspect.Parameter.KEYWORD_ONLY
1250}