Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/hypothesis/_settings.py: 72%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

338 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 

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) 

31 

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 

41 

42if TYPE_CHECKING: 

43 from hypothesis.database import ExampleDatabase 

44 

45__all__ = ["settings"] 

46 

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] 

61 

62 

63@unique 

64@total_ordering 

65class Verbosity(Enum): 

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

67 

68 quiet = "quiet" 

69 """ 

70 Hypothesis will not print any output, not even the |minimal failing test case|. 

71 """ 

72 

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

78 

79 verbose = "verbose" 

80 """ 

81 Increased verbosity. In addition to everything in |Verbosity.normal|, Hypothesis 

82 will: 

83 

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

90 

91 debug = "debug" 

92 """ 

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

94 don't want this. 

95 """ 

96 

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 

113 

114 def __repr__(self) -> str: 

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

116 

117 @staticmethod 

118 def _int_value(value: "Verbosity") -> int: 

119 # we would just map Verbosity keys, except it's not hashable 

120 mapping = { 

121 Verbosity.quiet.name: 0, 

122 Verbosity.normal.name: 1, 

123 Verbosity.verbose.name: 2, 

124 Verbosity.debug.name: 3, 

125 } 

126 # make sure we don't forget any new verbosity members 

127 assert list(mapping.keys()) == [verbosity.name for verbosity in Verbosity] 

128 return mapping[value.name] 

129 

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

131 if isinstance(other, Verbosity): 

132 return super().__eq__(other) 

133 return Verbosity._int_value(self) == other 

134 

135 def __gt__(self, other: Any) -> bool: 

136 value1 = Verbosity._int_value(self) 

137 value2 = Verbosity._int_value(other) if isinstance(other, Verbosity) else other 

138 return value1 > value2 

139 

140 

141@unique 

142class Phase(Enum): 

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

144 

145 explicit = "explicit" 

146 """ 

147 Controls whether |explicit examples| are run. 

148 """ 

149 

150 reuse = "reuse" 

151 """ 

152 Controls whether previous test cases will be reused. 

153 """ 

154 

155 generate = "generate" 

156 """ 

157 Controls whether new test cases will be generated. 

158 """ 

159 

160 target = "target" 

161 """ 

162 Controls whether test cases will be mutated for targeting. 

163 """ 

164 

165 shrink = "shrink" 

166 """ 

167 Controls whether failing test cases will be shrunk. 

168 """ 

169 

170 explain = "explain" 

171 """ 

172 Controls whether Hypothesis attempts to explain test failures. 

173 

174 The explain phase has two parts, each of which is best-effort - if Hypothesis 

175 can't find a useful explanation, we'll just print the |minimal failing test case|. 

176 """ 

177 

178 @classmethod 

179 def _missing_(cls, value): 

180 # deprecation pathway for integer values. Can be removed in Hypothesis 7. 

181 if isinstance(value, int) and not isinstance(value, bool): 

182 int_to_name = { 

183 0: "explicit", 

184 1: "reuse", 

185 2: "generate", 

186 3: "target", 

187 4: "shrink", 

188 5: "explain", 

189 } 

190 if value in int_to_name: 

191 note_deprecation( 

192 f"Passing Phase({value}) as an integer is deprecated. " 

193 "Hypothesis now treats Phase values as strings, not integers. " 

194 f"Use Phase.{int_to_name[value]} instead.", 

195 since="2025-11-05", 

196 has_codemod=False, 

197 stacklevel=2, 

198 ) 

199 return cls(int_to_name[value]) 

200 return None 

201 

202 def __repr__(self) -> str: 

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

204 

205 

206class HealthCheckMeta(EnumMeta): 

207 def __iter__(self): 

208 deprecated = (HealthCheck.return_value, HealthCheck.not_a_test_method) 

209 return iter(x for x in super().__iter__() if x not in deprecated) 

210 

211 

212@unique 

213class HealthCheck(Enum, metaclass=HealthCheckMeta): 

214 """ 

215 A |HealthCheck| is proactively raised by Hypothesis when Hypothesis detects 

216 that your test has performance problems, which may result in less rigorous 

217 testing than you expect. For example, if your test takes a long time to generate 

218 inputs, or filters away too many inputs using |assume| or |filter|, Hypothesis 

219 will raise a corresponding health check. 

220 

221 A health check is a proactive warning, not an error. We encourage suppressing 

222 health checks where you have evaluated they will not pose a problem, or where 

223 you have evaluated that fixing the underlying issue is not worthwhile. 

224 

225 With the exception of |HealthCheck.function_scoped_fixture| and 

226 |HealthCheck.differing_executors|, all health checks warn about performance 

227 problems, not correctness errors. 

228 

229 Disabling health checks 

230 ----------------------- 

231 

232 Health checks can be disabled by |settings.suppress_health_check|. To suppress 

233 all health checks, you can pass ``suppress_health_check=list(HealthCheck)``. 

234 

235 .. seealso:: 

236 

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

238 

239 Correctness health checks 

240 ------------------------- 

241 

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

243 problems. 

244 

245 * |HealthCheck.function_scoped_fixture| indicates that a function-scoped 

246 pytest fixture is used by an |@given| test. Many Hypothesis users expect 

247 function-scoped fixtures to reset once per input, but they actually reset once 

248 per test. We proactively raise |HealthCheck.function_scoped_fixture| to 

249 ensure you have considered this case. 

