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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

345 statements  

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

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

3# 

4# Copyright the Hypothesis Authors. 

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

6# 

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

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

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

10 

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

12 

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

14this module can be modified. 

15""" 

16 

17import contextlib 

18import datetime 

19import inspect 

20import os 

21import warnings 

22from collections.abc import Collection, Generator, Sequence 

23from enum import Enum, EnumMeta, unique 

24from functools import total_ordering 

25from typing import ( 

26 TYPE_CHECKING, 

27 Any, 

28 ClassVar, 

29 Optional, 

30 TypeVar, 

31) 

32 

33from hypothesis.errors import ( 

34 HypothesisDeprecationWarning, 

35 InvalidArgument, 

36) 

37from hypothesis.internal.conjecture.providers import AVAILABLE_PROVIDERS 

38from hypothesis.internal.reflection import get_pretty_function_description 

39from hypothesis.internal.validation import check_type, try_convert 

40from hypothesis.utils.conventions import not_set 

41from hypothesis.utils.dynamicvariables import DynamicVariable 

42 

43if TYPE_CHECKING: 

44 from hypothesis.database import ExampleDatabase 

45 

46__all__ = ["settings"] 

47 

48T = TypeVar("T") 

49all_settings: list[str] = [ 

50 "max_examples", 

51 "derandomize", 

52 "database", 

53 "verbosity", 

54 "phases", 

55 "stateful_step_count", 

56 "report_multiple_bugs", 

57 "suppress_health_check", 

58 "deadline", 

59 "print_blob", 

60 "backend", 

61] 

62 

63 

64@unique 

65@total_ordering 

66class Verbosity(Enum): 

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

68 

69 quiet = "quiet" 

70 """ 

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

72 """ 

73 

74 normal = "normal" 

75 """ 

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

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

78 """ 

79 

80 verbose = "verbose" 

81 """ 

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

83 will: 

84 

85 * Print each test case as it tries it 

86 * Print any notes made with |note| for each test case 

87 * Print each shrinking attempt 

88 * Print all explicit failing examples when using |@example|, instead of only 

89 the simplest one 

90 """ 

91 

92 debug = "debug" 

93 """ 

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

95 don't want this. 

96 """ 

97 

98 @classmethod 

99 def _missing_(cls, value): 

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

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

102 int_to_name = {0: "quiet", 1: "normal", 2: "verbose", 3: "debug"} 

103 if value in int_to_name: 

104 note_deprecation( 

105 f"Passing Verbosity({value}) as an integer is deprecated. " 

106 "Hypothesis now treats Verbosity values as strings, not integers. " 

107 f"Use Verbosity.{int_to_name[value]} instead.", 

108 since="2025-11-05", 

109 has_codemod=False, 

110 stacklevel=2, 

111 ) 

112 return cls(int_to_name[value]) 

113 return None 

114 

115 def __repr__(self) -> str: 

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

117 

118 @staticmethod 

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

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

121 mapping = { 

122 Verbosity.quiet.name: 0, 

123 Verbosity.normal.name: 1, 

124 Verbosity.verbose.name: 2, 

125 Verbosity.debug.name: 3, 

126 } 

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

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

129 return mapping[value.name] 

130 

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

132 if isinstance(other, Verbosity): 

133 return super().__eq__(other) 

134 return Verbosity._int_value(self) == other 

135 

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

137 value1 = Verbosity._int_value(self) 

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

139 return value1 > value2 

140 

141 

142@unique 

143class Phase(Enum): 

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

145 

146 explicit = "explicit" 

147 """ 

148 Controls whether explicit examples are run. 

149 """ 

150 

151 reuse = "reuse" 

152 """ 

153 Controls whether previous examples will be reused. 

154 """ 

155 

156 generate = "generate" 

157 """ 

158 Controls whether new examples will be generated. 

159 """ 

160 

161 target = "target" 

162 """ 

163 Controls whether examples will be mutated for targeting. 

164 """ 

165 

166 shrink = "shrink" 

167 """ 

168 Controls whether examples will be shrunk. 

169 """ 

170 

171 explain = "explain" 

172 """ 

173 Controls whether Hypothesis attempts to explain test failures. 

174 

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

176 can't find a useful explanation, we'll just print the minimal failing example. 

