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

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

303 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, IntEnum, unique 

24from typing import ( 

25 TYPE_CHECKING, 

26 Any, 

27 ClassVar, 

28 Optional, 

29 TypeVar, 

30 Union, 

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 

65class Verbosity(IntEnum): 

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

67 

68 quiet = 0 

69 """ 

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

71 """ 

72 

73 normal = 1 

74 """ 

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

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

77 """ 

78 

79 verbose = 2 

80 """ 

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

82 will print each example as it tries it, as well as any notes made with |note| 

83 for every example. Hypothesis will also print shrinking attempts. 

84 """ 

85 

86 debug = 3 

87 """ 

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

89 don't want this. 

90 """ 

91 

92 def __repr__(self) -> str: 

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

94 

95 

96@unique 

97class Phase(IntEnum): 

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

99 

100 explicit = 0 

101 """ 

102 Controls whether explicit examples are run. 

103 """ 

104 

105 reuse = 1 

106 """ 

107 Controls whether previous examples will be reused. 

108 """ 

109 

110 generate = 2 

111 """ 

112 Controls whether new examples will be generated. 

113 """ 

114 

115 target = 3 

116 """ 

117 Controls whether examples will be mutated for targeting. 

118 """ 

119 

120 shrink = 4 

121 """ 

122 Controls whether examples will be shrunk. 

123 """ 

124 

125 explain = 5 

126 """ 

127 Controls whether Hypothesis attempts to explain test failures. 

128 

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

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

131 """ 

132 

133 def __repr__(self) -> str: 

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

135 

136 

137class HealthCheckMeta(EnumMeta): 

138 def __iter__(self): 

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

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

141 

142 

143@unique 

144class HealthCheck(Enum, metaclass=HealthCheckMeta): 

145 """ 

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

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

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

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

150 will raise a corresponding health check. 

151 

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

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

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

155 

156 With the exception of |HealthCheck.function_scoped_fixture| and 

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

158 problems, not correctness errors. 

159 

160 Disabling health checks 

161 ----------------------- 

162 

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

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

165 

166 .. seealso:: 

167 

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

169 

170 Correctness health checks 

171 ------------------------- 

172 

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

174 problems. 

175 

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

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

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

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

180 ensure you have considered this case. 

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

182 been executed multiple times with multiple distinct executors. 

183 

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

185 suppressing them may result in an unsound test. 

186 """ 

187 

188 def __repr__(self) -> str: 

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

190 

191 @classmethod 

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

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

194 note_deprecation( 

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

196 since="2023-04-16", 

197 has_codemod=True, 

198 stacklevel=1, 

199 ) 

200 return list(HealthCheck) 

201 

202 data_too_large = 1 

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

204 

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

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

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

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

209 this health check. 

210 """ 

211 

212 filter_too_much = 2 

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

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

215 internal reasons.""" 

216 

217 too_slow = 3 

218 """ 

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

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

221 can result in very slow tests overall. 

222 """ 

223 

224 return_value = 5 

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

226 

227 large_base_example = 7 

228 """ 

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

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

231 shrink failing inputs. 

232 """ 

233 

234 not_a_test_method = 8 

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

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

237 

238 function_scoped_fixture = 9 

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

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

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

242 you want. 

243 

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

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

246 typically using an appropriate context manager. 

247 

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

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

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

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

252 

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

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

255 

256 differing_executors = 10 

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

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

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

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

261 for things to go wrong. 

262 

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

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

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

266 specified on leaf subclasses.""" 

267 

268 nested_given = 11 

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

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

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

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

273 |@given|. 

274 

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

276 quadratic behavior and cannot easily reexpress the inner function with 

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

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

279 |@given|. Setting it on the inner 

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

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

282 |@given| except the innermost one. 

283 """ 

284 

285 

286class duration(datetime.timedelta): 

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

288 

289 def __repr__(self) -> str: 

290 ms = self.total_seconds() * 1000 

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

292 

293 

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

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

296_CI_VARS = { 

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

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

299 "__TOX_ENVIRONMENT_VARIABLE_ORIGINAL_CI": None, 

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

301 "bamboo.buildKey": None, # Bamboo 

302 "BUILDKITE": "true", # Buildkite 

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

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

305 "CODEBUILD_BUILD_ID": None, # CodeBuild 

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

307 "GITLAB_CI": None, # GitLab CI 

308 "HEROKU_TEST_RUN_ID": None, # Heroku CI 

309 "TEAMCITY_VERSION": None, # TeamCity 

310} 

311 

312 

313def is_in_ci() -> bool: 

314 return any( 

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

316 for key, value in _CI_VARS.items() 

317 ) 

318 

319 

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

321 

322 

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

324 if value not in choices: 

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

326 raise InvalidArgument(msg) 

327 return value 

328 

329 

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

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

332 if max_examples < 1: 

333 raise InvalidArgument( 

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

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

336 ) 

337 return max_examples 

338 

339 

340def _validate_database( 

341 database: Optional["ExampleDatabase"], 

342) -> Optional["ExampleDatabase"]: 

343 from hypothesis.database import ExampleDatabase 

344 

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

346 return database 

347 raise InvalidArgument( 

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

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

350 "hypothesis.database" 

351 ) 

352 

353 

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

355 phases = tuple(phases) 

356 for phase in phases: 

357 if not isinstance(phase, Phase): 

358 raise InvalidArgument(f"{phase!r} is not a valid phase") 

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

360 

361 

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

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

364 if stateful_step_count < 1: 

365 raise InvalidArgument( 

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

367 ) 

368 return stateful_step_count 

369 

370 

371def _validate_suppress_health_check(suppressions): 

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

373 for health_check in suppressions: 

374 if not isinstance(health_check, HealthCheck): 

375 raise InvalidArgument( 

376 f"Non-HealthCheck value {health_check!r} of type {type(health_check).__name__} " 

377 "is invalid in suppress_health_check." 

378 ) 

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

380 note_deprecation( 

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

382 since="2023-03-15", 

383 has_codemod=False, 

384 stacklevel=2, 

385 ) 

386 return suppressions 

387 

388 

389def _validate_deadline( 

390 x: Union[int, float, datetime.timedelta, None], 

391) -> Optional[duration]: 

392 if x is None: 

393 return x 

394 invalid_deadline_error = InvalidArgument( 

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

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

397 "per-test-case deadline." 

398 ) 

399 if isinstance(x, (int, float)): 

400 if isinstance(x, bool): 

401 raise invalid_deadline_error 

402 try: 

403 x = duration(milliseconds=x) 

404 except OverflowError: 

405 raise InvalidArgument( 

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

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

408 ) from None 

409 if isinstance(x, datetime.timedelta): 

410 if x <= datetime.timedelta(0): 

411 raise InvalidArgument( 

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

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

414 ) 

415 return duration(seconds=x.total_seconds()) 

416 raise invalid_deadline_error 

417 

418 

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

420 if backend not in AVAILABLE_PROVIDERS: 

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

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

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

424 raise InvalidArgument( 

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

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

427 ) 

428 return backend 

429 

430 

431class settingsMeta(type): 

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

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

434 

435 @property 

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

437 v = default_variable.value 

438 if v is not None: 

439 return v 

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

441 assert settings._current_profile is not None 

442 settings.load_profile(settings._current_profile) 

443 assert default_variable.value is not None 

444 return default_variable.value 

445 

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

447 if name == "default": 

448 raise AttributeError( 

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

450 "consider using settings.load_profile instead." 

451 ) 

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

453 raise AttributeError( 

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

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

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

457 "to decorate your test instead." 

458 ) 

459 super().__setattr__(name, value) 

460 

461 def __repr__(cls): 

462 return "hypothesis.settings" 

463 

464 

465class settings(metaclass=settingsMeta): 

466 """ 

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

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

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

470 |~settings.report_multiple_bugs|, |~settings.suppress_health_check|, 

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

472 

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

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

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

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

477 

478 Attribute inheritance 

479 --------------------- 

480 

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

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

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

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

485 from the currently active settings profile instead. 

486 

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

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

489 currently active settings profile. 

490 

491 A settings object is immutable once created. Changes made from activating a new 

492 settings profile with |settings.load_profile| will be reflected in 

493 settings objects created after the profile was made active, but not in existing 

494 settings objects. 

495 

496 .. _builtin-profiles: 

497 

498 Built-in profiles 

499 ----------------- 

500 

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

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

503 

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

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

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

507 

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

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

510 for |settings.max_examples|). 

511 

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

513 

514 .. code-block:: python 

515 

516 default = settings.register_profile( 

517 "default", 

518 max_examples=100, 

519 derandomize=False, 

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

521 verbosity=Verbosity.normal, 

522 phases=tuple(Phase), 

523 stateful_step_count=50, 

524 report_multiple_bugs=True, 

525 suppress_health_check=(), 

526 deadline=duration(milliseconds=200), 

527 print_blob=False, 

528 backend="hypothesis", 

529 ) 

530 

531 ci = settings.register_profile( 

532 "ci", 

533 parent=default, 

534 derandomize=True, 

535 deadline=None, 

536 database=None, 

537 print_blob=True, 

538 suppress_health_check=[HealthCheck.too_slow], 

539 ) 

540 

541 You can configure either of the built-in profiles with |settings.register_profile|: 

542 

543 .. code-block:: python 

544 

545 # run more examples in CI 

546 settings.register_profile( 

547 "ci", 

548 settings.get_profile("ci"), 

549 max_examples=1000, 

550 ) 

551 """ 

552 

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

554 _current_profile: ClassVar[Optional[str]] = None 

555 

556 def __init__( 

557 self, 

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

559 *, 

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

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

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

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

564 max_examples: int = not_set, # type: ignore 

565 derandomize: bool = not_set, # type: ignore 

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

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

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

569 stateful_step_count: int = not_set, # type: ignore 

570 report_multiple_bugs: bool = not_set, # type: ignore 

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

572 deadline: Union[int, float, datetime.timedelta, None] = not_set, # type: ignore 

573 print_blob: bool = not_set, # type: ignore 

574 backend: str = not_set, # type: ignore 

575 ) -> None: 

576 self._in_definition = True 

577 

578 if parent is not None: 

579 check_type(settings, parent, "parent") 

580 if derandomize not in (not_set, False): 

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

582 raise InvalidArgument( 

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

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

585 ) 

586 database = None 

587 

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

589 # the parent (or default settings object) otherwise 

590 self._fallback = parent or settings.default 

591 self._max_examples = ( 

592 self._fallback.max_examples # type: ignore 

593 if max_examples is not_set # type: ignore 

594 else _validate_max_examples(max_examples) 

595 ) 

596 self._derandomize = ( 

597 self._fallback.derandomize # type: ignore 

598 if derandomize is not_set # type: ignore 

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

600 ) 

601 if database is not not_set: # type: ignore 

602 database = _validate_database(database) 

603 self._database = database 

604 self._cached_database = None 

605 self._verbosity = ( 

606 self._fallback.verbosity # type: ignore 

607 if verbosity is not_set # type: ignore 

608 else _validate_choices("verbosity", verbosity, choices=tuple(Verbosity)) 

609 ) 

610 self._phases = ( 

611 self._fallback.phases # type: ignore 

612 if phases is not_set # type: ignore 

613 else _validate_phases(phases) 

614 ) 

615 self._stateful_step_count = ( 

616 self._fallback.stateful_step_count # type: ignore 

617 if stateful_step_count is not_set # type: ignore 

618 else _validate_stateful_step_count(stateful_step_count) 

619 ) 

620 self._report_multiple_bugs = ( 

621 self._fallback.report_multiple_bugs # type: ignore 

622 if report_multiple_bugs is not_set # type: ignore 

623 else _validate_choices( 

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

625 ) 

626 ) 

627 self._suppress_health_check = ( 

628 self._fallback.suppress_health_check # type: ignore 

629 if suppress_health_check is not_set # type: ignore 

630 else _validate_suppress_health_check(suppress_health_check) 

631 ) 

632 self._deadline = ( 

633 self._fallback.deadline # type: ignore 

634 if deadline is not_set # type: ignore 

635 else _validate_deadline(deadline) 

636 ) 

637 self._print_blob = ( 

638 self._fallback.print_blob # type: ignore 

639 if print_blob is not_set # type: ignore 

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

641 ) 

642 self._backend = ( 

643 self._fallback.backend # type: ignore 

644 if backend is not_set # type: ignore 

645 else _validate_backend(backend) 

646 ) 

647 

648 self._in_definition = False 

649 

650 @property 

651 def max_examples(self): 

652 """ 

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

654 counter-example, Hypothesis will stop looking. 

655 

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

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

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

659 prevent the test case from completing successfully. 

660 

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

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

663 running time against the chance of missing a bug. 

664 

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

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

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

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

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

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

671 shines when given minutes or hours to run. 

672 

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

674 """ 

675 return self._max_examples 

676 

677 @property 

678 def derandomize(self): 

679 """ 

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

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

682 update Hypothesis, Python, or the test function. 

683 

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

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

686 settings profiles - for example running 

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

688 nightly testing run. 

689 

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

691 """ 

692 return self._derandomize 

693 

694 @property 

695 def database(self): 

696 """ 

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

698 and load previous examples from. 

699 

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

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

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

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

704 

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

706 

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

708 classes, and how to define custom database classes. 

709 """ 

710 from hypothesis.database import _db_for_path 

711 

712 # settings.database has two conflicting requirements: 

713 # * The default settings should respect changes to set_hypothesis_home_dir 

714 # in-between accesses 

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

716 # 

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

718 # which always recomputes dynamically. 

719 if self._fallback is None: 

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

721 # we should recompute the database dynamically 

722 assert self._database is not_set 

723 return _db_for_path(not_set) 

724 

725 # otherwise, we cache the database 

726 if self._cached_database is None: 

727 self._cached_database = ( 

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

729 ) 

730 return self._cached_database 

731 

732 @property 

733 def verbosity(self): 

734 """ 

735 Control the verbosity level of Hypothesis messages. 

736 

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

738 up the verbosity setting. 

739 

740 .. code-block:: pycon 

741 

742 >>> from hypothesis import settings, Verbosity 

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

744 >>> @given(lists(integers())) 

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

746 ... def f(x): 

747 ... assert not any(x) 

748 ... f() 

749 Trying example: [] 

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

751 Shrunk example to [-1198601713] 

752 Shrunk example to [-128] 

753 Shrunk example to [32] 

754 Shrunk example to [1] 

755 [1] 

756 

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

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

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

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

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

762 

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

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

765 to see verbose output as tests run. 

766 """ 

767 return self._verbosity 

768 

769 @property 

770 def phases(self): 

771 """ 

772 Control which phases should be run. 

773 

774 Hypothesis divides tests into logically distinct phases. 

775 

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

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

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

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

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

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

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

783 Requires |Phase.shrink|. 

784 

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

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

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

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

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

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

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

792 temptation to guess <20>`. 

793 

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

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

796 -- which can vary freely without changing the result 

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

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

799 

800 .. code-block:: python 

801 

802 test_x_divided_by_y( 

803 x=0, # or any other generated value 

804 y=0, 

805 ) 

806 

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

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

809 simpler failing example) exists. 

810 

811 

812 The phases setting provides you with fine grained control over which of 

813 these run, with each phase corresponding to a value on the |Phase| enum. 

814 

815 The phases argument accepts a collection with any subset of these. e.g. 

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

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

818 while ``settings(phases=[Phase.explicit])`` will only run the explicit 

819 examples. 

820 """ 

821 

822 return self._phases 

823 

824 @property 

825 def stateful_step_count(self): 

826 """ 

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

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

829 

830 Note that this setting is effectively multiplicative with max_examples, 

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

832 

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

834 """ 

835 return self._stateful_step_count 

836 

837 @property 

838 def report_multiple_bugs(self): 

839 """ 

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

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

842 but replacing the exceptions can occasionally clash with debuggers. 

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

844 

845 The default value is ``True``. 

846 """ 

847 return self._report_multiple_bugs 

848 

849 @property 

850 def suppress_health_check(self): 

851 """ 

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

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

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

855 

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

857 encourage suppressing health checks where you have evaluated they will 

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

859 issue is not worthwhile. 

860 

861 .. seealso:: 

862 

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

864 """ 

865 return self._suppress_health_check 

866 

867 @property 

868 def deadline(self): 

869 """ 

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

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

872 is disabled entirely. 

873 

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

875 avoid flakiness due to timing variability. 

876 

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

878 ``None`` instead. 

879 """ 

880 return self._deadline 

881 

882 @property 

883 def print_blob(self): 

884 """ 

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

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

887 

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

889 """ 

890 return self._print_blob 

891 

892 @property 

893 def backend(self): 

894 """ 

895 .. warning:: 

896 

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

898 

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

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

901 backends. 

902 """ 

903 return self._backend 

904 

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

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

907 

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

909 """ 

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

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

912 _test: Any = test 

913 

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

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

916 if not callable(_test): 

917 raise InvalidArgument( 

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

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

920 ) 

921 if inspect.isclass(test): 

922 from hypothesis.stateful import RuleBasedStateMachine 

923 

924 if issubclass(_test, RuleBasedStateMachine): 

925 attr_name = "_hypothesis_internal_settings_applied" 

926 if getattr(test, attr_name, False): 

927 raise InvalidArgument( 

928 "Applying the @settings decorator twice would " 

929 "overwrite the first version; merge their arguments " 

930 "instead." 

931 ) 

932 setattr(test, attr_name, True) 

933 _test.TestCase.settings = self 

934 return test 

935 else: 

936 raise InvalidArgument( 

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

938 "functions, or on subclasses of RuleBasedStateMachine." 

939 ) 

940 if hasattr(_test, "_hypothesis_internal_settings_applied"): 

941 # Can't use _hypothesis_internal_use_settings as an indicator that 

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

943 descr = get_pretty_function_description(test) 

944 raise InvalidArgument( 

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

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

947 f" This: {self!r}" 

948 ) 

949 

950 _test._hypothesis_internal_use_settings = self 

951 _test._hypothesis_internal_settings_applied = True 

952 return test 

953 

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

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

956 raise AttributeError("settings objects are immutable") 

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

958 

959 def __repr__(self) -> str: 

960 bits = sorted( 

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

962 for name in all_settings 

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

964 ) 

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

966 

967 def show_changed(self) -> str: 

968 bits = [] 

969 for name in all_settings: 

970 value = getattr(self, name) 

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

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

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

974 

975 @staticmethod 

976 def register_profile( 

977 name: str, 

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

979 **kwargs: Any, 

980 ) -> None: 

981 """ 

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

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

984 |settings|. 

985 

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

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

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

989 and do not require reloading the profile. 

990 

991 Registered settings profiles can be retrieved later by name with 

992 |settings.get_profile|. 

993 """ 

994 check_type(str, name, "name") 

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

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

997 # then optimize out the pointless intermediate settings object which 

998 # would just forward everything to the parent. 

999 settings._profiles[name] = ( 

1000 parent 

1001 if parent is not None and not kwargs 

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

1003 ) 

1004 if settings._current_profile == name: 

1005 settings.load_profile(name) 

1006 

1007 @staticmethod 

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

1009 """ 

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

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

1012 """ 

1013 check_type(str, name, "name") 

1014 try: 

1015 return settings._profiles[name] 

1016 except KeyError: 

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

1018 

1019 @staticmethod 

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

1021 """ 

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

1023 

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

1025 """ 

1026 check_type(str, name, "name") 

1027 settings._current_profile = name 

1028 default_variable.value = settings.get_profile(name) 

1029 

1030 @staticmethod 

1031 def get_current_profile_name() -> str: 

1032 """ 

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

1034 

1035 .. code-block:: python 

1036 

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

1038 >>> settings.get_current_profile_name() 

1039 'myprofile' 

1040 """ 

1041 assert settings._current_profile is not None 

1042 return settings._current_profile 

1043 

1044 

1045@contextlib.contextmanager 

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

1047 with default_variable.with_value(s): 

1048 yield s 

1049 

1050 

1051def note_deprecation( 

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

1053) -> None: 

1054 if since != "RELEASEDAY": 

1055 date = datetime.date.fromisoformat(since) 

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

1057 if has_codemod: 

1058 message += ( 

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

1060 "refactor your code to fix this warning." 

1061 ) 

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

1063 

1064 

1065default = settings( 

1066 max_examples=100, 

1067 derandomize=False, 

1068 database=not_set, # type: ignore 

1069 verbosity=Verbosity.normal, 

1070 phases=tuple(Phase), 

1071 stateful_step_count=50, 

1072 report_multiple_bugs=True, 

1073 suppress_health_check=(), 

1074 deadline=duration(milliseconds=200), 

1075 print_blob=False, 

1076 backend="hypothesis", 

1077) 

1078settings.register_profile("default", default) 

1079settings.load_profile("default") 

1080 

1081assert settings.default is not None 

1082 

1083CI = settings( 

1084 derandomize=True, 

1085 deadline=None, 

1086 database=None, 

1087 print_blob=True, 

1088 suppress_health_check=[HealthCheck.too_slow], 

1089) 

1090 

1091settings.register_profile("ci", CI) 

1092 

1093 

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

1095 settings.load_profile("ci") 

1096 

1097assert settings.default is not None 

1098 

1099 

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

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

1102# not the other. 

1103assert set(all_settings) == { 

1104 p.name 

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

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

1107}