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 final falsifying example. 

71 """ 

72 

73 normal = "normal" 

74 """ 

75 Standard verbosity. Hypothesis will print the falsifying example, alongside 

76 any notes made with |note| (only for the falsfying example). 

77 """ 

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 examples will be reused. 

153 """ 

154 

155 generate = "generate" 

156 """ 

157 Controls whether new examples will be generated. 

158 """ 

159 

160 target = "target" 

161 """ 

162 Controls whether examples will be mutated for targeting. 

163 """ 

164 

165 shrink = "shrink" 

166 """ 

167 Controls whether examples 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 example. 

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 examples 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 examples, 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 example, 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 example 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 examples, 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 examples have been considered without finding any 

758 counter-example, Hypothesis will stop looking. 

759 

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

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

762 examples due to use of .filter(), assume(), or a few other things that can 

763 prevent the test case from completing successfully. 

764 

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

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

767 running time against the chance of missing a bug. 

768 

769 If you are writing one-off tests, running tens of thousands of examples is 

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

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

772 *several million* examples while testing :pypi:`SymPy <sympy>`. 

773 If you are running more than 100k examples for a test, consider using our 

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

775 shines when given minutes or hours to run. 

776 

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

778 """ 

779 return self._max_examples 

780 

781 @property 

782 def derandomize(self): 

783 """ 

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

785 function, so that every run will test the same set of examples until you 

786 update Hypothesis, Python, or the test function. 

787 

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

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

790 settings profiles - for example running 

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

792 nightly testing run. 

793 

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

795 """ 

796 return self._derandomize 

797 

798 @property 

799 def database(self): 

800 """ 

801 An instance of |ExampleDatabase| that will be used to save examples to 

802 and load previous examples from. 

803 

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

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

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

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

808 

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

810 

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

812 classes, and how to define custom database classes. 

813 """ 

814 from hypothesis.database import _db_for_path 

815 

816 # settings.database has two conflicting requirements: 

817 # * The default settings should respect changes to set_hypothesis_home_dir 

818 # in-between accesses 

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

820 # 

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

822 # which always recomputes dynamically. 

823 if self._fallback is None: 

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

825 # we should recompute the database dynamically 

826 assert self._database is not_set 

827 return _db_for_path(not_set) 

828 

829 # otherwise, we cache the database 

830 if self._cached_database is None: 

831 self._cached_database = ( 

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

833 ) 

834 return self._cached_database 

835 

836 @property 

837 def verbosity(self): 

838 """ 

839 Control the verbosity level of Hypothesis messages. 

840 

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

842 up the verbosity setting. 

843 

844 .. code-block:: pycon 

845 

846 >>> from hypothesis import settings, Verbosity 

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

848 >>> @given(lists(integers())) 

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

850 ... def f(x): 

851 ... assert not any(x) 

852 ... f() 

853 Trying example: [] 

854 Falsifying example: [-1198601713, -67, 116, -29578] 

855 Shrunk example to [-1198601713] 

856 Shrunk example to [-128] 

857 Shrunk example to [32] 

858 Shrunk example to [1] 

859 [1] 

860 

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

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

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

864 not even the final falsifying example. |Verbosity.debug| is basically 

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

866 

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

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

869 example: 

870 

871 .. code-block:: python 

872 

873 # these three are equivalent 

874 settings(verbosity=Verbosity.verbose) 

875 settings(verbosity="verbose") 

876 

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

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

879 to see verbose output as tests run. 

880 """ 

881 return self._verbosity 

882 

883 @property 

884 def phases(self): 