177 """ 

178 

179 @classmethod 

180 def _missing_(cls, value): 

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

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

183 int_to_name = { 

184 0: "explicit", 

185 1: "reuse", 

186 2: "generate", 

187 3: "target", 

188 4: "shrink", 

189 5: "explain", 

190 } 

191 if value in int_to_name: 

192 note_deprecation( 

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

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

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

196 since="2025-11-05", 

197 has_codemod=False, 

198 stacklevel=2, 

199 ) 

200 return cls(int_to_name[value]) 

201 return None 

202 

203 def __repr__(self) -> str: 

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

205 

206 

207class HealthCheckMeta(EnumMeta): 

208 def __iter__(self): 

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

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

211 

212 

213@unique 

214class HealthCheck(Enum, metaclass=HealthCheckMeta): 

215 """ 

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

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

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

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

220 will raise a corresponding health check. 

221 

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

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

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

225 

226 With the exception of |HealthCheck.function_scoped_fixture| and 

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

228 problems, not correctness errors. 

229 

230 Disabling health checks 

231 ----------------------- 

232 

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

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

235 

236 .. seealso:: 

237 

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

239 

240 Correctness health checks 

241 ------------------------- 

242 

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

244 problems. 

245 

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

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

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

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

250 ensure you have considered this case. 

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

252 been executed multiple times with multiple distinct executors. 

253 

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

255 suppressing them may result in an unsound test. 

256 """ 

257 

258 @classmethod 

259 def _missing_(cls, value): 

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

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

262 int_to_name = { 

263 1: "data_too_large", 

264 2: "filter_too_much", 

265 3: "too_slow", 

266 5: "return_value", 

267 7: "large_base_example", 

268 8: "not_a_test_method", 

269 9: "function_scoped_fixture", 

270 10: "differing_executors", 

271 11: "nested_given", 

272 } 

273 if value in int_to_name: 

274 note_deprecation( 

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

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

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

278 since="2025-11-05", 

279 has_codemod=False, 

280 stacklevel=2, 

281 ) 

282 return cls(int_to_name[value]) 

283 return None 

284 

285 def __repr__(self) -> str: 

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

287 

288 @classmethod 

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

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

291 note_deprecation( 

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

293 since="2023-04-16", 

294 has_codemod=True, 

295 stacklevel=1, 

296 ) 

297 return list(HealthCheck) 

298 

299 data_too_large = "data_too_large" 

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

301 

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

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

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

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

306 this health check. 

307 """ 

308 

309 filter_too_much = "filter_too_much" 

310 """Check for when the test is filtering out too many examples, either 

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

312 internal reasons.""" 

313 

314 too_slow = "too_slow" 

315 """ 

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

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

318 can result in very slow tests overall. 

319 """ 

320 

321 return_value = "return_value" 

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

323 

324 large_base_example = "large_base_example" 

325 """ 

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

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

328 shrink failing inputs. 

329 """ 

330 

331 not_a_test_method = "not_a_test_method" 

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

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

334 

335 function_scoped_fixture = "function_scoped_fixture" 

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

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

338 for the whole function, not once per example, and this is usually not what 

339 you want. 

340 

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

342 state for every example need to do so manually within the test itself, 

343 typically using an appropriate context manager. 

344 

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

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

347 examples, but for some reason you cannot use a wider fixture scope 

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

349 

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

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

352 

353 differing_executors = "differing_executors" 

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

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

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

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

358 for things to go wrong. 

359 

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

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

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

363 specified on leaf subclasses.""" 

364 

365 nested_given = "nested_given" 

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

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

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

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

370 |@given|. 

371 

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

373 quadratic behavior and cannot easily reexpress the inner function with 

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

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

376 |@given|. Setting it on the inner 

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

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

379 |@given| except the innermost one. 

380 """ 

381 

382 

383class duration(datetime.timedelta): 

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

385 

386 def __repr__(self) -> str: 

387 ms = self.total_seconds() * 1000 

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

389 

390 

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

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

393_CI_VARS = { 

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

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

396 "__TOX_ENVIRONMENT_VARIABLE_ORIGINAL_CI": None, 

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

398 "bamboo.buildKey": None, # Bamboo 

399 "BUILDKITE": "true", # Buildkite 

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

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

402 "CODEBUILD_BUILD_ID": None, # CodeBuild 

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

404 "GITLAB_CI": None, # GitLab CI 

405 "HEROKU_TEST_RUN_ID": None, # Heroku CI 

406 "TEAMCITY_VERSION": None, # TeamCity 

407} 

