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

344 statements  

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

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

3# 

4# Copyright the Hypothesis Authors. 

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

6# 

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

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

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

10 

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

12 

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

14this module can be modified. 

15""" 

16 

17import contextlib 

18import datetime 

19import inspect 

20import os 

21from collections.abc import Collection, Generator, Sequence 

22from enum import Enum, EnumMeta, unique 

23from functools import total_ordering 

24from typing import ( 

25 TYPE_CHECKING, 

26 Any, 

27 ClassVar, 

28 Optional, 

29 TypeVar, 

30) 

31 

32from hypothesis.errors import ( 

33 InvalidArgument, 

34) 

35from hypothesis.internal.conjecture.providers import AVAILABLE_PROVIDERS 

36from hypothesis.internal.reflection import get_pretty_function_description 

37from hypothesis.internal.validation import check_type, try_convert 

38from hypothesis.utils.conventions import not_set 

39from hypothesis.utils.deprecation import note_deprecation 

40from hypothesis.utils.dynamicvariables import DynamicVariable 

41 

42if TYPE_CHECKING: 

43 from hypothesis.database import ExampleDatabase 

44 

45__all__ = ["settings"] 

46 

47T = TypeVar("T") 

48all_settings: list[str] = [ 

49 "max_examples", 

50 "derandomize", 

51 "database", 

52 "verbosity", 

53 "phases", 

54 "stateful_step_count", 

55 "report_multiple_bugs", 

56 "suppress_health_check", 

57 "deadline", 

58 "print_blob", 

59 "backend", 

60] 

61 

62 

63@unique 

64@total_ordering 

65class Verbosity(Enum): 

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

67 

68 quiet = "quiet" 

69 """ 

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

71 """ 

72 

73 normal = "normal" 

74 """ 

75 Standard verbosity. Hypothesis will print the |minimal failing test case|, alongside 

76 any notes made with |note| (only for the minimal failing test case). 

77 """ 

78 

79 verbose = "verbose" 

80 """ 

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

82 will: 

83 

84 * Print each |test case| as it tries it 

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

86 * Print each shrinking attempt 

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

88 the simplest one 

89 """ 

90 

91 debug = "debug" 

92 """ 

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

94 don't want this. 

95 """ 

96 

97 @classmethod 

98 def _missing_(cls, value): 

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

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

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

102 if value in int_to_name: 

103 note_deprecation( 

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

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

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

107 since="2025-11-05", 

108 has_codemod=False, 

109 stacklevel=2, 

110 ) 

111 return cls(int_to_name[value]) 

112 return None 

113 

114 def __repr__(self) -> str: 

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

116 

117 @staticmethod 

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

119 return _VERBOSITY_INT_VALUES[value.name] 

120 

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

122 if isinstance(other, Verbosity): 

123 return super().__eq__(other) 

124 return Verbosity._int_value(self) == other 

125 

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

127 value1 = Verbosity._int_value(self) 

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

129 return value1 > value2 

130 

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

132 value1 = Verbosity._int_value(self) 

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

134 return value1 >= value2 

135 

136 

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

138_VERBOSITY_INT_VALUES = {"quiet": 0, "normal": 1, "verbose": 2, "debug": 3} 

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

140assert list(_VERBOSITY_INT_VALUES) == [verbosity.name for verbosity in Verbosity] 

141 

142 

143@unique 

144class Phase(Enum): 

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

146 

147 explicit = "explicit" 

148 """ 

149 Controls whether |explicit examples| are run. 

150 """ 

151 

152 reuse = "reuse" 

153 """ 

154 Controls whether previous test cases will be reused. 

155 """ 

156 

157 generate = "generate" 

158 """ 

159 Controls whether new test cases will be generated. 

160 """ 

161 

162 target = "target" 

163 """ 

164 Controls whether test cases will be mutated for targeting. 

165 """ 

166 

167 shrink = "shrink" 

168 """ 

169 Controls whether failing test cases will be shrunk. 

170 """ 

171 

172 explain = "explain" 

173 """ 

174 Controls whether Hypothesis attempts to explain test failures. 

175 

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

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