250 * |HealthCheck.differing_executors| indicates that the same |@given| test has 

251 been executed multiple times with multiple distinct executors. 

252 

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

254 suppressing them may result in an unsound test. 

255 """ 

256 

257 @classmethod 

258 def _missing_(cls, value): 

259 # deprecation pathway for integer values. Can be removed in Hypothesis 7. 

260 if isinstance(value, int) and not isinstance(value, bool): 

261 int_to_name = { 

262 1: "data_too_large", 

263 2: "filter_too_much", 

264 3: "too_slow", 

265 5: "return_value", 

266 7: "large_base_example", 

267 8: "not_a_test_method", 

268 9: "function_scoped_fixture", 

269 10: "differing_executors", 

270 11: "nested_given", 

271 } 

272 if value in int_to_name: 

273 note_deprecation( 

274 f"Passing HealthCheck({value}) as an integer is deprecated. " 

275 "Hypothesis now treats HealthCheck values as strings, not integers. " 

276 f"Use HealthCheck.{int_to_name[value]} instead.", 

277 since="2025-11-05", 

278 has_codemod=False, 

279 stacklevel=2, 

280 ) 

281 return cls(int_to_name[value]) 

282 return None 

283 

284 def __repr__(self) -> str: 

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

286 

287 @classmethod 

288 def all(cls) -> list["HealthCheck"]: 

289 # Skipping of deprecated attributes is handled in HealthCheckMeta.__iter__ 

290 note_deprecation( 

291 "`HealthCheck.all()` is deprecated; use `list(HealthCheck)` instead.", 

292 since="2023-04-16", 

293 has_codemod=True, 

294 stacklevel=1, 

295 ) 

296 return list(HealthCheck) 

297 

298 data_too_large = "data_too_large" 

299 """Checks if too many test cases are aborted for being too large. 

300 

301 This is measured by the number of random choices that Hypothesis makes 

302 in order to generate something, not the size of the generated object. 

303 For example, choosing a 100MB object from a predefined list would take 

304 only a few bits, while generating 10KB of JSON from scratch might trigger 

305 this health check. 

306 """ 

307 

308 filter_too_much = "filter_too_much" 

309 """Check for when the test is filtering out too many test cases, either 

310 through use of |assume| or |.filter|, or occasionally for Hypothesis 

311 internal reasons.""" 

312 

313 too_slow = "too_slow" 

314 """ 

315 Check for when input generation is very slow. Since Hypothesis generates 100 

316 (by default) inputs per test execution, a slowdown in generating each input 

317 can result in very slow tests overall. 

318 """ 

319 

320 return_value = "return_value" 

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

322 

323 large_base_example = "large_base_example" 

324 """ 

325 Checks if the smallest natural input to your test is very large. This makes 

326 it difficult for Hypothesis to generate good inputs, especially when trying to 

327 shrink failing inputs. 

328 """ 

329 

330 not_a_test_method = "not_a_test_method" 

331 """Deprecated; we always error if |@given| is applied 

332 to a method defined by :class:`python:unittest.TestCase` (i.e. not a test).""" 

333 

334 function_scoped_fixture = "function_scoped_fixture" 

335 """Checks if |@given| has been applied to a test 

336 with a pytest function-scoped fixture. Function-scoped fixtures run once 

337 for the whole function, not once per test case, and this is usually not what 

338 you want. 

339 

340 Because of this limitation, tests that need to set up or reset 

341 state for every test case need to do so manually within the test itself, 

342 typically using an appropriate context manager. 

343 

344 Suppress this health check only in the rare case that you are using a 

345 function-scoped fixture that does not need to be reset between individual 

346 test cases, but for some reason you cannot use a wider fixture scope 

347 (e.g. session scope, module scope, class scope). 

348 

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

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

351 

352 differing_executors = "differing_executors" 

353 """Checks if |@given| has been applied to a test 

354 which is executed by different :ref:`executors<custom-function-execution>`. 

355 If your test function is defined as a method on a class, that class will be 

356 your executor, and subclasses executing an inherited test is a common way 

357 for things to go wrong. 

358 

359 The correct fix is often to bring the executor instance under the control 

360 of hypothesis by explicit parametrization over, or sampling from, 

361 subclasses, or to refactor so that |@given| is 

362 specified on leaf subclasses.""" 

363 

364 nested_given = "nested_given" 

365 """Checks if |@given| is used inside another 

366 |@given|. This results in quadratic generation and 

367 shrinking behavior, and can usually be expressed more cleanly by using 

368 :func:`~hypothesis.strategies.data` to replace the inner 

369 |@given|. 

370 

371 Nesting @given can be appropriate if you set appropriate limits for the 

372 quadratic behavior and cannot easily reexpress the inner function with 

373 :func:`~hypothesis.strategies.data`. To suppress this health check, set 

374 ``suppress_health_check=[HealthCheck.nested_given]`` on the outer 

375 |@given|. Setting it on the inner 

376 |@given| has no effect. If you have more than one 

377 level of nesting, add a suppression for this health check to every 

378 |@given| except the innermost one. 

379 """ 

380 

381 

382class duration(datetime.timedelta): 

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

384 

385 def __repr__(self) -> str: 

386 ms = self.total_seconds() * 1000 

387 return f"timedelta(milliseconds={int(ms) if ms == int(ms) else ms!r})" 

388 

389 

