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

345 statements  

1# This file is part of Hypothesis, which may be found at 

2# https://github.com/HypothesisWorks/hypothesis/ 

3# 

4# Copyright the Hypothesis Authors. 

5# Individual contributors are listed in AUTHORS.rst and the git log. 

6# 

7# This Source Code Form is subject to the terms of the Mozilla Public License, 

8# v. 2.0. If a copy of the MPL was not distributed with this file, You can 

9# obtain one at https://mozilla.org/MPL/2.0/. 

10 

11"""The settings module configures runtime options for Hypothesis. 

12 

13Either an explicit settings object can be used or the default object on 

14this module can be modified. 

15""" 

16 

17import contextlib 

18import datetime 

19import inspect 

20import os 

21import warnings 

22from collections.abc import Collection, Generator, Sequence 

23from enum import Enum, EnumMeta, unique 

24from functools import total_ordering 

25from typing import ( 

26 TYPE_CHECKING, 

27 Any, 

28 ClassVar, 

29 Optional, 

30 TypeVar, 

31) 

32 

33from hypothesis.errors import ( 

34 HypothesisDeprecationWarning, 

35 InvalidArgument, 

36) 

37from hypothesis.internal.conjecture.providers import AVAILABLE_PROVIDERS 

38from hypothesis.internal.reflection import get_pretty_function_description 

39from hypothesis.internal.validation import check_type, try_convert 

40from hypothesis.utils.conventions import not_set 

41from hypothesis.utils.dynamicvariables import DynamicVariable 

42 

43if TYPE_CHECKING: 

44 from hypothesis.database import ExampleDatabase 

45 

46__all__ = ["settings"] 

47 

48T = TypeVar("T") 

49all_settings: list[str] = [ 

50 "max_examples", 

51 "derandomize", 

52 "database", 

53 "verbosity", 

54 "phases", 

55 "stateful_step_count", 

56 "report_multiple_bugs", 

57 "suppress_health_check", 

58 "deadline", 

59 "print_blob", 

60 "backend", 

61] 

62 

63 

64@unique 

65@total_ordering 

66class Verbosity(Enum): 

67 """Options for the |settings.verbosity| argument to |@settings|.""" 

68 

69 quiet = "quiet" 

70 """ 

71 Hypothesis will not print any output, not even the final falsifying example. 

72 """ 

73 

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 """ 

79 

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 """ 

86 

87 debug = "debug" 

88 """ 

89 Even more verbosity. Useful for debugging Hypothesis internals. You probably 

90 don't want this. 

91 """ 

92 

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 

109 

110 def __repr__(self) -> str: 

111 return f"Verbosity.{self.name}" 

112 

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] 

125 

126 def __eq__(self, other: Any) -> bool: 

127 if isinstance(other, Verbosity): 

128 return super().__eq__(other) 

129 return Verbosity._int_value(self) == other 

130 

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 

135 

136 

137@unique 

138class Phase(Enum): 

139 """Options for the |settings.phases| argument to |@settings|.""" 

140 

141 explicit = "explicit" 

142 """ 

143 Controls whether explicit examples are run. 

144 """ 

145 

146 reuse = "reuse" 

147 """ 

148 Controls whether previous examples will be reused. 

149 """ 

150 

151 generate = "generate" 

152 """ 

153 Controls whether new examples will be generated. 

154 """ 

155 

156 target = "target" 

157 """ 

158 Controls whether examples will be mutated for targeting. 

159 """ 

160 

161 shrink = "shrink" 

162 """ 

163 Controls whether examples will be shrunk. 

164 """ 

165 

166 explain = "explain" 

167 """ 

168 Controls whether Hypothesis attempts to explain test failures. 

169 

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 """ 

173 

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 

197 

198 def __repr__(self) -> str: 

199 return f"Phase.{self.name}" 

200 

201 

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) 

206 

207 

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. 

216 

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. 

220 

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. 

224 

225 Disabling health checks 

226 ----------------------- 

227 

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)``. 

230 

231 .. seealso:: 

232 

233 See also the :doc:`/how-to/suppress-healthchecks` how-to. 

