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 final falsifying example.
71 """
73 normal = "normal"
74 """
75 Standard verbosity. Hypothesis will print the falsifying example, alongside
76 any notes made with |note| (only for the falsfying example).
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 examples will be reused.
153 """
155 generate = "generate"
156 """
157 Controls whether new examples will be generated.
158 """
160 target = "target"
161 """
162 Controls whether examples will be mutated for targeting.
163 """
165 shrink = "shrink"
166 """
167 Controls whether examples 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 example.
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 examples 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 examples, 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 example, 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 example 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 examples, 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 examples have been considered without finding any
758 counter-example, Hypothesis will stop looking.
760 Note that we might call your test function fewer times if we find a bug early
761 or can tell that we've exhausted the search space; or more if we discard some
762 examples due to use of .filter(), assume(), or a few other things that can
763 prevent the test case from completing successfully.
765 The default value is chosen to suit a workflow where the test will be part of
766 a suite that is regularly executed locally or on a CI server, balancing total
767 running time against the chance of missing a bug.
769 If you are writing one-off tests, running tens of thousands of examples is
770 quite reasonable as Hypothesis may miss uncommon bugs with default settings.
771 For very complex code, we have observed Hypothesis finding novel bugs after
772 *several million* examples while testing :pypi:`SymPy <sympy>`.
773 If you are running more than 100k examples for a test, consider using our
774 :ref:`integration for coverage-guided fuzzing <fuzz_one_input>` - it really
775 shines when given minutes or hours to run.
777 The default max examples is ``100``.
778 """
779 return self._max_examples
781 @property
782 def derandomize(self):
783 """
784 If True, seed Hypothesis' random number generator using a hash of the test
785 function, so that every run will test the same set of examples until you
786 update Hypothesis, Python, or the test function.
788 This allows you to `check for regressions and look for bugs
789 <https://blog.nelhage.com/post/two-kinds-of-testing/>`__ using separate
790 settings profiles - for example running
791 quick deterministic tests on every commit, and a longer non-deterministic
792 nightly testing run.
794 The default is ``False``. If running on CI, the default is ``True`` instead.
795 """
796 return self._derandomize
798 @property
799 def database(self):
800 """
801 An instance of |ExampleDatabase| that will be used to save examples to
802 and load previous examples from.
804 If not set, a |DirectoryBasedExampleDatabase| is created in the current
805 working directory under ``.hypothesis/examples``. If this location is
806 unusable, e.g. due to the lack of read or write permissions, Hypothesis
807 will emit a warning and fall back to an |InMemoryExampleDatabase|.
809 If ``None``, no storage will be used.
811 See the :ref:`database documentation <database>` for a list of database
812 classes, and how to define custom database classes.
813 """
814 from hypothesis.database import _db_for_path
816 # settings.database has two conflicting requirements:
817 # * The default settings should respect changes to set_hypothesis_home_dir
818 # in-between accesses
819 # * `s.database is s.database` should be true, except for the default settings
820 #
821 # We therefore cache s.database for everything except the default settings,
822 # which always recomputes dynamically.
823 if self._fallback is None:
824 # if self._fallback is None, we are the default settings, at which point
825 # we should recompute the database dynamically
826 assert self._database is not_set
827 return _db_for_path(not_set)
829 # otherwise, we cache the database
830 if self._cached_database is None:
831 self._cached_database = (
832 self._fallback.database if self._database is not_set else self._database
833 )
834 return self._cached_database
836 @property
837 def verbosity(self):
838 """
839 Control the verbosity level of Hypothesis messages.
841 To see what's going on while Hypothesis runs your tests, you can turn
842 up the verbosity setting.
844 .. code-block:: pycon
846 >>> from hypothesis import settings, Verbosity
847 >>> from hypothesis.strategies import lists, integers
848 >>> @given(lists(integers()))
849 ... @settings(verbosity=Verbosity.verbose)
850 ... def f(x):
851 ... assert not any(x)
852 ... f()
853 Trying example: []
854 Falsifying example: [-1198601713, -67, 116, -29578]
855 Shrunk example to [-1198601713]
856 Shrunk example to [-128]
857 Shrunk example to [32]
858 Shrunk example to [1]
859 [1]
861 The four levels are |Verbosity.quiet|, |Verbosity.normal|,
862 |Verbosity.verbose|, and |Verbosity.debug|. |Verbosity.normal| is the
863 default. For |Verbosity.quiet|, Hypothesis will not print anything out,
864 not even the final falsifying example. |Verbosity.debug| is basically
865 |Verbosity.verbose| but a bit more so. You probably don't want it.
867 Verbosity can be passed either as a |Verbosity| enum value, or as the
868 corresponding string value, or as the corresponding integer value. For
869 example:
871 .. code-block:: python
873 # these three are equivalent
874 settings(verbosity=Verbosity.verbose)
875 settings(verbosity="verbose")
877 If you are using :pypi:`pytest`, you may also need to :doc:`disable
878 output capturing for passing tests <pytest:how-to/capture-stdout-stderr>`
879 to see verbose output as tests run.
880 """
881 return self._verbosity
883 @property
884 def phases(self):
885 """
886 Control which phases should be run.
888 Hypothesis divides tests into logically distinct phases.
890 - |Phase.explicit|: Running explicit examples from |@example|.
891 - |Phase.reuse|: Running examples from the database which previously failed.
892 - |Phase.generate|: Generating new random examples.
893 - |Phase.target|: Mutating examples for :ref:`targeted property-based
894 testing <targeted>`. Requires |Phase.generate|.
895 - |Phase.shrink|: Shrinking failing examples.
896 - |Phase.explain|: Attempting to explain why a failure occurred.
897 Requires |Phase.shrink|.
899 The phases argument accepts a collection with any subset of these. E.g.
900 ``settings(phases=[Phase.generate, Phase.shrink])`` will generate new examples
901 and shrink them, but will not run explicit examples or reuse previous failures,
902 while ``settings(phases=[Phase.explicit])`` will only run explicit examples
903 from |@example|.
905 Phases can be passed either as a |Phase| enum value, or as the corresponding
906 string value. For example:
908 .. code-block:: python
910 # these two are equivalent
911 settings(phases=[Phase.explicit])
912 settings(phases=["explicit"])
914 Following the first failure, Hypothesis will (usually, depending on
915 which |Phase| is enabled) track which lines of code are always run on
916 failing but never on passing inputs. On 3.12+, this uses
917 :mod:`sys.monitoring`, while 3.11 and earlier uses :func:`python:sys.settrace`.
918 For python 3.11 and earlier, we therefore automatically disable the explain
919 phase on PyPy, or if you are using :pypi:`coverage` or a debugger. If
920 there are no clearly suspicious lines of code, :pep:`we refuse the
921 temptation to guess <20>`.
923 After shrinking to a minimal failing example, Hypothesis will try to find
924 parts of the example -- e.g. separate args to |@given|
925 -- which can vary freely without changing the result
926 of that minimal failing example. If the automated experiments run without
927 finding a passing variation, we leave a comment in the final report:
929 .. code-block:: python
931 test_x_divided_by_y(
932 x=0, # or any other generated value
933 y=0,
934 )
936 Just remember that the *lack* of an explanation sometimes just means that
937 Hypothesis couldn't efficiently find one, not that no explanation (or
938 simpler failing example) exists.
939 """
941 return self._phases
943 @property
944 def stateful_step_count(self):
945 """
946 The maximum number of times to call an additional |@rule| method in
947 :ref:`stateful testing <stateful>` before we give up on finding a bug.
949 Note that this setting is effectively multiplicative with max_examples,
950 as each example will run for a maximum of ``stateful_step_count`` steps.
952 The default stateful step count is ``50``.
953 """
954 return self._stateful_step_count
956 @property
957 def report_multiple_bugs(self):
958 """
959 Because Hypothesis runs the test many times, it can sometimes find multiple
960 bugs in a single run. Reporting all of them at once is usually very useful,
961 but replacing the exceptions can occasionally clash with debuggers.
962 If disabled, only the exception with the smallest minimal example is raised.
964 The default value is ``True``.
965 """
966 return self._report_multiple_bugs
968 @property
969 def suppress_health_check(self):
970 """
971 Suppress the given |HealthCheck| exceptions. Those health checks will not
972 be raised by Hypothesis. To suppress all health checks, you can pass
973 ``suppress_health_check=list(HealthCheck)``.
975 Health checks can be passed either as a |HealthCheck| enum value, or as
976 the corresponding string value. For example:
978 .. code-block:: python
980 # these two are equivalent
981 settings(suppress_health_check=[HealthCheck.filter_too_much])
982 settings(suppress_health_check=["filter_too_much"])
984 Health checks are proactive warnings, not correctness errors, so we
985 encourage suppressing health checks where you have evaluated they will
986 not pose a problem, or where you have evaluated that fixing the underlying
987 issue is not worthwhile.
989 .. seealso::
991 See also the :doc:`/how-to/suppress-healthchecks` how-to.
992 """
993 return self._suppress_health_check
995 @property
996 def deadline(self):
997 """
998 The maximum allowed duration of an individual test case, in milliseconds.
999 You can pass an integer, float, or timedelta. If ``None``, the deadline
1000 is disabled entirely.
1002 We treat the deadline as a soft limit in some cases, where that would
1003 avoid flakiness due to timing variability.
1005 The default deadline is 200 milliseconds. If running on CI, the default is
1006 ``None`` instead.
1007 """
1008 return self._deadline
1010 @property
1011 def print_blob(self):
1012 """
1013 If set to ``True``, Hypothesis will print code for failing examples that
1014 can be used with |@reproduce_failure| to reproduce the failing example.
1016 The default value is ``False``. If running on CI, the default is ``True`` instead.
1017 """
1018 return self._print_blob
1020 @property
1021 def backend(self):
1022 """
1023 .. warning::
1025 EXPERIMENTAL AND UNSTABLE - see :ref:`alternative-backends`.
1027 The importable name of a backend which Hypothesis should use to generate
1028 primitive types. We support heuristic-random, solver-based, and fuzzing-based
1029 backends.
1030 """
1031 return self._backend
1033 def __call__(self, test: T) -> T:
1034 """Make the settings object (self) an attribute of the test.
1036 The settings are later discovered by looking them up on the test itself.
1037 """
1038 # Aliasing as Any avoids mypy errors (attr-defined) when accessing and
1039 # setting custom attributes on the decorated function or class.
1040 _test: Any = test
1042 # Using the alias here avoids a mypy error (return-value) later when
1043 # ``test`` is returned, because this check results in type refinement.
1044 if not callable(_test):
1045 raise InvalidArgument(
1046 "settings objects can be called as a decorator with @given, "
1047 f"but decorated {test=} is not callable."
1048 )
1049 if inspect.isclass(test):
1050 from hypothesis.stateful import RuleBasedStateMachine
1052 if issubclass(_test, RuleBasedStateMachine):
1053 attr_name = "_hypothesis_internal_settings_applied"
1054 if getattr(test, attr_name, False):
1055 raise InvalidArgument(
1056 "Applying the @settings decorator twice would "
1057 "overwrite the first version; merge their arguments "
1058 "instead."
1059 )
1060 setattr(test, attr_name, True)
1061 _test.TestCase.settings = self
1062 return test
1063 else:
1064 raise InvalidArgument(
1065 "@settings(...) can only be used as a decorator on "
1066 "functions, or on subclasses of RuleBasedStateMachine."
1067 )
1068 if hasattr(_test, "_hypothesis_internal_settings_applied"):
1069 # Can't use _hypothesis_internal_use_settings as an indicator that
1070 # @settings was applied, because @given also assigns that attribute.
1071 descr = get_pretty_function_description(test)
1072 raise InvalidArgument(
1073 f"{descr} has already been decorated with a settings object.\n"
1074 f" Previous: {_test._hypothesis_internal_use_settings!r}\n"
1075 f" This: {self!r}"
1076 )
1078 _test._hypothesis_internal_use_settings = self
1079 _test._hypothesis_internal_settings_applied = True
1080 return test
1082 def __setattr__(self, name: str, value: object) -> None:
1083 if not name.startswith("_") and not self._in_definition:
1084 raise AttributeError("settings objects are immutable")
1085 return super().__setattr__(name, value)
1087 def __repr__(self) -> str:
1088 bits = sorted(
1089 f"{name}={getattr(self, name)!r}"
1090 for name in all_settings
1091 if (name != "backend" or len(AVAILABLE_PROVIDERS) > 1) # experimental
1092 )
1093 return "settings({})".format(", ".join(bits))
1095 def show_changed(self) -> str:
1096 bits = []
1097 for name in all_settings:
1098 value = getattr(self, name)
1099 if value != getattr(default, name):
1100 bits.append(f"{name}={value!r}")
1101 return ", ".join(sorted(bits, key=len))
1103 @staticmethod
1104 def register_profile(
1105 name: str,
1106 parent: Optional["settings"] = None,
1107 **kwargs: Any,
1108 ) -> None:
1109 """
1110 Register a settings object as a settings profile, under the name ``name``.
1111 The ``parent`` and ``kwargs`` arguments to this method are as for
1112 |settings|.
1114 If a settings profile already exists under ``name``, it will be overwritten.
1115 Registering a profile with the same name as the currently active profile
1116 will cause those changes to take effect in the active profile immediately,
1117 and do not require reloading the profile.
1119 Registered settings profiles can be retrieved later by name with
1120 |settings.get_profile|.
1121 """
1122 check_type(str, name, "name")
1124 if (
1125 default_variable.value
1126 and settings._current_profile
1127 and default_variable.value != settings._profiles[settings._current_profile]
1128 ):
1129 note_deprecation(
1130 "Cannot register a settings profile when the current settings differ "
1131 "from the current profile (usually due to an @settings decorator). "
1132 "Register profiles at module level instead.",
1133 since="2025-11-15",
1134 has_codemod=False,
1135 )
1137 # if we just pass the parent and no kwargs, like
1138 # settings.register_profile(settings(max_examples=10))
1139 # then optimize out the pointless intermediate settings object which
1140 # would just forward everything to the parent.
1141 settings._profiles[name] = (
1142 parent
1143 if parent is not None and not kwargs
1144 else settings(parent=parent, **kwargs)
1145 )
1146 if settings._current_profile == name:
1147 settings.load_profile(name)
1149 @staticmethod
1150 def get_profile(name: str) -> "settings":
1151 """
1152 Returns the settings profile registered under ``name``. If no settings
1153 profile is registered under ``name``, raises |InvalidArgument|.
1154 """
1155 check_type(str, name, "name")
1156 try:
1157 return settings._profiles[name]
1158 except KeyError:
1159 raise InvalidArgument(f"Profile {name!r} is not registered") from None
1161 @staticmethod
1162 def load_profile(name: str) -> None:
1163 """
1164 Makes the settings profile registered under ``name`` the active profile.
1166 If no settings profile is registered under ``name``, raises |InvalidArgument|.
1167 """
1168 check_type(str, name, "name")
1169 settings._current_profile = name
1170 default_variable.value = settings.get_profile(name)
1172 @staticmethod
1173 def get_current_profile_name() -> str:
1174 """
1175 The name of the current settings profile. For example:
1177 .. code-block:: python
1179 >>> settings.load_profile("myprofile")
1180 >>> settings.get_current_profile_name()
1181 'myprofile'
1182 """
1183 assert settings._current_profile is not None
1184 return settings._current_profile
1187@contextlib.contextmanager
1188def local_settings(s: settings) -> Generator[settings, None, None]:
1189 with default_variable.with_value(s):
1190 yield s
1193default = settings(
1194 max_examples=100,
1195 derandomize=False,
1196 database=not_set, # type: ignore
1197 verbosity=Verbosity.normal,
1198 phases=tuple(Phase),
1199 stateful_step_count=50,
1200 report_multiple_bugs=True,
1201 suppress_health_check=(),
1202 deadline=duration(milliseconds=200),
1203 print_blob=False,
1204 backend="hypothesis",
1205)
1206settings.register_profile("default", default)
1207settings.load_profile("default")
1209assert settings.default is not None
1211CI = settings(
1212 derandomize=True,
1213 deadline=None,
1214 database=None,
1215 print_blob=True,
1216 suppress_health_check=[HealthCheck.too_slow],
1217)
1219settings.register_profile("ci", CI)
1222if is_in_ci(): # pragma: no cover # covered in ci, but not locally
1223 settings.load_profile("ci")
1225assert settings.default is not None
1228# Check that the kwonly args to settings.__init__ is the same as the set of
1229# defined settings - in case we've added or remove something from one but
1230# not the other.
1231assert set(all_settings) == {
1232 p.name
1233 for p in inspect.signature(settings.__init__).parameters.values()
1234 if p.kind == inspect.Parameter.KEYWORD_ONLY
1235}