390# see https://adamj.eu/tech/2020/03/09/detect-if-your-tests-are-running-on-ci 

391# initially from https://github.com/tox-dev/tox/blob/e911788a/src/tox/util/ci.py 

392_CI_VARS = { 

393 "CI": None, # various, including GitHub Actions, Travis CI, and AppVeyor 

394 # see https://github.com/tox-dev/tox/issues/3442 

395 "__TOX_ENVIRONMENT_VARIABLE_ORIGINAL_CI": None, 

396 "TF_BUILD": "true", # Azure Pipelines 

397 "bamboo.buildKey": None, # Bamboo 

398 "BUILDKITE": "true", # Buildkite 

399 "CIRCLECI": "true", # Circle CI 

400 "CIRRUS_CI": "true", # Cirrus CI 

401 "CODEBUILD_BUILD_ID": None, # CodeBuild 

402 "GITHUB_ACTIONS": "true", # GitHub Actions 

403 "GITLAB_CI": None, # GitLab CI 

404 "HEROKU_TEST_RUN_ID": None, # Heroku CI 

405 "TEAMCITY_VERSION": None, # TeamCity 

406} 

407 

408 

409def is_in_ci() -> bool: 

410 return any( 

411 key in os.environ and (value is None or os.environ[key] == value) 

412 for key, value in _CI_VARS.items() 

413 ) 

414 

415 

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

417 

418 

419def _validate_choices(name: str, value: T, *, choices: Sequence[object]) -> T: 

420 if value not in choices: 

421 msg = f"Invalid {name}, {value!r}. Valid choices: {choices!r}" 

422 raise InvalidArgument(msg) 

423 return value 

424 

425 

426def _validate_enum_value(cls: Any, value: object, *, name: str) -> Any: 

427 try: 

428 return cls(value) 

429 except ValueError: 

430 raise InvalidArgument( 

431 f"{name}={value} is not a valid value. The options " 

432 f"are: {', '.join(repr(m.name) for m in cls)}" 

433 ) from None 

434 

435 

436def _validate_max_examples(max_examples: int) -> int: 

437 check_type(int, max_examples, name="max_examples") 

438 if max_examples < 1: 

439 raise InvalidArgument( 

440 f"max_examples={max_examples!r} must be at least one. If you want " 

441 "to disable generation entirely, use phases=[Phase.explicit] instead." 

442 ) 

443 return max_examples 

444 

445 

446def _validate_database( 

447 database: Optional["ExampleDatabase"], 

448) -> Optional["ExampleDatabase"]: 

449 from hypothesis.database import ExampleDatabase 

450 

451 if database is None or isinstance(database, ExampleDatabase): 

452 return database 

453 raise InvalidArgument( 

454 "Arguments to the database setting must be None or an instance of " 

455 "ExampleDatabase. Use one of the database classes in " 

456 "hypothesis.database" 

457 ) 

458 

459 

460def _validate_phases(phases: Collection[Phase]) -> Sequence[Phase]: 

461 phases = try_convert(tuple, phases, "phases") 

462 phases = tuple( 

463 _validate_enum_value(Phase, phase, name="phases") for phase in phases 

464 ) 

465 # sort by definition order 

466 return tuple(phase for phase in list(Phase) if phase in phases) 

467 

468 

469def _validate_stateful_step_count(stateful_step_count: int) -> int: 

470 check_type(int, stateful_step_count, name="stateful_step_count") 

471 if stateful_step_count < 1: 

472 raise InvalidArgument( 

473 f"stateful_step_count={stateful_step_count!r} must be at least one." 

474 ) 

475 return stateful_step_count 

476 

477 

478def _validate_suppress_health_check(suppressions: object) -> tuple[HealthCheck, ...]: 

479 suppressions = try_convert(tuple, suppressions, "suppress_health_check") 

480 for health_check in suppressions: 

481 if health_check in (HealthCheck.return_value, HealthCheck.not_a_test_method): 

482 note_deprecation( 

483 f"The {health_check.name} health check is deprecated, because this is always an error.", 

484 since="2023-03-15", 

485 has_codemod=False, 

486 stacklevel=2, 

487 ) 

488 return tuple( 

489 _validate_enum_value(HealthCheck, health_check, name="suppress_health_check") 

490 for health_check in suppressions 

491 ) 

492 

493 

494def _validate_deadline( 

495 deadline: int | float | datetime.timedelta | None, 

496) -> duration | None: 

497 if deadline is None: 

498 return deadline 

499 invalid_deadline_error = InvalidArgument( 

500 f"deadline={deadline!r} (type {type(deadline).__name__}) must be a timedelta object, " 

501 "an integer or float number of milliseconds, or None to disable the " 

502 "per-test-case deadline." 

503 ) 

504 if isinstance(deadline, (int, float)): 

505 if isinstance(deadline, bool): 

506 raise invalid_deadline_error 

507 try: 

508 deadline = duration(milliseconds=deadline) 

509 except OverflowError: 

510 raise InvalidArgument( 

511 f"deadline={deadline!r} is invalid, because it is too large to represent " 

512 "as a timedelta. Use deadline=None to disable deadlines." 

513 ) from None 

514 if isinstance(deadline, datetime.timedelta): 

515 if deadline <= datetime.timedelta(0): 

516 raise InvalidArgument( 

517 f"deadline={deadline!r} is invalid, because it is impossible to meet a " 

518 "deadline <= 0. Use deadline=None to disable deadlines." 

519 ) 