234 

235 Correctness health checks 

236 ------------------------- 

237 

238 Some health checks report potential correctness errors, rather than performance 

239 problems. 

240 

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. 

248 

249 We recommend treating these particular health checks with more care, as 

250 suppressing them may result in an unsound test. 

251 """ 

252 

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 

279 

280 def __repr__(self) -> str: 

281 return f"{self.__class__.__name__}.{self.name}" 

282 

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) 

293 

294 data_too_large = "data_too_large" 

295 """Checks if too many examples are aborted for being too large. 

296 

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 """ 

303 

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.""" 

308 

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 """ 

315 

316 return_value = "return_value" 

317 """Deprecated; we always error if a test returns a non-None value.""" 

318 

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 """ 

325 

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).""" 

329 

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. 

335 

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. 

339 

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). 

344 

345 This check requires the :ref:`Hypothesis pytest plugin<pytest-plugin>`, 

346 which is enabled by default when running Hypothesis inside pytest.""" 

347 

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. 

354 

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.""" 

359 

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|. 

366 

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 """ 

376 

377 

378class duration(datetime.timedelta): 

379 """A timedelta specifically measured in milliseconds.""" 

380 

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})" 

384 

385 

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} 

403 

404 

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 ) 

410 

411 

412default_variable = DynamicVariable[Optional["settings"]](None) 

413 

414 

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 

420 

421 

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 

430 

431 

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 

440 

441 

442def _validate_database( 

443 database: Optional["ExampleDatabase"], 

444) -> Optional["ExampleDatabase"]: 

445 from hypothesis.database import ExampleDatabase 

446 

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 ) 

454 

455 

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) 

463 

464 

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 

472 

473 

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 ) 

488 

489 

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 

518 

519 

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 

530 

531 

532class settingsMeta(type): 

533 def __init__(cls, *args, **kwargs): 

534 super().__init__(*args, **kwargs) 

535 

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 

546 

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) 

561 

562 def __repr__(cls): 

563 return "hypothesis.settings" 

564 

565 

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|. 

573 

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|. 

578 

579 Attribute inheritance 

580 --------------------- 

581 

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. 

587 

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. 

591 

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. 

595 

596 .. _builtin-profiles: 

597 

598 Built-in profiles 

599 ----------------- 

600 

601 While you can register additional profiles with |settings.register_profile|, 

602 Hypothesis comes with two built-in profiles: ``default`` and ``ci``. 

603 

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. 

607 

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|). 

611 

612 The settings attributes for the built-in profiles are as follows: 

613 

614 .. code-block:: python 

615 

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 ) 

630 

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 ) 

640 

641 You can replace either of the built-in profiles with |settings.register_profile|: 

642 

643 .. code-block:: python 

644 

645 # run more examples in CI 

646 settings.register_profile( 

647 "ci", 

648 settings.get_profile("ci"), 

649 max_examples=1000, 

650 ) 

651 """ 

652 

653 _profiles: ClassVar[dict[str, "settings"]] = {} 

654 _current_profile: ClassVar[str | None] = None 

655 

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 

677 

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 

687 

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 ) 

747 

748 self._in_definition = False 

749 

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. 

755 

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. 

760 

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. 

764 

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. 

772 

773 The default max examples is ``100``. 

774 """ 

775 return self._max_examples 

776 

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. 

783 

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. 

789 

790 The default is ``False``. If running on CI, the default is ``True`` instead. 

791 """ 

792 return self._derandomize 

793 

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. 

799 

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|. 

804 

805 If ``None``, no storage will be used. 

806 

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 

811 

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) 

824 

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 

831 

832 @property 

833 def verbosity(self): 

834 """ 

835 Control the verbosity level of Hypothesis messages. 

836 

837 To see what's going on while Hypothesis runs your tests, you can turn 

838 up the verbosity setting. 

839 

840 .. code-block:: pycon 

841 

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] 

856 

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. 

862 

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: 

866 

867 .. code-block:: python 

868 

869 # these three are equivalent 

870 settings(verbosity=Verbosity.verbose) 