885 """ 

886 Control which phases should be run. 

887 

888 Hypothesis divides tests into logically distinct phases. 

889 

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

891 - |Phase.reuse|: Running examples from the database which previously failed. 

892 - |Phase.generate|: Generating new random examples. 

893 - |Phase.target|: Mutating examples for :ref:`targeted property-based 

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

895 - |Phase.shrink|: Shrinking failing examples. 

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

897 Requires |Phase.shrink|. 

898 

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

900 ``settings(phases=[Phase.generate, Phase.shrink])`` will generate new examples 

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

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

903 from |@example|. 

904 

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

906 string value. For example: 

907 

908 .. code-block:: python 

909 

910 # these two are equivalent 

911 settings(phases=[Phase.explicit]) 

912 settings(phases=["explicit"]) 

913 

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

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

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

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

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

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

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

921 temptation to guess <20>`. 

922 

923 After shrinking to a minimal failing example, Hypothesis will try to find 

924 parts of the example -- e.g. separate args to |@given| 

925 -- which can vary freely without changing the result 

926 of that minimal failing example. If the automated experiments run without 

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

928 

929 .. code-block:: python 

930 

931 test_x_divided_by_y( 

932 x=0, # or any other generated value 

933 y=0, 

934 ) 

935 

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

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

938 simpler failing example) exists. 

939 """ 

940 

941 return self._phases 

942 

943 @property 

944 def stateful_step_count(self): 

945 """ 

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

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

948 

949 Note that this setting is effectively multiplicative with max_examples, 

950 as each example will run for a maximum of ``stateful_step_count`` steps. 

951 

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

953 """ 

954 return self._stateful_step_count 

955 

956 @property 

957 def report_multiple_bugs(self): 

958 """ 

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

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

961 but replacing the exceptions can occasionally clash with debuggers. 

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

963 

964 The default value is ``True``. 

965 """ 

966 return self._report_multiple_bugs 

967 

968 @property 

969 def suppress_health_check(self): 

970 """ 

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

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

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

974 

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

976 the corresponding string value. For example: 

977 

978 .. code-block:: python 

979 

980 # these two are equivalent 

981 settings(suppress_health_check=[HealthCheck.filter_too_much]) 

982 settings(suppress_health_check=["filter_too_much"]) 

983 

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

985 encourage suppressing health checks where you have evaluated they will 

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

987 issue is not worthwhile. 

988 

989 .. seealso:: 

990 

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

992 """ 

993 return self._suppress_health_check 

994 

995 @property 

996 def deadline(self): 

997 """ 

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

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

1000 is disabled entirely. 

1001 

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

1003 avoid flakiness due to timing variability. 

1004 

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

1006 ``None`` instead. 

1007 """ 

1008 return self._deadline 

1009 

1010 @property 

1011 def print_blob(self): 

1012 """ 

1013 If set to ``True``, Hypothesis will print code for failing examples that 

1014 can be used with |@reproduce_failure| to reproduce the failing example. 

1015 

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

1017 """ 

1018 return self._print_blob 

1019 

1020 @property 

1021 def backend(self): 

1022 """ 

1023 .. warning:: 

1024 

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

1026 

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

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

1029 backends. 

1030 """ 

1031 return self._backend 

1032 

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

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

1035 

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