520 return duration(seconds=deadline.total_seconds()) 

521 raise invalid_deadline_error 

522 

523 

524def _validate_backend(backend: str) -> str: 

525 if backend not in AVAILABLE_PROVIDERS: 

526 if backend == "crosshair": # pragma: no cover 

527 install = '`pip install "hypothesis[crosshair]"` and try again.' 

528 raise InvalidArgument(f"backend={backend!r} is not available. {install}") 

529 raise InvalidArgument( 

530 f"backend={backend!r} is not available - maybe you need to install a plugin?" 

531 f"\n Installed backends: {sorted(AVAILABLE_PROVIDERS)!r}" 

532 ) 

533 return backend 

534 

535 

536class settingsMeta(type): 

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

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

539 

540 @property 

541 def default(cls) -> Optional["settings"]: 

542 v = default_variable.value 

543 if v is not None: 

544 return v 

545 if getattr(settings, "_current_profile", None) is not None: 

546 assert settings._current_profile is not None 

547 settings.load_profile(settings._current_profile) 

548 assert default_variable.value is not None 

549 return default_variable.value 

550 

551 def __setattr__(cls, name: str, value: object) -> None: 

552 if name == "default": 

553 raise AttributeError( 

554 "Cannot assign to the property settings.default - " 

555 "consider using settings.load_profile instead." 

556 ) 

557 elif not name.startswith("_"): 

558 raise AttributeError( 

559 f"Cannot assign hypothesis.settings.{name}={value!r} - the settings " 

560 "class is immutable. You can change the global default " 

561 "settings with settings.load_profile, or use @settings(...) " 

562 "to decorate your test instead." 

563 ) 

564 super().__setattr__(name, value) 

565 

566 def __repr__(cls): 

567 return "hypothesis.settings" 

568 

569 

570class settings(metaclass=settingsMeta): 

571 """ 

572 A settings object controls the following aspects of test behavior: 

573 |~settings.max_examples|, |~settings.derandomize|, |~settings.database|, 

574 |~settings.verbosity|, |~settings.phases|, |~settings.stateful_step_count|, 

575 |~settings.report_multiple_bugs|, |~settings.suppress_health_check|, 

576 |~settings.deadline|, |~settings.print_blob|, and |~settings.backend|. 

577 

578 A settings object can be applied as a decorator to a test function, in which 

579 case that test function will use those settings. A test may only have one 

580 settings object applied to it. A settings object can also be passed to 

581 |settings.register_profile| or as a parent to another |settings|. 

582 

583 Attribute inheritance 

584 --------------------- 

585 

586 Settings objects are immutable once created. When a settings object is created, 

587 it uses the value specified for each attribute. Any attribute which is 

588 not specified will inherit from its value in the ``parent`` settings object. 

589 If ``parent`` is not passed, any attributes which are not specified will inherit 

590 from the current settings profile instead. 

591 

592 For instance, ``settings(max_examples=10)`` will have a ``max_examples`` of ``10``, 

593 and the value of all other attributes will be equal to its value in the 

594 current settings profile. 

595 

596 Changes made from activating a new settings profile with |settings.load_profile| 

597 will be reflected in settings objects created after the profile was loaded, 

598 but not in existing settings objects. 

599 

600 .. _builtin-profiles: 

601 

602 Built-in profiles 

603 ----------------- 

604 

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

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

607 

608 By default, the ``default`` profile is active. If the ``CI`` environment 

609 variable is set to any value, the ``ci`` profile is active by default. Hypothesis 

610 also automatically detects various vendor-specific CI environment variables. 

611 

612 The attributes of the currently active settings profile can be retrieved with 

613 ``settings()`` (so ``settings().max_examples`` is the currently active default 

614 for |settings.max_examples|). 

615 

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

617 

618 .. code-block:: python 

619 

620 default = settings.register_profile( 

621 "default", 

622 max_examples=100, 

623 derandomize=False, 

624 database=not_set, # see settings.database for default behavior 

625 verbosity=Verbosity.normal, 

626 phases=tuple(Phase), 

627 stateful_step_count=50, 

628 report_multiple_bugs=True, 

629 suppress_health_check=(), 

630 deadline=duration(milliseconds=200), 

631 print_blob=False, 

632 backend="hypothesis", 

633 ) 

634 

635 ci = settings.register_profile( 

636 "ci", 

637 parent=default, 

638 derandomize=True, 

639 deadline=None, 

640 database=None, 

641 print_blob=True, 

642 suppress_health_check=[HealthCheck.too_slow], 

643 ) 

644 

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

646 

647 .. code-block:: python 

648 

649 # run more examples in CI 

650 settings.register_profile( 

651 "ci", 

652 settings.get_profile("ci"), 

653 max_examples=1000, 

654 ) 

655 """ 

656 

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

658 _current_profile: ClassVar[str | None] = None 

659 

