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

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

297 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 """Arguments for :attr:`~hypothesis.settings.suppress_health_check`. 

146 

147 Each member of this enum is a specific health check to suppress. 

148 """ 

149 

150 def __repr__(self) -> str: 

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

152 

153 @classmethod 

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

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

156 note_deprecation( 

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

158 since="2023-04-16", 

159 has_codemod=True, 

160 stacklevel=1, 

161 ) 

162 return list(HealthCheck) 

163 

164 data_too_large = 1 

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

166 

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

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

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

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

171 this health check. 

172 """ 

173 

174 filter_too_much = 2 

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

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

177 internal reasons.""" 

178 

179 too_slow = 3 

180 """Check for when your data generation is extremely slow and likely to hurt 

181 testing.""" 

182 

183 return_value = 5 

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

185 

186 large_base_example = 7 

187 """Checks if the natural example to shrink towards is very large.""" 

188 

189 not_a_test_method = 8 

190 """Deprecated; we always error if :func:`@given <hypothesis.given>` is applied 

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

192 

193 function_scoped_fixture = 9 

194 """Checks if :func:`@given <hypothesis.given>` has been applied to a test 

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

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

197 you want. 

198 

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

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

201 typically using an appropriate context manager. 

202 

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

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

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

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

207 

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

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

210 

211 differing_executors = 10 

212 """Checks if :func:`@given <hypothesis.given>` has been applied to a test 

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

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

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

216 for things to go wrong. 

217 

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

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

220 subclasses, or to refactor so that :func:`@given <hypothesis.given>` is 

221 specified on leaf subclasses.""" 

222 

223 nested_given = 11 

224 """Checks if :func:`@given <hypothesis.given>` is used inside another 

225 :func:`@given <hypothesis.given>`. This results in quadratic generation and 

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

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

228 :func:`@given <hypothesis.given>`. 

229 

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

231 quadratic behavior and cannot easily reexpress the inner function with 

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

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

234 :func:`@given <hypothesis.given>`. Setting it on the inner 

235 :func:`@given <hypothesis.given>` has no effect. If you have more than one 

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

237 :func:`@given <hypothesis.given>` except the innermost one. 

238 """ 

239 

240 

241class duration(datetime.timedelta): 

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

243 

244 def __repr__(self) -> str: 

245 ms = self.total_seconds() * 1000 

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

247 

248 

249def is_in_ci() -> bool: 

250 # GitHub Actions, Travis CI and AppVeyor have "CI" 

251 # Azure Pipelines has "TF_BUILD" 

252 return "CI" in os.environ or "TF_BUILD" in os.environ 

253 

254 

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

256 

257 

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

259 if value not in choices: 

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

261 raise InvalidArgument(msg) 

262 return value 

263 

264 

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

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

267 if max_examples < 1: 

268 raise InvalidArgument( 

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

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

271 ) 

272 return max_examples 

273 

274 

275def _validate_database( 

276 database: Optional["ExampleDatabase"], 

277) -> Optional["ExampleDatabase"]: 

278 from hypothesis.database import ExampleDatabase 

279 

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

281 return database 

282 raise InvalidArgument( 

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

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

285 "hypothesis.database" 

286 ) 

287 

288 

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

290 phases = tuple(phases) 

291 for phase in phases: 

292 if not isinstance(phase, Phase): 

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

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

295 

296 

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

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

299 if stateful_step_count < 1: 

300 raise InvalidArgument( 

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

302 ) 

303 return stateful_step_count 

304 

305 

306def _validate_suppress_health_check(suppressions): 

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

308 for health_check in suppressions: 

309 if not isinstance(health_check, HealthCheck): 

310 raise InvalidArgument( 

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

312 "is invalid in suppress_health_check." 

313 ) 

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

315 note_deprecation( 

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

317 since="2023-03-15", 

318 has_codemod=False, 

319 stacklevel=2, 

320 ) 

321 return suppressions 

322 

323 

324def _validate_deadline( 

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

326) -> Optional[duration]: 

327 if x is None: 

328 return x 

329 invalid_deadline_error = InvalidArgument( 

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

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

332 "per-test-case deadline." 

333 ) 

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

335 if isinstance(x, bool): 

336 raise invalid_deadline_error 

337 try: 

338 x = duration(milliseconds=x) 

339 except OverflowError: 

340 raise InvalidArgument( 

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

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

343 ) from None 

344 if isinstance(x, datetime.timedelta): 

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

