Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/hypothesis/errors.py: 63%
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
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
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/.
11from collections.abc import Mapping
12from datetime import timedelta
13from typing import TYPE_CHECKING, Any, Literal
15from hypothesis.internal.compat import ExceptionGroup
17if TYPE_CHECKING:
18 from hypothesis.internal.conjecture.choice import ChoiceConstraintsT
19else:
20 ChoiceConstraintsT = Mapping
23class HypothesisException(Exception):
24 """Generic parent class for exceptions thrown by Hypothesis."""
27class _Trimmable(HypothesisException):
28 """Hypothesis can trim these tracebacks even if they're raised internally."""
31class UnsatisfiedAssumption(HypothesisException):
32 """An internal error raised by assume.
34 If you're seeing this error something has gone wrong.
35 """
37 def __init__(self, reason: str | None = None) -> None:
38 self.reason = reason
41class NoSuchExample(HypothesisException):
42 """The condition we have been asked to satisfy appears to be always false.
44 This does not guarantee that no example exists, only that we were
45 unable to find one.
46 """
48 def __init__(self, condition_string: str, extra: str = "") -> None:
49 super().__init__(f"No examples found of condition {condition_string}{extra}")
52class Unsatisfiable(_Trimmable):
53 """We ran out of time or examples before we could find enough examples
54 which satisfy the assumptions of this hypothesis.
56 This could be because the function is too slow. If so, try upping
57 the timeout. It could also be because the function is using assume
58 in a way that is too hard to satisfy. If so, try writing a custom
59 strategy or using a better starting point (e.g if you are requiring
60 a list has unique values you could instead filter out all duplicate
61 values from the list)
62 """
65class ChoiceTooLarge(HypothesisException):
66 """An internal error raised by choice_from_index."""
69class Flaky(_Trimmable):
70 """
71 Base class for indeterministic failures. Usually one of the more
72 specific subclasses (|FlakyFailure| or |FlakyStrategyDefinition|) is raised.
74 .. seealso::
76 See also the :doc:`flaky failures tutorial </tutorial/flaky>`.
77 """
80class FlakyReplay(Flaky):
81 """Internal error raised by the conjecture engine if flaky failures are
82 detected during replay.
84 Carries information allowing the runner to reconstruct the flakiness as
85 a FlakyFailure exception group for final presentation.
86 """
88 def __init__(self, reason, interesting_origins=None):
89 super().__init__(reason)
90 self.reason = reason
91 self._interesting_origins = interesting_origins
94def _render_constraints(show: Mapping[str, object], other: Mapping[str, object]) -> str:
95 assert show.keys() == other.keys()
96 return ", ".join(
97 f"{k}={'...' if v == other[k] else repr(v)}" for k, v in show.items()
98 )
101class FlakyStrategyDefinition(Flaky):
102 """
103 This function appears to cause inconsistent data generation.
105 Common causes for this problem are:
106 1. The strategy depends on external state. e.g. it uses an external
107 random number generator. Try to make a version that passes all the
108 relevant state in from Hypothesis.
110 .. seealso::
112 See also the :doc:`flaky failures tutorial </tutorial/flaky>`.
113 """
115 _BASE_MESSAGE = (
116 "Inconsistent data generation! Data generation behaved differently "
117 "between test cases. Is your data generation depending on external "
118 "state?"
119 )
121 @classmethod
122 def with_detail(cls, detail: str) -> "FlakyStrategyDefinition":
123 return cls(f"{cls._BASE_MESSAGE}\n\n{detail}")
125 @classmethod
126 def from_mismatch(
127 cls,
128 expected_type: str,
129 expected_constraints: ChoiceConstraintsT,
130 actual_type: str,
131 actual_constraints: ChoiceConstraintsT,
132 ) -> "FlakyStrategyDefinition":
133 if actual_type != expected_type:
134 detail = (
135 "The second test case drew a different type of value than the first.\n"
136 f" first: {expected_type}\n"
137 f" second: {actual_type}\n"
138 )
139 else:
140 detail = (
141 f"The second test case drew type {actual_type} with different constraints "
142 "than the first.\n"
143 f" first: {_render_constraints(expected_constraints, actual_constraints)}\n"
144 f" second: {_render_constraints(actual_constraints, expected_constraints)}\n"
145 )
146 return cls.with_detail(detail)
149class _WrappedBaseException(Exception):
150 """Used internally for wrapping BaseExceptions as components of FlakyFailure."""
153class FlakyFailure(ExceptionGroup, Flaky):
154 """
155 This function appears to fail non-deterministically: We have seen it
156 fail when passed this example at least once, but a subsequent invocation
157 did not fail, or caused a distinct error.
159 Common causes for this problem are:
160 1. The function depends on external state. e.g. it uses an external
161 random number generator. Try to make a version that passes all the
162 relevant state in from Hypothesis.
163 2. The function is suffering from too much recursion and its failure
164 depends sensitively on where it's been called from.
165 3. The function is timing sensitive and can fail or pass depending on
166 how long it takes. Try breaking it up into smaller functions which
167 don't do that and testing those instead.
169 .. seealso::
171 See also the :doc:`flaky failures tutorial </tutorial/flaky>`.
172 """
174 def __new__(cls, msg, group):
175 # The Exception mixin forces this an ExceptionGroup (only accepting
176 # Exceptions, not BaseException). Usually BaseException is raised
177 # directly and will hence not be part of a FlakyFailure, but I'm not
178 # sure this assumption holds everywhere. So wrap any BaseExceptions.
179 group = list(group)
180 for i, exc in enumerate(group):
181 if not isinstance(exc, Exception):
182 err = _WrappedBaseException()
183 err.__cause__ = err.__context__ = exc
184 group[i] = err
185 return ExceptionGroup.__new__(cls, msg, group)
187 # defining `derive` is required for `split` to return an instance of FlakyFailure
188 # instead of ExceptionGroup. See https://github.com/python/cpython/issues/119287
189 # and https://docs.python.org/3/library/exceptions.html#BaseExceptionGroup.derive
190 def derive(self, excs):
191 return type(self)(self.message, excs)
194class FlakyBackendFailure(FlakyFailure):
195 """
196 A failure was reported by an |alternative backend|,
197 but this failure did not reproduce when replayed under the Hypothesis backend.
199 When an alternative backend reports a failure, Hypothesis first replays it
200 under the standard Hypothesis backend to check for flakiness. If the failure
201 does not reproduce, Hypothesis raises this exception.
202 """
205class InvalidArgument(_Trimmable, TypeError):
206 """Used to indicate that the arguments to a Hypothesis function were in
207 some manner incorrect."""
210class ResolutionFailed(InvalidArgument):
211 """Hypothesis had to resolve a type to a strategy, but this failed.
213 Type inference is best-effort, so this only happens when an
214 annotation exists but could not be resolved for a required argument
215 to the target of ``builds()``, or where the user passed ``...``.
216 """
219class InvalidState(HypothesisException):
220 """The system is not in a state where you were allowed to do that."""
223class InvalidDefinition(_Trimmable, TypeError):
224 """Used to indicate that a class definition was not well put together and
225 has something wrong with it."""
228class HypothesisWarning(HypothesisException, Warning):
229 """A generic warning issued by Hypothesis."""
232class FailedHealthCheck(_Trimmable):
233 """Raised when a test fails a health check. See |HealthCheck|."""
236class NonInteractiveExampleWarning(HypothesisWarning):
237 """
238 Emitted when |.example| is used outside of interactive use.
240 |.example| is intended for exploratory and interactive work, not to be run as
241 part of a test suite.
242 """
245class HypothesisDeprecationWarning(HypothesisWarning, FutureWarning):
246 """A deprecation warning issued by Hypothesis.
248 Actually inherits from FutureWarning, because DeprecationWarning is
249 hidden by the default warnings filter.
251 You can configure the :mod:`python:warnings` module to handle these
252 warnings differently to others, either turning them into errors or
253 suppressing them entirely. Obviously we would prefer the former!
254 """
257class HypothesisSideeffectWarning(HypothesisWarning):
258 """A warning issued by Hypothesis when it sees actions that are
259 discouraged at import or initialization time because they are
260 slow or have user-visible side effects.
261 """
264class Frozen(HypothesisException):
265 """Raised when a mutation method has been called on a ConjectureData object
266 after freeze() has been called."""
269def __getattr__(name: str) -> Any:
270 if name == "MultipleFailures":
271 from hypothesis.internal.compat import BaseExceptionGroup
272 from hypothesis.utils.deprecation import note_deprecation
274 note_deprecation(
275 "MultipleFailures is deprecated; use the builtin `BaseExceptionGroup` type "
276 "instead, or `exceptiongroup.BaseExceptionGroup` before Python 3.11",
277 since="2022-08-02",
278 has_codemod=False, # This would be a great PR though!
279 stacklevel=1,
280 )
281 return BaseExceptionGroup
283 raise AttributeError(f"Module 'hypothesis.errors' has no attribute {name}")
286class DeadlineExceeded(_Trimmable):
287 """
288 Raised when an input takes too long to run, relative to the |settings.deadline|
289 setting.
290 """
292 def __init__(self, runtime: timedelta, deadline: timedelta) -> None:
293 super().__init__(
294 f"Test took {runtime.total_seconds() * 1000:.2f}ms, which exceeds "
295 f"the deadline of {deadline.total_seconds() * 1000:.2f}ms. If you "
296 "expect test cases to take this long, you can use @settings(deadline=...) "
297 "to either set a higher deadline, or to disable it with deadline=None."
298 )
299 self.runtime = runtime
300 self.deadline = deadline
302 def __reduce__(
303 self,
304 ) -> tuple[type["DeadlineExceeded"], tuple[timedelta, timedelta]]:
305 return (type(self), (self.runtime, self.deadline))
308class StopTest(BaseException):
309 """Raised when a test should stop running and return control to
310 the Hypothesis engine, which should then continue normally.
311 """
313 def __init__(self, testcounter: int) -> None:
314 super().__init__(repr(testcounter))
315 self.testcounter = testcounter
318class DidNotReproduce(HypothesisException):
319 pass
322class Found(HypothesisException):
323 """Signal that the example matches condition. Internal use only."""
326class RewindRecursive(Exception):
327 """Signal that the type inference should be rewound due to recursive types. Internal use only."""
329 def __init__(self, target: object) -> None:
330 self.target = target
333class SmallSearchSpaceWarning(HypothesisWarning):
334 """Indicates that an inferred strategy does not span the search space
335 in a meaningful way, for example by only creating default instances."""
338CannotProceedScopeT = Literal["verified", "exhausted", "discard_test_case", "other"]
339_valid_cannot_proceed_scopes = CannotProceedScopeT.__args__ # type: ignore
342class BackendCannotProceed(HypothesisException):
343 """
344 Raised by alternative backends when a |PrimitiveProvider| cannot proceed.
345 This is expected to occur inside one of the ``.draw_*()`` methods, or for
346 symbolic execution perhaps in |PrimitiveProvider.realize|.
348 The optional ``scope`` argument can enable smarter integration:
350 verified:
351 Do not request further test cases from this backend. We *may*
352 generate more test cases with other backends; if one fails then
353 Hypothesis will report unsound verification in the backend too.
355 exhausted:
356 Do not request further test cases from this backend; finish testing
357 with test cases generated with the default backend. Common if e.g.
358 native code blocks symbolic reasoning very early.
360 discard_test_case:
361 This particular test case could not be converted to concrete values;
362 skip any further processing and continue with another test case from
363 this backend.
364 """
366 def __init__(self, scope: CannotProceedScopeT = "other", /) -> None:
367 if scope not in _valid_cannot_proceed_scopes:
368 raise InvalidArgument(
369 f"Got scope={scope}, but expected one of "
370 f"{_valid_cannot_proceed_scopes!r}"
371 )
372 self.scope = scope