660 def __init__( 

661 self, 

662 parent: Optional["settings"] = None, 

663 *, 

664 # This looks pretty strange, but there's good reason: we want Mypy to detect 

665 # bad calls downstream, but not to freak out about the `= not_set` part even 

666 # though it's not semantically valid to pass that as an argument value. 

667 # The intended use is "like **kwargs, but more tractable for tooling". 

668 max_examples: int = not_set, # type: ignore 

669 derandomize: bool = not_set, # type: ignore 

670 database: Optional["ExampleDatabase"] = not_set, # type: ignore 

671 verbosity: "Verbosity" = not_set, # type: ignore 

672 phases: Collection["Phase"] = not_set, # type: ignore 

673 stateful_step_count: int = not_set, # type: ignore 

674 report_multiple_bugs: bool = not_set, # type: ignore 

675 suppress_health_check: Collection["HealthCheck"] = not_set, # type: ignore 

676 deadline: int | float | datetime.timedelta | None = not_set, # type: ignore 

677 print_blob: bool = not_set, # type: ignore 

678 backend: str = not_set, # type: ignore 

679 ) -> None: 

680 self._in_definition = True 

681 

682 if parent is not None: 

683 check_type(settings, parent, "parent") 

684 if derandomize not in (not_set, False): 

685 if database not in (not_set, None): # type: ignore 

686 raise InvalidArgument( 

687 "derandomize=True implies database=None, so passing " 

688 f"{database=} too is invalid." 

689 ) 

690 database = None 

691 

692 # fallback is None if we're creating the default settings object, and 

693 # the parent (or default settings object) otherwise 

694 self._fallback = parent or settings.default 

695 self._max_examples = ( 

696 self._fallback.max_examples # type: ignore 

697 if max_examples is not_set # type: ignore 

698 else _validate_max_examples(max_examples) 

699 ) 

700 self._derandomize = ( 

701 self._fallback.derandomize # type: ignore 

702 if derandomize is not_set # type: ignore 

703 else _validate_choices("derandomize", derandomize, choices=[True, False]) 

704 ) 

705 if database is not not_set: # type: ignore 

706 database = _validate_database(database) 

707 self._database = database 

708 self._cached_database = None 

709 self._verbosity = ( 

710 self._fallback.verbosity # type: ignore 

711 if verbosity is not_set # type: ignore 

712 else _validate_enum_value(Verbosity, verbosity, name="verbosity") 

713 ) 

714 self._phases = ( 

715 self._fallback.phases # type: ignore 

716 if phases is not_set # type: ignore 

717 else _validate_phases(phases) 

718 ) 

719 self._stateful_step_count = ( 

720 self._fallback.stateful_step_count # type: ignore 

721 if stateful_step_count is not_set # type: ignore 

722 else _validate_stateful_step_count(stateful_step_count) 

723 ) 

724 self._report_multiple_bugs = ( 

725 self._fallback.report_multiple_bugs # type: ignore 

726 if report_multiple_bugs is not_set # type: ignore 

727 else _validate_choices( 

728 "report_multiple_bugs", report_multiple_bugs, choices=[True, False] 

729 ) 

730 ) 

731 self._suppress_health_check = ( 

732 self._fallback.suppress_health_check # type: ignore 

733 if suppress_health_check is not_set # type: ignore 

734 else _validate_suppress_health_check(suppress_health_check) 

735 ) 

736 self._deadline = ( 

737 self._fallback.deadline # type: ignore 

738 if deadline is not_set # type: ignore 

739 else _validate_deadline(deadline) 

740 ) 

741 self._print_blob = ( 

742 self._fallback.print_blob # type: ignore 

743 if print_blob is not_set # type: ignore 

744 else _validate_choices("print_blob", print_blob, choices=[True, False]) 

745 ) 

746 self._backend = ( 

747 self._fallback.backend # type: ignore 

748 if backend is not_set # type: ignore 

749 else _validate_backend(backend) 

750 ) 

751 

752 self._in_definition = False 

753 

754 @property 

755 def max_examples(self): 

756 """ 

757 Once this many satisfying |test cases| have been considered without finding 

758 any failing test case, Hypothesis will stop looking. 

759 

760 .. note:: 

761 

762 Historically, Hypothesis referred to test cases as "examples", including in 

763 this setting name. We now refer to them as test cases throughout our 

764 documentation and codebase. 

765 

766 This setting is an exception: to avoid ecosystem churn, this setting will 

767 continue to be called ``max_examples``. Conceptually, it is better thought of 

768 as "max test cases". 

769 

770 Note that we might call your test function fewer times if we find a bug early 

771 or can tell that we've exhausted the search space; or more if we discard some 

772 test cases due to use of .filter(), assume(), or a few other things that can 

773 prevent the test case from completing successfully. 

774 

775 The default value is chosen to suit a workflow where the test will be part of 

776 a suite that is regularly executed locally or on a CI server, balancing total 

777 running time against the chance of missing a bug. 

778 

779 If you are writing one-off tests, running tens of thousands of test cases is 

780 quite reasonable as Hypothesis may miss uncommon bugs with default settings. 

781 For very complex code, we have observed Hypothesis finding novel bugs after 

782 *several million* test cases while testing :pypi:`SymPy <sympy>`. 

783 If you are running more than 100k test cases for a test, consider using our 

784 :ref:`integration for coverage-guided fuzzing <fuzz_one_input>` - it really 

785 shines when given minutes or hours to run. 

786 

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

788 

789 .. note:: 

790 

791 See :doc:`../explanation/test-case-count` for details on how |max_examples| 

792 interacts with other parts of Hypothesis. 

793 """ 

794 return self._max_examples 

795 

796 @property 

797 def derandomize(self): 