346 raise InvalidArgument( 

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

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

349 ) 

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

351 raise invalid_deadline_error 

352 

353 

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

355 if backend not in AVAILABLE_PROVIDERS: 

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

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

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

359 raise InvalidArgument( 

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

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

362 ) 

363 return backend 

364 

365 

366class settingsMeta(type): 

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

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

369 

370 @property 

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

372 v = default_variable.value 

373 if v is not None: 

374 return v 

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

376 assert settings._current_profile is not None 

377 settings.load_profile(settings._current_profile) 

378 assert default_variable.value is not None 

379 return default_variable.value 

380 

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

382 if name == "default": 

383 raise AttributeError( 

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

385 "consider using settings.load_profile instead." 

386 ) 

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

388 raise AttributeError( 

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

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

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

392 "to decorate your test instead." 

393 ) 

394 super().__setattr__(name, value) 

395 

396 def __repr__(cls): 

397 return "hypothesis.settings" 

398 

399 

400class settings(metaclass=settingsMeta): 

401 """A settings object configures options including verbosity, runtime controls, 

402 persistence, determinism, and more. 

403 

404 Default values are picked up from the settings.default object and 

405 changes made there will be picked up in newly created settings. 

406 """ 

407 

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

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

410 

411 def __init__( 

412 self, 

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

414 *, 

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

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

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

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

419 max_examples: int = not_set, # type: ignore 

420 derandomize: bool = not_set, # type: ignore 

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

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

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

424 stateful_step_count: int = not_set, # type: ignore 

425 report_multiple_bugs: bool = not_set, # type: ignore 

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

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

428 print_blob: bool = not_set, # type: ignore 

429 backend: str = not_set, # type: ignore 

430 ) -> None: 

431 self._in_definition = True 

432 

433 if parent is not None: 

434 check_type(settings, parent, "parent") 

435 if derandomize not in (not_set, False): 

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

437 raise InvalidArgument( 

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

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

440 ) 

441 database = None 

442 

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

444 # the parent (or default settings object) otherwise 

445 self._fallback = parent or settings.default 

446 self._max_examples = ( 

447 self._fallback.max_examples # type: ignore 

448 if max_examples is not_set # type: ignore 

449 else _validate_max_examples(max_examples) 

450 ) 

451 self._derandomize = ( 

452 self._fallback.derandomize # type: ignore 

453 if derandomize is not_set # type: ignore 

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

455 ) 

456 if database is not not_set: # type: ignore 

457 database = _validate_database(database) 

458 self._database = database 

459 self._cached_database = None 

460 self._verbosity = ( 

461 self._fallback.verbosity # type: ignore 

462 if verbosity is not_set # type: ignore 

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

464 ) 

465 self._phases = ( 

466 self._fallback.phases # type: ignore 

467 if phases is not_set # type: ignore 

468 else _validate_phases(phases) 

469 ) 

470 self._stateful_step_count = ( 

471 self._fallback.stateful_step_count # type: ignore 

472 if stateful_step_count is not_set # type: ignore 

473 else _validate_stateful_step_count(stateful_step_count) 

474 ) 

475 self._report_multiple_bugs = ( 

476 self._fallback.report_multiple_bugs # type: ignore 

477 if report_multiple_bugs is not_set # type: ignore 

478 else _validate_choices( 

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

480 ) 

481 ) 

482 self._suppress_health_check = ( 

483 self._fallback.suppress_health_check # type: ignore 

484 if suppress_health_check is not_set # type: ignore 

485 else _validate_suppress_health_check(suppress_health_check) 

486 ) 

487 self._deadline = ( 

488 self._fallback.deadline # type: ignore 

489 if deadline is not_set 

490 else _validate_deadline(deadline) 

491 ) 

492 self._print_blob = ( 

493 self._fallback.print_blob # type: ignore 

494 if print_blob is not_set # type: ignore 

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

496 ) 

497 self._backend = ( 

498 self._fallback.backend # type: ignore 

499 if backend is not_set # type: ignore 

500 else _validate_backend(backend) 

501 ) 

502 

503 self._in_definition = False 

504 

505 @property 

506 def max_examples(self): 

507 """ 

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

509 counter-example, Hypothesis will stop looking. 

510 

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

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

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

514 prevent the test case from completing successfully. 

515 

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

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

518 running time against the chance of missing a bug. 

519 

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

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

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

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

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

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

526 shines when given minutes or hours to run. 

527 

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

529 """ 