408 

409 

410def is_in_ci() -> bool: 

411 return any( 

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

413 for key, value in _CI_VARS.items() 

414 ) 

415 

416 

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

418 

419 

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

421 if value not in choices: 

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

423 raise InvalidArgument(msg) 

424 return value 

425 

426 

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

428 try: 

429 return cls(value) 

430 except ValueError: 

431 raise InvalidArgument( 

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

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

434 ) from None 

435 

436 

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

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

439 if max_examples < 1: 

440 raise InvalidArgument( 

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

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

443 ) 

444 return max_examples 

445 

446 

447def _validate_database( 

448 database: Optional["ExampleDatabase"], 

449) -> Optional["ExampleDatabase"]: 

450 from hypothesis.database import ExampleDatabase 

451 

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

453 return database 

454 raise InvalidArgument( 

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

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

457 "hypothesis.database" 

458 ) 

459 

460 

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

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

463 phases = tuple( 

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

465 ) 

466 # sort by definition order 

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

468 

469 

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

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

472 if stateful_step_count < 1: 

473 raise InvalidArgument( 

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

475 ) 

476 return stateful_step_count 

477 

478 

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

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

481 for health_check in suppressions: 

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

483 note_deprecation( 

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

485 since="2023-03-15", 

486 has_codemod=False, 

487 stacklevel=2, 

488 ) 

489 return tuple( 

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

491 for health_check in suppressions 

492 ) 

493 

494 

495def _validate_deadline( 

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

497) -> duration | None: 

498 if deadline is None: 

499 return deadline 

500 invalid_deadline_error = InvalidArgument( 

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

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

503 "per-test-case deadline." 

504 ) 

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

506 if isinstance(deadline, bool): 

507 raise invalid_deadline_error 

508 try: 

509 deadline = duration(milliseconds=deadline) 

510 except OverflowError: 

511 raise InvalidArgument( 

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

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

514 ) from None 

515 if isinstance(deadline, datetime.timedelta): 

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

517 raise InvalidArgument( 

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

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

520 ) 

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

522 raise invalid_deadline_error 

523 

524 

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

526 if backend not in AVAILABLE_PROVIDERS: 

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

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

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

530 raise InvalidArgument( 

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

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

533 ) 

534 return backend 

535 

536 

537class settingsMeta(type): 

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

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

540 

541 @property 

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

543 v = default_variable.value 

544 if v is not None: 

545 return v 

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

547 assert settings._current_profile is not None 

548 settings.load_profile(settings._current_profile) 

549 assert default_variable.value is not None 

550 return default_variable.value 

551 

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

553 if name == "default": 

554 raise AttributeError( 

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

556 "consider using settings.load_profile instead." 

557 ) 

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

559 raise AttributeError( 

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

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

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

563 "to decorate your test instead." 

564 ) 

565 super().__setattr__(name, value) 

566 

567 def __repr__(cls): 

568 return "hypothesis.settings" 

569 

570 

571class settings(metaclass=settingsMeta): 

572 """ 

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

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

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

576 |~settings.report_multiple_bugs|, |~settings.suppress_health_check|, 

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

578 

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

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

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

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

583 

584 Attribute inheritance 

585 --------------------- 

586 

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

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

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

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

591 from the current settings profile instead. 

592 

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

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

595 current settings profile. 

596 

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

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

599 but not in existing settings objects. 

600 

601 .. _builtin-profiles: 

602 

603 Built-in profiles 

604 ----------------- 

605 

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

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

608 

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

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

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

612 

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

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

615 for |settings.max_examples|). 

616 

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

618 

619 .. code-block:: python 

620 

621 default = settings.register_profile( 

622 "default", 

623 max_examples=100, 

624 derandomize=False, 

625 database=not_set, # see settings.database for the default database 

626 verbosity=Verbosity.normal, 

627 phases=tuple(Phase), 

628 stateful_step_count=50, 

629 report_multiple_bugs=True, 

630 suppress_health_check=(), 

631 deadline=duration(milliseconds=200), 

632 print_blob=False, 

633 backend="hypothesis", 

634 ) 

635 

636 ci = settings.register_profile( 

637 "ci", 

638 parent=default, 

639 derandomize=True, 

640 deadline=None, 

641 database=None, 

642 print_blob=True, 

643 suppress_health_check=[HealthCheck.too_slow], 

644 ) 

645 

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

647 

648 .. code-block:: python 

649 

650 # run more examples in CI 

651 settings.register_profile( 

652 "ci", 

653 settings.get_profile("ci"), 

654 max_examples=1000, 

655 ) 

656 """ 