178 """ 

179 

180 @classmethod 

181 def _missing_(cls, value): 

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

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

184 int_to_name = { 

185 0: "explicit", 

186 1: "reuse", 

187 2: "generate", 

188 3: "target", 

189 4: "shrink", 

190 5: "explain", 

191 } 

192 if value in int_to_name: 

193 note_deprecation( 

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

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

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

197 since="2025-11-05", 

198 has_codemod=False, 

199 stacklevel=2, 

200 ) 

201 return cls(int_to_name[value]) 

202 return None 

203 

204 def __repr__(self) -> str: 

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

206 

207 

208class HealthCheckMeta(EnumMeta): 

209 def __iter__(self): 

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

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

212 

213 

214@unique 

215class HealthCheck(Enum, metaclass=HealthCheckMeta): 

216 """ 

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

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

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

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

221 will raise a corresponding health check. 

222 

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

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

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

226 

227 With the exception of |HealthCheck.function_scoped_fixture| and 

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

229 problems, not correctness errors. 

230 

231 Disabling health checks 

232 ----------------------- 

233 

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

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

236 

237 .. seealso:: 

238 

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

240 

241 Correctness health checks 

242 ------------------------- 

243 

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

245 problems. 

246 

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

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

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

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

251 ensure you have considered this case. 

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

253 been executed multiple times with multiple distinct executors. 

254 

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

256 suppressing them may result in an unsound test. 

257 """ 

258 

259 @classmethod 

260 def _missing_(cls, value): 

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

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

263 int_to_name = { 

264 1: "data_too_large", 

265 2: "filter_too_much", 

266 3: "too_slow", 

267 5: "return_value", 

268 7: "large_base_example", 

269 8: "not_a_test_method", 

270 9: "function_scoped_fixture", 

271 10: "differing_executors", 

272 11: "nested_given", 

273 } 

274 if value in int_to_name: 

275 note_deprecation( 

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

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

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

279 since="2025-11-05", 

280 has_codemod=False, 

281 stacklevel=2, 

282 ) 

283 return cls(int_to_name[value]) 

284 return None 

285 

286 def __repr__(self) -> str: 

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

288 

289 @classmethod 

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

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

292 note_deprecation( 

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

294 since="2023-04-16", 

295 has_codemod=True, 

296 stacklevel=1, 

297 ) 

298 return list(HealthCheck) 

299 

300 data_too_large = "data_too_large" 

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

302 

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

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

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

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

307 this health check. 

308 """ 

309 

310 filter_too_much = "filter_too_much" 

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

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

313 internal reasons.""" 

314 

315 too_slow = "too_slow" 

316 """ 

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

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

319 can result in very slow tests overall. 

320 """ 

321 

322 return_value = "return_value" 

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

324 

325 large_base_example = "large_base_example" 

326 """ 

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

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

329 shrink failing inputs. 

330 """ 

331 

332 not_a_test_method = "not_a_test_method" 

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

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

335 

336 function_scoped_fixture = "function_scoped_fixture" 

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

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

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

340 you want. 

341 

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

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

344 typically using an appropriate context manager. 

345 

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

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

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

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

350 

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

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

353 

354 differing_executors = "differing_executors" 

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

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

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

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

359 for things to go wrong. 

360 

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

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

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

364 specified on leaf subclasses.""" 

365 

366 nested_given = "nested_given" 

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

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

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

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

371 |@given|. 

372 

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

374 quadratic behavior and cannot easily reexpress the inner function with 

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

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

377 |@given|. Setting it on the inner 

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

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

380 |@given| except the innermost one. 