798 """ 

799 If True, seed Hypothesis' random number generator using a hash of the test 

800 function, so that every run will test the same set of test cases until you 

801 update Hypothesis, Python, or the test function. 

802 

803 This allows you to `check for regressions and look for bugs 

804 <https://blog.nelhage.com/post/two-kinds-of-testing/>`__ using separate 

805 settings profiles - for example running 

806 quick deterministic tests on every commit, and a longer non-deterministic 

807 nightly testing run. 

808 

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

810 """ 

811 return self._derandomize 

812 

813 @property 

814 def database(self): 

815 """ 

816 An instance of |ExampleDatabase| in which we will save failing |test cases|, 

817 and from which we will load previous failing test cases. 

818 

819 If not set, a |DirectoryBasedExampleDatabase| is created in the current 

820 working directory under ``.hypothesis/examples``. If this location is 

821 unusable, e.g. due to the lack of read or write permissions, Hypothesis 

822 will emit a warning and fall back to an |InMemoryExampleDatabase|. 

823 

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

825 

826 See the :ref:`database documentation <database>` for a list of database 

827 classes, and how to define custom database classes. 

828 """ 

829 from hypothesis.database import _db_for_path 

830 

831 # settings.database has two conflicting requirements: 

832 # * The default settings should respect changes to set_hypothesis_home_dir 

833 # in-between accesses 

834 # * `s.database is s.database` should be true, except for the default settings 

835 # 

836 # We therefore cache s.database for everything except the default settings, 

837 # which always recomputes dynamically. 

838 if self._fallback is None: 

839 # if self._fallback is None, we are the default settings, at which point 

840 # we should recompute the database dynamically 

841 assert self._database is not_set 

842 return _db_for_path(not_set) 

843 

844 # otherwise, we cache the database 

845 if self._cached_database is None: 

846 self._cached_database = ( 

847 self._fallback.database if self._database is not_set else self._database 

848 ) 

849 return self._cached_database 

850 

851 @property 

852 def verbosity(self): 

853 """ 

854 Control the verbosity level of Hypothesis messages. 

855 

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

857 up the verbosity setting. 

858 

859 .. code-block:: pycon 

860 

861 >>> from hypothesis import settings, Verbosity 

862 >>> from hypothesis.strategies import lists, integers 

863 >>> @given(lists(integers())) 

864 ... @settings(verbosity=Verbosity.verbose) 

865 ... def f(x): 

866 ... assert not any(x) 

867 ... f() 

868 Test case: [] 

869 Failing test case: [-1198601713, -67, 116, -29578] 

870 Shrunk test case to [-1198601713] 

871 Shrunk test case to [-128] 

872 Shrunk test case to [32] 

873 Shrunk test case to [1] 

874 [1] 

875 

876 The four levels are |Verbosity.quiet|, |Verbosity.normal|, 

877 |Verbosity.verbose|, and |Verbosity.debug|. |Verbosity.normal| is the 

878 default. For |Verbosity.quiet|, Hypothesis will not print anything out, 

879 not even the |minimal failing test case|. |Verbosity.debug| is basically 

880 |Verbosity.verbose| but a bit more so. You probably don't want it. 

881 

882 Verbosity can be passed either as a |Verbosity| enum value, or as the 

883 corresponding string value, or as the corresponding integer value. For 

884 example: 

885 

886 .. code-block:: python 

887 

888 # these three are equivalent 

889 settings(verbosity=Verbosity.verbose) 

890 settings(verbosity="verbose") 

891 

892 If you are using :pypi:`pytest`, you may also need to :doc:`disable 

893 output capturing for passing tests <pytest:how-to/capture-stdout-stderr>` 

894 to see verbose output as tests run. 

895 """ 

896 return self._verbosity 

897 

898 @property 

899 def phases(self): 

900 """ 

901 Control which phases should be run. 

902 

903 Hypothesis divides tests into logically distinct phases. 

904 

905 - |Phase.explicit|: Running |explicit examples| from |@example|. 

906 - |Phase.reuse|: Running |test cases| from the database which previously failed. 

907 - |Phase.generate|: Generating new random test cases. 

908 - |Phase.target|: Mutating test cases for :ref:`targeted property-based 

909 testing <targeted>`. Requires |Phase.generate|. 

910 - |Phase.shrink|: Shrinking |failing test cases|. 

911 - |Phase.explain|: Attempting to explain why a failure occurred. 

912 Requires |Phase.shrink|. 

913 

914 The phases argument accepts a collection with any subset of these. E.g. 

915 ``settings(phases=[Phase.generate, Phase.shrink])`` will generate new test cases 

916 and shrink them, but will not run explicit examples or reuse previous failures, 

917 while ``settings(phases=[Phase.explicit])`` will only run explicit examples 

918 from |@example|. 

919 

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

921 string value. For example: 

922 

923 .. code-block:: python 

924 

925 # these two are equivalent 

926 settings(phases=[Phase.explicit]) 

927 settings(phases=["explicit"]) 

928 

929 Following the first failure, Hypothesis will (usually, depending on 

930 which |Phase| is enabled) track which lines of code are always run on 

931 failing but never on passing inputs. On 3.12+, this uses 

932 :mod:`sys.monitoring`, while 3.11 and earlier uses :func:`python:sys.settrace`. 

933 For python 3.11 and earlier, we therefore automatically disable the explain 

934 phase on PyPy, or if you are using :pypi:`coverage` or a debugger. If 

935 there are no clearly suspicious lines of code, :pep:`we refuse the 

936 temptation to guess <20>`. 

937 

938 After shrinking to a minimal failing test case, Hypothesis will try to find 

939 parts of the test case -- e.g. separate args to |@given| 

940 -- which can vary freely without changing the result 

941 of that minimal failing test case. If the automated experiments run without 

942 finding a passing variation, we leave a comment in the final report: 

943 

944 .. code-block:: python 

945 

946 test_x_divided_by_y( 

947 x=0, # or any other generated value 

948 y=0, 

949 ) 

950 

951 Just remember that the *lack* of an explanation sometimes just means that 

952 Hypothesis couldn't efficiently find one, not that no explanation (or 

953 simpler failing test case) exists. 

954 """ 