871 settings(verbosity="verbose") 

872 

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 

878 

879 @property 

880 def phases(self): 

881 """ 

882 Control which phases should be run. 

883 

884 Hypothesis divides tests into logically distinct phases. 

885 

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|. 

894 

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|. 

900 

901 Phases can be passed either as a |Phase| enum value, or as the corresponding 

902 string value. For example: 

903 

904 .. code-block:: python 

905 

906 # these two are equivalent 

907 settings(phases=[Phase.explicit]) 

908 settings(phases=["explicit"]) 

909 

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>`. 

918 

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: 

924 

925 .. code-block:: python 

926 

927 test_x_divided_by_y( 

928 x=0, # or any other generated value 

929 y=0, 

930 ) 

931 

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 """ 

936 

937 return self._phases 

938 

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. 

944 

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. 

947 

948 The default stateful step count is ``50``. 

949 """ 

950 return self._stateful_step_count 

951 

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. 

959 

960 The default value is ``True``. 

961 """ 

962 return self._report_multiple_bugs 

963 

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)``. 

970 

971 Health checks can be passed either as a |HealthCheck| enum value, or as 

972 the corresponding string value. For example: 

973 

974 .. code-block:: python 

975 

976 # these two are equivalent 

977 settings(suppress_health_check=[HealthCheck.filter_too_much]) 

978 settings(suppress_health_check=["filter_too_much"]) 

979 

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. 

984 

985 .. seealso:: 

986 

987 See also the :doc:`/how-to/suppress-healthchecks` how-to. 

988 """ 

989 return self._suppress_health_check 

990 

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. 

997 

998 We treat the deadline as a soft limit in some cases, where that would 

999 avoid flakiness due to timing variability. 

1000 

1001 The default deadline is 200 milliseconds. If running on CI, the default is 

1002 ``None`` instead. 

1003 """ 

1004 return self._deadline 

1005 

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. 

1011 

1012 The default value is ``False``. If running on CI, the default is ``True`` instead. 

1013 """ 

1014 return self._print_blob 

1015 

1016 @property 

1017 def backend(self): 

1018 """ 

1019 .. warning:: 

1020 

1021 EXPERIMENTAL AND UNSTABLE - see :ref:`alternative-backends`. 

1022 

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 

1028 

1029 def __call__(self, test: T) -> T: 

1030 """Make the settings object (self) an attribute of the test. 

1031 

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 

1037 

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 

1047 

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 ) 

1073 

1074 _test._hypothesis_internal_use_settings = self 

1075 _test._hypothesis_internal_settings_applied = True 

1076 return test 

1077 

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) 

1082 

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)) 

1090 

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)) 

1098 

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|. 

1109 

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. 

1114 

1115 Registered settings profiles can be retrieved later by name with 

1116 |settings.get_profile|. 

1117 """ 

1118 check_type(str, name, "name") 

1119 

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 ) 

1132 

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) 

1144 

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 

1156 

1157 @staticmethod 

1158 def load_profile(name: str) -> None: 

1159 """ 

1160 Makes the settings profile registered under ``name`` the active profile. 

1161 

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) 

1167 

1168 @staticmethod 

1169 def get_current_profile_name() -> str: 

1170 """ 

1171 The name of the current settings profile. For example: 

1172 

1173 .. code-block:: python 

1174 

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 

1181 

1182 

1183@contextlib.contextmanager 

1184def local_settings(s: settings) -> Generator[settings, None, None]: 

1185 with default_variable.with_value(s): 

1186 yield s 

1187 

1188 

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) 

1201 

1202 

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") 

1218 

1219assert settings.default is not None 

1220 

1221CI = settings( 

1222 derandomize=True, 

1223 deadline=None, 

1224 database=None, 

1225 print_blob=True, 

1226 suppress_health_check=[HealthCheck.too_slow], 

1227) 

1228 

1229settings.register_profile("ci", CI) 

1230 

1231 

1232if is_in_ci(): # pragma: no cover # covered in ci, but not locally 

1233 settings.load_profile("ci") 

1234 

1235assert settings.default is not None 

1236 

1237 

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}