1037 """ 

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

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

1040 _test: Any = test 

1041 

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

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

1044 if not callable(_test): 

1045 raise InvalidArgument( 

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

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

1048 ) 

1049 if inspect.isclass(test): 

1050 from hypothesis.stateful import RuleBasedStateMachine 

1051 

1052 if issubclass(_test, RuleBasedStateMachine): 

1053 attr_name = "_hypothesis_internal_settings_applied" 

1054 if getattr(test, attr_name, False): 

1055 raise InvalidArgument( 

1056 "Applying the @settings decorator twice would " 

1057 "overwrite the first version; merge their arguments " 

1058 "instead." 

1059 ) 

1060 setattr(test, attr_name, True) 

1061 _test.TestCase.settings = self 

1062 return test 

1063 else: 

1064 raise InvalidArgument( 

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

1066 "functions, or on subclasses of RuleBasedStateMachine." 

1067 ) 

1068 if hasattr(_test, "_hypothesis_internal_settings_applied"): 

1069 # Can't use _hypothesis_internal_use_settings as an indicator that 

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

1071 descr = get_pretty_function_description(test) 

1072 raise InvalidArgument( 

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

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

1075 f" This: {self!r}" 

1076 ) 

1077 

1078 _test._hypothesis_internal_use_settings = self 

1079 _test._hypothesis_internal_settings_applied = True 

1080 return test 

1081 

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

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

1084 raise AttributeError("settings objects are immutable") 

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

1086 

1087 def __repr__(self) -> str: 

1088 bits = sorted( 

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

1090 for name in all_settings 

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

1092 ) 

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

1094 

1095 def show_changed(self) -> str: 

1096 bits = [] 

1097 for name in all_settings: 

1098 value = getattr(self, name) 

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

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

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

1102 

1103 @staticmethod 

1104 def register_profile( 

1105 name: str, 

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

1107 **kwargs: Any, 

1108 ) -> None: 

1109 """ 

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

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

1112 |settings|. 

1113 

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

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

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

1117 and do not require reloading the profile. 

1118 

1119 Registered settings profiles can be retrieved later by name with 

1120 |settings.get_profile|. 

1121 """ 

1122 check_type(str, name, "name") 

1123 

1124 if ( 

1125 default_variable.value 

1126 and settings._current_profile 

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

1128 ): 

1129 note_deprecation( 

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

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

1132 "Register profiles at module level instead.", 

1133 since="2025-11-15", 

1134 has_codemod=False, 

1135 ) 

1136 

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

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

1139 # then optimize out the pointless intermediate settings object which 

1140 # would just forward everything to the parent. 

1141 settings._profiles[name] = ( 

1142 parent 

1143 if parent is not None and not kwargs 

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

1145 ) 

1146 if settings._current_profile == name: 

1147 settings.load_profile(name) 

1148 

1149 @staticmethod 

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

1151 """ 

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

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

1154 """ 

1155 check_type(str, name, "name") 

1156 try: 

1157 return settings._profiles[name] 

1158 except KeyError: 

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

1160 

1161 @staticmethod 

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

1163 """ 

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

1165 

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

1167 """ 

1168 check_type(str, name, "name") 

1169 settings._current_profile = name 

1170 default_variable.value = settings.get_profile(name) 

1171 

1172 @staticmethod 

1173 def get_current_profile_name() -> str: 

1174 """ 

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

1176 

1177 .. code-block:: python 

1178 

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

1180 >>> settings.get_current_profile_name() 

1181 'myprofile' 

1182 """ 

1183 assert settings._current_profile is not None 

1184 return settings._current_profile 

1185 

1186 

1187@contextlib.contextmanager 

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

1189 with default_variable.with_value(s): 

1190 yield s 

1191 

1192 

1193default = settings( 

1194 max_examples=100, 

1195 derandomize=False, 

1196 database=not_set, # type: ignore 

1197 verbosity=Verbosity.normal, 

1198 phases=tuple(Phase), 

1199 stateful_step_count=50, 

1200 report_multiple_bugs=True, 

1201 suppress_health_check=(), 

1202 deadline=duration(milliseconds=200), 

1203 print_blob=False, 

1204 backend="hypothesis", 

1205) 

1206settings.register_profile("default", default) 

1207settings.load_profile("default") 

1208 

1209assert settings.default is not None 

1210 

1211CI = settings( 

1212 derandomize=True, 

1213 deadline=None, 

1214 database=None, 

1215 print_blob=True, 

1216 suppress_health_check=[HealthCheck.too_slow], 

1217) 

1218 

1219settings.register_profile("ci", CI) 

1220 

1221 

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

1223 settings.load_profile("ci") 

1224 

1225assert settings.default is not None 

1226 

1227 

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

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

1230# not the other. 

1231assert set(all_settings) == { 

1232 p.name 

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

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

1235}