955 

956 return self._phases 

957 

958 @property 

959 def stateful_step_count(self): 

960 """ 

961 The maximum number of times to call an additional |@rule| method in 

962 :ref:`stateful testing <stateful>` before we give up on finding a bug. 

963 

964 Note that this setting is effectively multiplicative with max_examples, 

965 as each test case will run for a maximum of ``stateful_step_count`` steps. 

966 

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

968 """ 

969 return self._stateful_step_count 

970 

971 @property 

972 def report_multiple_bugs(self): 

973 """ 

974 Because Hypothesis runs the test many times, it can sometimes find multiple 

975 bugs in a single run. Reporting all of them at once is usually very useful, 

976 but replacing the exceptions can occasionally clash with debuggers. 

977 If disabled, only the exception with the smallest minimal example is raised. 

978 

979 The default value is ``True``. 

980 """ 

981 return self._report_multiple_bugs 

982 

983 @property 

984 def suppress_health_check(self): 

985 """ 

986 Suppress the given |HealthCheck| exceptions. Those health checks will not 

987 be raised by Hypothesis. To suppress all health checks, you can pass 

988 ``suppress_health_check=list(HealthCheck)``. 

989 

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

991 the corresponding string value. For example: 

992 

993 .. code-block:: python 

994 

995 # these two are equivalent 

996 settings(suppress_health_check=[HealthCheck.filter_too_much]) 

997 settings(suppress_health_check=["filter_too_much"]) 

998 

999 Health checks are proactive warnings, not correctness errors, so we 

1000 encourage suppressing health checks where you have evaluated they will 

1001 not pose a problem, or where you have evaluated that fixing the underlying 

1002 issue is not worthwhile. 

1003 

1004 .. seealso:: 

1005 

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

1007 """ 

1008 return self._suppress_health_check 

1009 

1010 @property 

1011 def deadline(self): 

1012 """ 

1013 The maximum allowed duration of an individual |test case|, in milliseconds. 

1014 You can pass an integer, float, or timedelta. If ``None``, the deadline 

1015 is disabled entirely. 

1016 

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

1018 avoid flakiness due to timing variability. 

1019 

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

1021 ``None`` instead. 

1022 """ 

1023 return self._deadline 

1024 

1025 @property 

1026 def print_blob(self): 

1027 """ 

1028 If set to ``True``, Hypothesis will print code for |failing test cases| that 

1029 can be used with |@reproduce_failure| to reproduce the failing test case. 

1030 

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

1032 """ 

1033 return self._print_blob 

1034 

1035 @property 

1036 def backend(self): 

1037 """ 

1038 .. warning:: 

1039 

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

1041 

1042 The importable name of a backend which Hypothesis should use to generate 

1043 primitive types. We support heuristic-random, solver-based, and fuzzing-based 

1044 backends. 

1045 """ 

1046 return self._backend 

1047 

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

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

1050 

1051 The settings are later discovered by looking them up on the test itself. 

1052 """ 

1053 # Aliasing as Any avoids mypy errors (attr-defined) when accessing and 

1054 # setting custom attributes on the decorated function or class. 

1055 _test: Any = test 

1056 

1057 # Using the alias here avoids a mypy error (return-value) later when 

1058 # ``test`` is returned, because this check results in type refinement. 

1059 if not callable(_test): 

1060 raise InvalidArgument( 

1061 "settings objects can be called as a decorator with @given, " 

1062 f"but decorated {test=} is not callable." 

1063 ) 

1064 if inspect.isclass(test): 

1065 from hypothesis.stateful import RuleBasedStateMachine 

1066 

1067 if issubclass(_test, RuleBasedStateMachine): 

1068 attr_name = "_hypothesis_internal_settings_applied" 

1069 if getattr(test, attr_name, False): 

1070 raise InvalidArgument( 

1071 "Applying the @settings decorator twice would " 

1072 "overwrite the first version; merge their arguments " 

1073 "instead." 

1074 ) 

1075 setattr(test, attr_name, True) 

1076 _test.TestCase.settings = self 

1077 return test 

1078 else: 

1079 raise InvalidArgument( 

1080 "@settings(...) can only be used as a decorator on " 

1081 "functions, or on subclasses of RuleBasedStateMachine." 

1082 ) 

1083 if hasattr(_test, "_hypothesis_internal_settings_applied"): 

1084 # Can't use _hypothesis_internal_use_settings as an indicator that 

1085 # @settings was applied, because @given also assigns that attribute. 

1086 descr = get_pretty_function_description(test) 

1087 raise InvalidArgument( 

1088 f"{descr} has already been decorated with a settings object.\n" 

1089 f" Previous: {_test._hypothesis_internal_use_settings!r}\n" 

1090 f" This: {self!r}" 

1091 ) 

1092 

1093 _test._hypothesis_internal_use_settings = self 

1094 _test._hypothesis_internal_settings_applied = True 

1095 return test 

1096 

1097 def __setattr__(self, name: str, value: object) -> None: 

1098 if not name.startswith("_") and not self._in_definition: 

1099 raise AttributeError("settings objects are immutable") 

1100 return super().__setattr__(name, value) 

1101 

1102 def __repr__(self) -> str: 

1103 bits = sorted( 

1104 f"{name}={getattr(self, name)!r}" 

1105 for name in all_settings 

1106 if (name != "backend" or len(AVAILABLE_PROVIDERS) > 1) # experimental 

1107 ) 

1108 return "settings({})".format(", ".join(bits)) 

1109 

1110 def show_changed(self) -> str: 

1111 bits = [] 

1112 for name in all_settings: 

1113 value = getattr(self, name) 

1114 if value != getattr(default, name): 

1115 bits.append(f"{name}={value!r}") 

1116 return ", ".join(sorted(bits, key=len)) 

1117 

1118 @staticmethod 

1119 def register_profile( 

1120 name: str, 

1121 parent: Optional["settings"] = None, 

1122 **kwargs: Any, 

1123 ) -> None: 

1124 """ 