381 """ 

382 

383 

384class duration(datetime.timedelta): 

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

386 

387 def __repr__(self) -> str: 

388 ms = self.total_seconds() * 1000 

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

390 

391 

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

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

394_CI_VARS = { 

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

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

397 "__TOX_ENVIRONMENT_VARIABLE_ORIGINAL_CI": None, 

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

399 "bamboo.buildKey": None, # Bamboo 

400 "BUILDKITE": "true", # Buildkite 

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

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

403 "CODEBUILD_BUILD_ID": None, # CodeBuild 

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

405 "GITLAB_CI": None, # GitLab CI 

406 "HEROKU_TEST_RUN_ID": None, # Heroku CI 

407 "TEAMCITY_VERSION": None, # TeamCity 

408} 

409 

410 

411def is_in_ci() -> bool: 

412 return any( 

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

414 for key, value in _CI_VARS.items() 

415 ) 

416 

417 

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

419 

420 

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

422 if value not in choices: 

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

424 raise InvalidArgument(msg) 

425 return value 

426 

427 

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

429 try: 

430 return cls(value) 

431 except ValueError: 

432 raise InvalidArgument( 

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

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

435 ) from None 

436 

437 

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

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

440 if max_examples < 1: 

441 raise InvalidArgument( 

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

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

444 ) 

445 return max_examples 

446 

447 

448def _validate_database( 

449 database: Optional["ExampleDatabase"], 

450) -> Optional["ExampleDatabase"]: 

451 from hypothesis.database import ExampleDatabase 

452 

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

454 return database 

455 raise InvalidArgument( 

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

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

458 "hypothesis.database" 

459 ) 

460 

461 

462def _validate_phases(phases: Collection[Phase]) -> tuple[Phase, ...]: 

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

464 phases = tuple( 

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

466 ) 

467 # sort by definition order 

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

469 

470 

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

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

473 if stateful_step_count < 1: 

474 raise InvalidArgument( 

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

476 ) 

477 return stateful_step_count 

478 

479 

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

481 converted = try_convert(tuple, suppressions, "suppress_health_check") 

482 for health_check in converted: 

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

484 note_deprecation( 

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

486 since="2023-03-15", 

487 has_codemod=False, 

488 stacklevel=2, 

489 ) 

490 return tuple( 

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

492 for health_check in converted 

493 ) 

494 

495 

496def _validate_deadline( 

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

498) -> duration | None: 

499 if deadline is None: 

500 return deadline 

501 invalid_deadline_error = InvalidArgument( 

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

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

504 "per-test-case deadline." 

505 ) 

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

507 if isinstance(deadline, bool): 

508 raise invalid_deadline_error 

509 try: 

510 deadline = duration(milliseconds=deadline) 

511 except OverflowError: 

512 raise InvalidArgument( 

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

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

515 ) from None 

516 if isinstance(deadline, datetime.timedelta): 

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

518 raise InvalidArgument( 

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

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

521 ) 

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

523 raise invalid_deadline_error 

524 

525 

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

527 if backend not in AVAILABLE_PROVIDERS: 

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

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

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

531 raise InvalidArgument( 

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

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

534 ) 

535 return backend 

536 

537 

538class settingsMeta(type): 

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

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

541 

542 @property 

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

544 v = default_variable.value 

545 if v is not None: 

546 return v 

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

548 assert settings._current_profile is not None 

549 settings.load_profile(settings._current_profile) 

550 assert default_variable.value is not None 

551 return default_variable.value 

552 

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

554 if name == "default": 

555 raise AttributeError( 

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

557 "consider using settings.load_profile instead." 

558 ) 

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

560 raise AttributeError( 

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

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

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

564 "to decorate your test instead." 

565 ) 

566 super().__setattr__(name, value) 

567 

568 def __repr__(cls): 

569 return "hypothesis.settings" 

570 

571 

572class settings(metaclass=settingsMeta): 

573 """ 

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

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

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

577 |~settings.report_multiple_bugs|, |~settings.suppress_health_check|, 

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

579 

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

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

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

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

584 

585 Attribute inheritance 

586 --------------------- 

587 

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

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

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

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

592 from the current settings profile instead. 

593 

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

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

596 current settings profile. 

597 

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

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

600 but not in existing settings objects. 

601 

602 .. _builtin-profiles: 

603 

604 Built-in profiles 

605 ----------------- 

606 

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

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

609 

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

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

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

613 

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

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

616 for |settings.max_examples|). 

617 

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

619 

620 .. code-block:: python 

621 

622 default = settings.register_profile( 

623 "default", 

624 max_examples=100, 

625 derandomize=False, 

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

627 verbosity=Verbosity.normal, 

628 phases=tuple(Phase), 

629 stateful_step_count=50, 

630 report_multiple_bugs=True, 

631 suppress_health_check=(), 

632 deadline=duration(milliseconds=200), 

633 print_blob=False, 

634 backend="hypothesis", 

635 ) 

636 

637 ci = settings.register_profile( 

638 "ci", 

639 parent=default, 

640 derandomize=True, 

641 deadline=None, 

642 database=None, 

643 print_blob=True, 

644 suppress_health_check=[HealthCheck.too_slow], 

645 ) 

646 

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

648 

649 .. code-block:: python 

650 

651 # run more examples in CI 

652 settings.register_profile( 

653 "ci", 

654 settings.get_profile("ci"), 

655 max_examples=1000, 

656 ) 