530 return self._max_examples 

531 

532 @property 

533 def derandomize(self): 

534 """ 

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

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

537 update Hypothesis, Python, or the test function. 

538 

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

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

541 :ref:`separate settings profiles <settings_profiles>` - for example running 

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

543 nightly testing run. 

544 

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

546 """ 

547 return self._derandomize 

548 

549 @property 

550 def database(self): 

551 """ 

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

553 and load previous examples from. 

554 

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

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

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

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

559 

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

561 

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

563 classes, and how to define custom database classes. 

564 """ 

565 from hypothesis.database import _db_for_path 

566 

567 # settings.database has two conflicting requirements: 

568 # * The default settings should respect changes to set_hypothesis_home_dir 

569 # in-between accesses 

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

571 # 

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

573 # which always recomputes dynamically. 

574 if self._fallback is None: 

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

576 # we should recompute the database dynamically 

577 assert self._database is not_set 

578 return _db_for_path(not_set) 

579 

580 # otherwise, we cache the database 

581 if self._cached_database is None: 

582 self._cached_database = ( 

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

584 ) 

585 return self._cached_database 

586 

587 @property 

588 def verbosity(self): 

589 """ 

590 Control the verbosity level of Hypothesis messages. 

591 

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

593 up the verbosity setting. 

594 

595 .. code-block:: pycon 

596 

597 >>> from hypothesis import settings, Verbosity 

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

599 >>> @given(lists(integers())) 

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

601 ... def f(x): 

602 ... assert not any(x) 

603 ... f() 

604 Trying example: [] 

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

606 Shrunk example to [-1198601713] 

607 Shrunk example to [-32896] 

608 Shrunk example to [-128] 

609 Shrunk example to [32] 

610 Shrunk example to [3] 

611 Shrunk example to [1] 

612 [1] 

613 

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

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

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

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

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

619 

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

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

622 to see verbose output as tests run. 

623 """ 

624 return self._verbosity 

625 

626 @property 

627 def phases(self): 

628 """ 

629 Control which phases should be run. 

630 

631 Hypothesis divides tests into logically distinct phases. 

632 

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

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

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

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

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

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

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

640 Requires |Phase.shrink|. 

641 

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

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

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

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

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

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

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

649 temptation to guess <20>`. 

650 

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

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

653 -- which can vary freely without changing the result 

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

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

656 

657 .. code-block:: python 

658 

659 test_x_divided_by_y( 

660 x=0, # or any other generated value 

661 y=0, 

662 ) 

663 

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

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

666 simpler failing example) exists. 

667 

668 

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

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

671 

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

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

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

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

676 examples. 

677 """ 

678 

679 return self._phases 

680 

681 @property 

682 def stateful_step_count(self): 

683 """ 

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

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

686 

687 Note that this setting is effectively multiplicative with max_examples, 

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

689 

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

691 """ 

692 return self._stateful_step_count 

693 

694 @property 

695 def report_multiple_bugs(self): 

696 """ 

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

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

699 but replacing the exceptions can occasionally clash with debuggers. 

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

701 

702 The default value is ``True``. 

703 """ 

704 return self._report_multiple_bugs 

705 

706 @property 

707 def suppress_health_check(self): 

708 """ 

709 A list of |HealthCheck| items to disable. 

710 """ 

711 return self._suppress_health_check 

712 

713 @property 

714 def deadline(self): 

715 """ 

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

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

718 is disabled entirely. 

719 

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

721 avoid flakiness due to timing variability. 

722 

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

724 ``None`` instead. 

725 """ 

726 return self._deadline 

727 

728 @property 

729 def print_blob(self): 

730 """ 

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

732 can be used with :func:`@reproduce_failure <hypothesis.reproduce_failure>` 

733 to reproduce the failing example. 

734 

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

736 """ 

737 return self._print_blob 

738 

739 @property 

740 def backend(self): 

741 """ 

742 .. warning:: 

743 

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

745 

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

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

748 backends. 

749 """ 

750 return self._backend 

751 

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

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

754 

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