657 

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

659 _current_profile: ClassVar[str | None] = None 

660 

661 def __init__( 

662 self, 

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

664 *, 

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

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

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

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

669 max_examples: int = not_set, # type: ignore 

670 derandomize: bool = not_set, # type: ignore 

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

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

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

674 stateful_step_count: int = not_set, # type: ignore 

675 report_multiple_bugs: bool = not_set, # type: ignore 

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

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

678 print_blob: bool = not_set, # type: ignore 

679 backend: str = not_set, # type: ignore 

680 ) -> None: 

681 self._in_definition = True 

682 

683 if parent is not None: 

684 check_type(settings, parent, "parent") 

685 if derandomize not in (not_set, False): 

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

687 raise InvalidArgument( 

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

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

690 ) 

691 database = None 

692 

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

694 # the parent (or default settings object) otherwise 

695 self._fallback = parent or settings.default 

696 self._max_examples = ( 

697 self._fallback.max_examples # type: ignore 

698 if max_examples is not_set # type: ignore 

699 else _validate_max_examples(max_examples) 

700 ) 

701 self._derandomize = ( 

702 self._fallback.derandomize # type: ignore 

703 if derandomize is not_set # type: ignore 

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

705 ) 

706 if database is not not_set: # type: ignore 

707 database = _validate_database(database) 

708 self._database = database 

709 self._cached_database = None 

710 self._verbosity = ( 

711 self._fallback.verbosity # type: ignore 

712 if verbosity is not_set # type: ignore 

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

714 ) 

715 self._phases = ( 

716 self._fallback.phases # type: ignore 

717 if phases is not_set # type: ignore 

718 else _validate_phases(phases) 

719 ) 

720 self._stateful_step_count = ( 

721 self._fallback.stateful_step_count # type: ignore 

722 if stateful_step_count is not_set # type: ignore 

723 else _validate_stateful_step_count(stateful_step_count) 

724 ) 

725 self._report_multiple_bugs = ( 

726 self._fallback.report_multiple_bugs # type: ignore 

727 if report_multiple_bugs is not_set # type: ignore 

728 else _validate_choices( 

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

730 ) 

731 ) 

732 self._suppress_health_check = ( 

733 self._fallback.suppress_health_check # type: ignore 

734 if suppress_health_check is not_set # type: ignore 

735 else _validate_suppress_health_check(suppress_health_check) 

736 ) 

737 self._deadline = ( 

738 self._fallback.deadline # type: ignore 

739 if deadline is not_set # type: ignore 

740 else _validate_deadline(deadline) 

741 ) 

742 self._print_blob = ( 

743 self._fallback.print_blob # type: ignore 

744 if print_blob is not_set # type: ignore 

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

746 ) 

747 self._backend = ( 

748 self._fallback.backend # type: ignore 

749 if backend is not_set # type: ignore 

750 else _validate_backend(backend) 

751 ) 

752 

753 self._in_definition = False 

754 

755 @property 

756 def max_examples(self): 

757 """ 

758 Once this many satisfying examples have been considered without finding any 

759 counter-example, Hypothesis will stop looking. 

760 

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

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

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

764 prevent the test case from completing successfully. 

765 

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

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

768 running time against the chance of missing a bug. 

769 

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

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

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

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

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

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

776 shines when given minutes or hours to run. 

777 

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

779 """ 

780 return self._max_examples 

781 

782 @property 

783 def derandomize(self): 

784 """ 

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

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

787 update Hypothesis, Python, or the test function. 

788 

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

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

791 settings profiles - for example running 

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

793 nightly testing run. 

794 

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

796 """ 

797 return self._derandomize 

798 

799 @property 

800 def database(self): 