657 """ 

658 

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

660 _current_profile: ClassVar[str | None] = None 

661 

662 def __init__( 

663 self, 

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

665 *, 

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

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

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

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

670 max_examples: int = not_set, # type: ignore 

671 derandomize: bool = not_set, # type: ignore 

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

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

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

675 stateful_step_count: int = not_set, # type: ignore 

676 report_multiple_bugs: bool = not_set, # type: ignore 

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

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

679 print_blob: bool = not_set, # type: ignore 

680 backend: str = not_set, # type: ignore 

681 ) -> None: 

682 self._in_definition = True 

683 

684 if parent is not None: 

685 check_type(settings, parent, "parent") 

686 if derandomize not in (not_set, False): 

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

688 raise InvalidArgument( 

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

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

691 ) 

692 database = None 

693 

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

695 # the parent (or default settings object) otherwise 

696 self._fallback = parent or settings.default 

697 self._max_examples = ( 

698 self._fallback.max_examples # type: ignore 

699 if max_examples is not_set # type: ignore 

700 else _validate_max_examples(max_examples) 

701 ) 

702 self._derandomize = ( 

703 self._fallback.derandomize # type: ignore 

704 if derandomize is not_set # type: ignore 

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

706 ) 

707 if database is not not_set: # type: ignore 

708 database = _validate_database(database) 

709 self._database: Any = database 

710 self._cached_database: ExampleDatabase | None = None 

711 self._verbosity = ( 

712 self._fallback.verbosity # type: ignore 

713 if verbosity is not_set # type: ignore 

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

715 ) 

716 self._phases = ( 

717 self._fallback.phases # type: ignore 

718 if phases is not_set # type: ignore 

719 else _validate_phases(phases) 

720 ) 

721 self._stateful_step_count = ( 

722 self._fallback.stateful_step_count # type: ignore 

723 if stateful_step_count is not_set # type: ignore 

724 else _validate_stateful_step_count(stateful_step_count) 

725 ) 

726 self._report_multiple_bugs = ( 

727 self._fallback.report_multiple_bugs # type: ignore 

728 if report_multiple_bugs is not_set # type: ignore 

729 else _validate_choices( 

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

731 ) 

732 ) 

733 self._suppress_health_check = ( 

734 self._fallback.suppress_health_check # type: ignore 

735 if suppress_health_check is not_set # type: ignore 

736 else _validate_suppress_health_check(suppress_health_check) 

737 ) 

738 self._deadline = ( 

739 self._fallback.deadline # type: ignore 

740 if deadline is not_set # type: ignore 

741 else _validate_deadline(deadline) 

742 ) 

743 self._print_blob = ( 

744 self._fallback.print_blob # type: ignore 

745 if print_blob is not_set # type: ignore 

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

747 ) 

748 self._backend = ( 

749 self._fallback.backend # type: ignore 

750 if backend is not_set # type: ignore 

751 else _validate_backend(backend) 

752 ) 

753 

754 self._in_definition = False 

755 

756 @property 

757 def max_examples(self) -> int: 

758 """ 

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

760 any failing test case, Hypothesis will stop looking. 

761 

762 .. note:: 

763 

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

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

766 documentation and codebase. 

767 

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

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

770 as "max test cases". 

771 

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

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

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

775 prevent the test case from completing successfully. 

776 

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

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

779 running time against the chance of missing a bug. 

780 

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

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

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

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

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

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

787 shines when given minutes or hours to run. 

788 

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

790 

791 .. note:: 

792 

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

794 interacts with other parts of Hypothesis. 

795 """ 

796 return self._max_examples 

797 

798 @property 

799 def derandomize(self) -> bool: 

800 """ 

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

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

803 update Hypothesis, Python, or the test function. 

804 

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

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

807 settings profiles - for example running 

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

809 nightly testing run. 

810 

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

812 """ 

813 return self._derandomize 

814 

815 @property 

816 def database(self) -> "ExampleDatabase | None": 

817 """ 

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

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

820 

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

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

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

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

825 

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

827 

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

829 classes, and how to define custom database classes. 

830 """ 

831 from hypothesis.database import _db_for_path 

832 

833 # settings.database has two conflicting requirements: 

834 # * The default settings should respect changes to set_hypothesis_home_dir 

835 # in-between accesses 

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

837 # 

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

839 # which always recomputes dynamically. 

840 if self._fallback is None: 

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

842 # we should recompute the database dynamically 

843 assert self._database is not_set 

844 return _db_for_path(not_set) 

845 

846 # otherwise, we cache the database 

847 if self._cached_database is None: 

848 self._cached_database = ( 

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

850 ) 

851 return self._cached_database 

852 

853 @property 

854 def verbosity(self) -> Verbosity: 

855 """ 