1125 Register a settings object as a settings profile, under the name ``name``. 

1126 The ``parent`` and ``kwargs`` arguments to this method are as for 

1127 |settings|. 

1128 

1129 If a settings profile already exists under ``name``, it will be overwritten. 

1130 Registering a profile with the same name as the currently active profile 

1131 will cause those changes to take effect in the active profile immediately, 

1132 and do not require reloading the profile. 

1133 

1134 Registered settings profiles can be retrieved later by name with 

1135 |settings.get_profile|. 

1136 """ 

1137 check_type(str, name, "name") 

1138 

1139 if ( 

1140 default_variable.value 

1141 and settings._current_profile 

1142 and default_variable.value != settings._profiles[settings._current_profile] 

1143 ): 

1144 note_deprecation( 

1145 "Cannot register a settings profile when the current settings differ " 

1146 "from the current profile (usually due to an @settings decorator). " 

1147 "Register profiles at module level instead.", 

1148 since="2025-11-15", 

1149 has_codemod=False, 

1150 ) 

1151 

1152 # if we just pass the parent and no kwargs, like 

1153 # settings.register_profile(settings(max_examples=10)) 

1154 # then optimize out the pointless intermediate settings object which 

1155 # would just forward everything to the parent. 

1156 settings._profiles[name] = ( 

1157 parent 

1158 if parent is not None and not kwargs 

1159 else settings(parent=parent, **kwargs) 

1160 ) 

1161 if settings._current_profile == name: 

1162 settings.load_profile(name) 

1163 

1164 @staticmethod 

1165 def get_profile(name: str) -> "settings": 

1166 """ 

1167 Returns the settings profile registered under ``name``. If no settings 

1168 profile is registered under ``name``, raises |InvalidArgument|. 

1169 """ 

1170 check_type(str, name, "name") 

1171 try: 

1172 return settings._profiles[name] 

1173 except KeyError: 

1174 raise InvalidArgument(f"Profile {name!r} is not registered") from None 

1175 

1176 @staticmethod 

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

1178 """ 

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

1180 

1181 If no settings profile is registered under ``name``, raises |InvalidArgument|. 

1182 """ 

1183 check_type(str, name, "name") 

1184 settings._current_profile = name 

1185 default_variable.value = settings.get_profile(name) 

1186 

1187 @staticmethod 

1188 def get_current_profile_name() -> str: 

1189 """ 

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

1191 

1192 .. code-block:: python 

1193 

1194 >>> settings.load_profile("myprofile") 

1195 >>> settings.get_current_profile_name() 

1196 'myprofile' 

1197 """ 

1198 assert settings._current_profile is not None 

1199 return settings._current_profile 

1200 

1201 

1202@contextlib.contextmanager 

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

1204 with default_variable.with_value(s): 

1205 yield s 

1206 

1207 

1208default = settings( 

1209 max_examples=100, 

1210 derandomize=False, 

1211 database=not_set, # type: ignore 

1212 verbosity=Verbosity.normal, 

1213 phases=tuple(Phase), 

1214 stateful_step_count=50, 

1215 report_multiple_bugs=True, 

1216 suppress_health_check=(), 

1217 deadline=duration(milliseconds=200), 

1218 print_blob=False, 

1219 backend="hypothesis", 

1220) 

1221settings.register_profile("default", default) 

1222settings.load_profile("default") 

1223 

1224assert settings.default is not None 

1225 

1226CI = settings( 

1227 derandomize=True, 

1228 deadline=None, 

1229 database=None, 

1230 print_blob=True, 

1231 suppress_health_check=[HealthCheck.too_slow], 

1232) 

1233 

1234settings.register_profile("ci", CI) 

1235 

1236 

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

1238 settings.load_profile("ci") 

1239 

1240assert settings.default is not None 

1241 

1242 

1243# Check that the kwonly args to settings.__init__ is the same as the set of 

1244# defined settings - in case we've added or remove something from one but 

1245# not the other. 

1246assert set(all_settings) == { 

1247 p.name 

1248 for p in inspect.signature(settings.__init__).parameters.values() 

1249 if p.kind == inspect.Parameter.KEYWORD_ONLY 

1250}