801 """ 

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

803 and load previous examples from. 

804 

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

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

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

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

809 

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

811 

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

813 classes, and how to define custom database classes. 

814 """ 

815 from hypothesis.database import _db_for_path 

816 

817 # settings.database has two conflicting requirements: 

818 # * The default settings should respect changes to set_hypothesis_home_dir 

819 # in-between accesses 

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

821 # 

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

823 # which always recomputes dynamically. 

824 if self._fallback is None: 

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

826 # we should recompute the database dynamically 

827 assert self._database is not_set 

828 return _db_for_path(not_set) 

829 

830 # otherwise, we cache the database 

831 if self._cached_database is None: 

832 self._cached_database = ( 

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

834 ) 

835 return self._cached_database 

836 

837 @property 

838 def verbosity(self): 

839 """ 

840 Control the verbosity level of Hypothesis messages. 

841 

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

843 up the verbosity setting. 

844 

845 .. code-block:: pycon 

846 

847 >>> from hypothesis import settings, Verbosity 

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

849 >>> @given(lists(integers())) 

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

851 ... def f(x): 

852 ... assert not any(x) 

853 ... f() 

854 Trying example: [] 

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

856 Shrunk example to [-1198601713] 

857 Shrunk example to [-128] 

858 Shrunk example to [32] 

859 Shrunk example to [1] 

860 [1] 

861 

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

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

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

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

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

867 

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

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

870 example: 

871 

872 .. code-block:: python 

873 

874 # these three are equivalent 

875 settings(verbosity=Verbosity.verbose) 

876 settings(verbosity="verbose") 

877 

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

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

880 to see verbose output as tests run. 

881 """ 

882 return self._verbosity 

883 

884 @property 

885 def phases(self): 

886 """ 

887 Control which phases should be run. 

888 

889 Hypothesis divides tests into logically distinct phases. 

890 

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

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

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

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

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

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

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

898 Requires |Phase.shrink|. 

899 

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

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

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

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

904 from |@example|. 

905 

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

907 string value. For example: 

908 

909 .. code-block:: python 

910 

911 # these two are equivalent 

912 settings(phases=[Phase.explicit]) 

913 settings(phases=["explicit"]) 

914 

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

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

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

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

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

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

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

922 temptation to guess <20>`. 

923 

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

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

926 -- which can vary freely without changing the result 

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

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

929 

930 .. code-block:: python 

931 

932 test_x_divided_by_y( 

933 x=0, # or any other generated value 

934 y=0, 

935 ) 

936 

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

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

939 simpler failing example) exists. 

940 """ 

941 

942 return self._phases 

943 

944 @property 

945 def stateful_step_count(self): 

946 """ 

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

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

949 

950 Note that this setting is effectively multiplicative with max_examples, 

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

952 

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

954 """ 

955 return self._stateful_step_count 

956 

957 @property 

958 def report_multiple_bugs(self): 

959 """ 

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

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

962 but replacing the exceptions can occasionally clash with debuggers. 

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

964 

965 The default value is ``True``. 

966 """ 

967 return self._report_multiple_bugs 

968 

969 @property 

970 def suppress_health_check(self): 

971 """ 

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

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

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

975 

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

977 the corresponding string value. For example: 

978 

979 .. code-block:: python 

980 

981 # these two are equivalent 

982 settings(suppress_health_check=[HealthCheck.filter_too_much]) 

983 settings(suppress_health_check=["filter_too_much"]) 

984 

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

986 encourage suppressing health checks where you have evaluated they will 

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

988 issue is not worthwhile. 

989 

990 .. seealso:: 

991 

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

993 """ 

994 return self._suppress_health_check 

995 

996 @property 

997 def deadline(self): 

998 """ 

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

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

1001 is disabled entirely. 

1002 

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

1004 avoid flakiness due to timing variability. 

1005 

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

1007 ``None`` instead. 

1008 """ 

1009 return self._deadline 

1010 

1011 @property 

1012 def print_blob(self): 

1013 """ 

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

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

1016 

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

1018 """ 

1019 return self._print_blob 

1020 

1021 @property 

1022 def backend(self): 

1023 """ 

1024 .. warning:: 

1025 

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

1027 

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

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

1030 backends. 

1031 """ 

1032 return self._backend 

1033 

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

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

1036 

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