856 Control the verbosity level of Hypothesis messages. 

857 

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

859 up the verbosity setting. 

860 

861 .. code-block:: pycon 

862 

863 >>> from hypothesis import settings, Verbosity 

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

865 >>> @given(lists(integers())) 

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

867 ... def f(x): 

868 ... assert not any(x) 

869 ... f() 

870 Test case: [] 

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

872 Shrunk test case to [-1198601713] 

873 Shrunk test case to [-128] 

874 Shrunk test case to [32] 

875 Shrunk test case to [1] 

876 [1] 

877 

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

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

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

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

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

883 

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

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

886 example: 

887 

888 .. code-block:: python 

889 

890 # these three are equivalent 

891 settings(verbosity=Verbosity.verbose) 

892 settings(verbosity="verbose") 

893 

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

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

896 to see verbose output as tests run. 

897 """ 

898 return self._verbosity 

899 

900 @property 

901 def phases(self) -> Collection[Phase]: 

902 """ 

903 Control which phases should be run. 

904 

905 Hypothesis divides tests into logically distinct phases. 

906 

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

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

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

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

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

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

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

914 Requires |Phase.shrink|. 

915 

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

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

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

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

920 from |@example|. 

921 

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

923 string value. For example: 

924 

925 .. code-block:: python 

926 

927 # these two are equivalent 

928 settings(phases=[Phase.explicit]) 

929 settings(phases=["explicit"]) 

930 

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

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

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

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

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

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

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