756 """ 

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

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

759 _test: Any = test 

760 

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

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

763 if not callable(_test): 

764 raise InvalidArgument( 

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

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

767 ) 

768 if inspect.isclass(test): 

769 from hypothesis.stateful import RuleBasedStateMachine 

770 

771 if issubclass(_test, RuleBasedStateMachine): 

772 attr_name = "_hypothesis_internal_settings_applied" 

773 if getattr(test, attr_name, False): 

774 raise InvalidArgument( 

775 "Applying the @settings decorator twice would " 

776 "overwrite the first version; merge their arguments " 

777 "instead." 

778 ) 

779 setattr(test, attr_name, True) 

780 _test.TestCase.settings = self 

781 return test # type: ignore 

782 else: 

783 raise InvalidArgument( 

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

785 "functions, or on subclasses of RuleBasedStateMachine." 

786 ) 

787 if hasattr(_test, "_hypothesis_internal_settings_applied"): 

788 # Can't use _hypothesis_internal_use_settings as an indicator that 

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

790 descr = get_pretty_function_description(test) 

791 raise InvalidArgument( 

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

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

794 f" This: {self!r}" 

795 ) 

796 

797 _test._hypothesis_internal_use_settings = self 

798 _test._hypothesis_internal_settings_applied = True 

799 return test 

800 

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

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

803 raise AttributeError("settings objects are immutable") 

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

805 

806 def __repr__(self) -> str: 

807 bits = sorted( 

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

809 for name in all_settings 

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

811 ) 

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

813 

814 def show_changed(self) -> str: 

815 bits = [] 

816 for name in all_settings: 

817 value = getattr(self, name) 

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

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

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

821 

822 @staticmethod 

823 def register_profile( 

824 name: str, 

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

826 **kwargs: Any, 

827 ) -> None: 

828 """Registers a collection of values to be used as a settings profile. 

829 

830 Settings profiles can be loaded by name - for example, you might 

831 create a 'fast' profile which runs fewer examples, keep the 'default' 

832 profile, and create a 'ci' profile that increases the number of 

833 examples and uses a different database to store failures. 

834 

835 The arguments to this method are exactly as for 

836 :class:`~hypothesis.settings`: optional ``parent`` settings, and 

837 keyword arguments for each setting that will be set differently to 

838 parent (or settings.default, if parent is None). 

839 

840 If you register a profile that has already been defined and that profile 

841 is the currently loaded profile, the new changes will take effect immediately, 

842 and do not require reloading the profile. 

843 """ 

844 check_type(str, name, "name") 

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

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

847 # then optimize out the pointless intermediate settings object which 

848 # would just forward everything to the parent. 

849 settings._profiles[name] = ( 

850 parent 

851 if parent is not None and not kwargs 

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

853 ) 

854 if settings._current_profile == name: 

855 settings.load_profile(name) 

856 

857 @staticmethod 

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

859 """Return the profile with the given name.""" 

860 check_type(str, name, "name") 

861 try: 

862 return settings._profiles[name] 

863 except KeyError: 

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

865 

866 @staticmethod 

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

868 """Loads in the settings defined in the profile provided. 

869 

870 If the profile does not exist, InvalidArgument will be raised. 

871 Any setting not defined in the profile will be the library 

872 defined default for that setting. 

873 """ 

874 check_type(str, name, "name") 

875 settings._current_profile = name 

876 default_variable.value = settings.get_profile(name) 

877 

878 

879@contextlib.contextmanager 

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

881 with default_variable.with_value(s): 

882 yield s 

883 

884 

885def note_deprecation( 

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

887) -> None: 

888 if since != "RELEASEDAY": 

889 date = datetime.date.fromisoformat(since) 

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

891 if has_codemod: 

892 message += ( 

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

894 "refactor your code to fix this warning." 

895 ) 

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

897 

898 

899default = settings( 

900 max_examples=100, 

901 derandomize=False, 

902 database=not_set, # type: ignore 

903 verbosity=Verbosity.normal, 

904 phases=tuple(Phase), 

905 stateful_step_count=50, 

906 report_multiple_bugs=True, 

907 suppress_health_check=(), 

908 deadline=duration(milliseconds=200), 

909 print_blob=False, 

910 backend="hypothesis", 

911) 

912settings.register_profile("default", default) 

913settings.load_profile("default") 

914 

915assert settings.default is not None 

916 

917CI = settings( 

918 derandomize=True, 

919 deadline=None, 

920 database=None, 

921 print_blob=True, 

922 suppress_health_check=[HealthCheck.too_slow], 

923) 

924 

925settings.register_profile("ci", CI) 

926 

927 

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

929 settings.load_profile("ci") 

930 

931assert settings.default is not None 

932 

933 

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

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

936# not the other. 

937assert set(all_settings) == { 

938 p.name 

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

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

941}