1038 """ 

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

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

1041 _test: Any = test 

1042 

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

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

1045 if not callable(_test): 

1046 raise InvalidArgument( 

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

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

1049 ) 

1050 if inspect.isclass(test): 

1051 from hypothesis.stateful import RuleBasedStateMachine 

1052 

1053 if issubclass(_test, RuleBasedStateMachine): 

1054 attr_name = "_hypothesis_internal_settings_applied" 

1055 if getattr(test, attr_name, False): 

1056 raise InvalidArgument( 

1057 "Applying the @settings decorator twice would " 

1058 "overwrite the first version; merge their arguments " 

1059 "instead." 

1060 ) 

1061 setattr(test, attr_name, True) 

1062 _test.TestCase.settings = self 

1063 return test 

1064 else: 

1065 raise InvalidArgument( 

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

1067 "functions, or on subclasses of RuleBasedStateMachine." 

1068 ) 

1069 if hasattr(_test, "_hypothesis_internal_settings_applied"): 

1070 # Can't use _hypothesis_internal_use_settings as an indicator that 

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

1072 descr = get_pretty_function_description(test) 

1073 raise InvalidArgument( 

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

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

1076 f" This: {self!r}" 

1077 ) 

1078 

1079 _test._hypothesis_internal_use_settings = self 

1080 _test._hypothesis_internal_settings_applied = True 

1081 return test 

1082 

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

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

1085 raise AttributeError("settings objects are immutable") 

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

1087 

1088 def __repr__(self) -> str: 

1089 bits = sorted( 

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

1091 for name in all_settings 

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

1093 ) 

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

1095 

1096 def show_changed(self) -> str: 

1097 bits = [] 

1098 for name in all_settings: 

1099 value = getattr(self, name) 

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

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

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

1103 

1104 @staticmethod 

1105 def register_profile( 

1106 name: str, 

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

1108 **kwargs: Any, 

1109 ) -> None: 

1110 """ 

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

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

1113 |settings|. 

1114 

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

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

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

1118 and do not require reloading the profile. 

1119 

1120 Registered settings profiles can be retrieved later by name with 

1121 |settings.get_profile|. 

1122 """ 

1123 check_type(str, name, "name") 

1124 

1125 if ( 

1126 default_variable.value 

1127 and settings._current_profile 

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

1129 ): 

1130 note_deprecation( 

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

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

1133 "Register profiles at module level instead.", 

1134 since="2025-11-15", 

1135 has_codemod=False, 

1136 ) 

1137 

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

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

1140 # then optimize out the pointless intermediate settings object which 

1141 # would just forward everything to the parent. 

1142 settings._profiles[name] = ( 

1143 parent 

1144 if parent is not None and not kwargs 

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

1146 ) 

1147 if settings._current_profile == name: 

1148 settings.load_profile(name) 

1149 

1150 @staticmethod 

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

1152 """ 

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

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

1155 """ 

1156 check_type(str, name, "name") 

1157 try: 

1158 return settings._profiles[name] 

1159 except KeyError: 

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

1161 

1162 @staticmethod 

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

1164 """ 

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

1166 

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

1168 """ 

1169 check_type(str, name, "name") 

1170 settings._current_profile = name 

1171 default_variable.value = settings.get_profile(name) 

1172 

1173 @staticmethod 

1174 def get_current_profile_name() -> str: 

1175 """ 

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

1177 

1178 .. code-block:: python 

1179 

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

1181 >>> settings.get_current_profile_name() 

1182 'myprofile' 

1183 """ 

1184 assert settings._current_profile is not None 

1185 return settings._current_profile 

1186 

1187 

1188@contextlib.contextmanager 

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

1190 with default_variable.with_value(s): 

1191 yield s 

1192 

1193 

1194def note_deprecation( 

1195 message: str, *, since: str, has_codemod: bool, stacklevel: int = 0 

1196) -> None: 

1197 if since != "RELEASEDAY": 

1198 date = datetime.date.fromisoformat(since) 

1199 assert datetime.date(2021, 1, 1) <= date 

1200 if has_codemod: 

1201 message += ( 

1202 "\n The `hypothesis codemod` command-line tool can automatically " 

1203 "refactor your code to fix this warning." 

1204 ) 

1205 warnings.warn(HypothesisDeprecationWarning(message), stacklevel=2 + stacklevel) 

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}