938 temptation to guess <20>`. 

939 

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

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

942 -- which can vary freely without changing the result 

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

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

945 

946 .. code-block:: python 

947 

948 test_x_divided_by_y( 

949 x=0, # or any other generated value 

950 y=0, 

951 ) 

952 

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

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

955 simpler failing test case) exists. 

956 """ 

957 

958 return self._phases 

959 

960 @property 

961 def stateful_step_count(self) -> int: 

962 """ 

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

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

965 

966 Note that this setting is effectively multiplicative with max_examples, 

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

968 

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

970 """ 

971 return self._stateful_step_count 

972 

973 @property 

974 def report_multiple_bugs(self) -> bool: 

975 """ 

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

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

978 but replacing the exceptions can occasionally clash with debuggers. 

979 If disabled, only the exception with the smallest 

980 |minimal failing test case| is raised. 

981 

982 The default value is ``True``. 

983 """ 

984 return self._report_multiple_bugs 

985 

986 @property 

987 def suppress_health_check(self) -> Collection[HealthCheck]: 

988 """ 

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

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

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

992 

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

994 the corresponding string value. For example: 

995 

996 .. code-block:: python 

997 

998 # these two are equivalent 

999 settings(suppress_health_check=[HealthCheck.filter_too_much]) 

1000 settings(suppress_health_check=["filter_too_much"]) 

1001 

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

1003 encourage suppressing health checks where you have evaluated they will 

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

1005 issue is not worthwhile. 

1006 

1007 .. seealso:: 

1008 

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

1010 """ 

1011 return self._suppress_health_check 

1012 

1013 @property 

1014 def deadline(self) -> datetime.timedelta | None: 

1015 """ 

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

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

1018 is disabled entirely. 

1019 

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

1021 avoid flakiness due to timing variability. 

1022 

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

1024 ``None`` instead. 

1025 """ 

1026 return self._deadline 

1027 

1028 @property 

1029 def print_blob(self) -> bool: 

1030 """ 

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

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

1033 

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

1035 """ 

1036 return self._print_blob 

1037 

1038 @property 

1039 def backend(self) -> str: 

1040 """ 

1041 .. warning:: 

1042 

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

1044 

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

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

1047 backends. 

1048 """ 

1049 return self._backend 

1050 

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

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

1053 

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

1055 """ 

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

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

1058 _test: Any = test 

1059 

1060 if not callable(test): 

1061 raise InvalidArgument( 

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

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

1064 ) 

1065 if inspect.isclass(test): 

1066 from hypothesis.stateful import RuleBasedStateMachine 

1067 

1068 if issubclass(_test, RuleBasedStateMachine): 

1069 attr_name = "_hypothesis_internal_settings_applied" 

1070 if getattr(test, attr_name, False): 

1071 raise InvalidArgument( 

1072 "Applying the @settings decorator twice would " 

1073 "overwrite the first version; merge their arguments " 

1074 "instead." 

1075 ) 

1076 setattr(test, attr_name, True) 

1077 _test.TestCase.settings = self 

1078 return test 

1079 else: 

1080 raise InvalidArgument( 

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

1082 "functions, or on subclasses of RuleBasedStateMachine." 

1083 ) 

1084 if hasattr(_test, "_hypothesis_internal_settings_applied"): 

1085 # Can't use _hypothesis_internal_use_settings as an indicator that 

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

1087 descr = get_pretty_function_description(test) 

1088 raise InvalidArgument( 

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

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

1091 f" This: {self!r}" 

1092 ) 

1093 

1094 _test._hypothesis_internal_use_settings = self 

1095 _test._hypothesis_internal_settings_applied = True 

1096 return test 

1097 

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

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

1100 raise AttributeError("settings objects are immutable") 

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

1102 

1103 def __repr__(self) -> str: 

1104 bits = sorted( 

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

1106 for name in all_settings 

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

1108 ) 

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

1110 

1111 def show_changed(self) -> str: 

1112 bits = [] 

1113 for name in all_settings: 

1114 value = getattr(self, name) 

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

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

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

1118 

1119 @staticmethod 

1120 def register_profile( 

1121 name: str, 

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

1123 **kwargs: Any, 

1124 ) -> None: 

1125 """ 

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

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

1128 |settings|. 

1129 

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

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

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

1133 and do not require reloading the profile. 

1134 

1135 Registered settings profiles can be retrieved later by name with 

1136 |settings.get_profile|. 

1137 """ 

1138 check_type(str, name, "name") 

1139 

1140 if ( 

1141 default_variable.value 

1142 and settings._current_profile 

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

1144 ): 

1145 note_deprecation( 

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

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

1148 "Register profiles at module level instead.", 

1149 since="2025-11-15", 

1150 has_codemod=False, 

1151 ) 

1152 

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

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

1155 # then optimize out the pointless intermediate settings object which 

1156 # would just forward everything to the parent. 

1157 settings._profiles[name] = ( 

1158 parent 

1159 if parent is not None and not kwargs 

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

1161 ) 

1162 if settings._current_profile == name: 

1163 settings.load_profile(name) 

1164 

1165 @staticmethod 

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

1167 """ 

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

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

1170 """ 

1171 check_type(str, name, "name") 

1172 try: 

1173 return settings._profiles[name] 

1174 except KeyError: 

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

1176 

1177 @staticmethod 

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

1179 """ 

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

1181 

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

1183 """ 

1184 check_type(str, name, "name") 

1185 settings._current_profile = name 

1186 default_variable.value = settings.get_profile(name) 

1187 

1188 @staticmethod 

1189 def get_current_profile_name() -> str: 

1190 """ 

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

1192 

1193 .. code-block:: python 

1194 

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

1196 >>> settings.get_current_profile_name() 

1197 'myprofile' 

1198 """ 

1199 assert settings._current_profile is not None 

1200 return settings._current_profile 

1201 

1202 

1203@contextlib.contextmanager 

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

1205 with default_variable.with_value(s): 

1206 yield s 

1207 

1208 

1209default = settings( 

1210 max_examples=100, 

1211 derandomize=False, 

1212 database=not_set, # type: ignore 

1213 verbosity=Verbosity.normal, 

1214 phases=tuple(Phase), 

1215 stateful_step_count=50, 

1216 report_multiple_bugs=True, 

1217 suppress_health_check=(), 

1218 deadline=duration(milliseconds=200), 

1219 print_blob=False, 

1220 backend="hypothesis", 

1221) 

1222settings.register_profile("default", default) 

1223settings.load_profile("default") 

1224 

1225assert settings.default is not None 

1226 

1227CI = settings( 

1228 derandomize=True, 

1229 deadline=None, 

1230 database=None, 

1231 print_blob=True, 

1232 suppress_health_check=[HealthCheck.too_slow], 

1233) 

1234 

1235settings.register_profile("ci", CI) 

1236 

1237 

1238if is_in_ci(): 

1239 settings.load_profile("ci") 

1240 

1241assert settings.default is not None 

1242 

1243 

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

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

1246# not the other. 

1247assert set(all_settings) == { 

1248 p.name 

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

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

1251}