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