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