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

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

73 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 

11from datetime import timedelta 

12from typing import Any, Literal, Optional 

13 

14from hypothesis.internal.compat import ExceptionGroup 

15 

16 

17class HypothesisException(Exception): 

18 """Generic parent class for exceptions thrown by Hypothesis.""" 

19 

20 

21class _Trimmable(HypothesisException): 

22 """Hypothesis can trim these tracebacks even if they're raised internally.""" 

23 

24 

25class UnsatisfiedAssumption(HypothesisException): 

26 """An internal error raised by assume. 

27 

28 If you're seeing this error something has gone wrong. 

29 """ 

30 

31 def __init__(self, reason: Optional[str] = None) -> None: 

32 self.reason = reason 

33 

34 

35class NoSuchExample(HypothesisException): 

36 """The condition we have been asked to satisfy appears to be always false. 

37 

38 This does not guarantee that no example exists, only that we were 

39 unable to find one. 

40 """ 

41 

42 def __init__(self, condition_string: str, extra: str = "") -> None: 

43 super().__init__(f"No examples found of condition {condition_string}{extra}") 

44 

45 

46class Unsatisfiable(_Trimmable): 

47 """We ran out of time or examples before we could find enough examples 

48 which satisfy the assumptions of this hypothesis. 

49 

50 This could be because the function is too slow. If so, try upping 

51 the timeout. It could also be because the function is using assume 

52 in a way that is too hard to satisfy. If so, try writing a custom 

53 strategy or using a better starting point (e.g if you are requiring 

54 a list has unique values you could instead filter out all duplicate 

55 values from the list) 

56 """ 

57 

58 

59class ChoiceTooLarge(HypothesisException): 

60 """An internal error raised by choice_from_index.""" 

61 

62 

63class Flaky(_Trimmable): 

64 """Base class for indeterministic failures. Usually one of the more 

65 specific subclasses (FlakyFailure or FlakyStrategyDefinition) is raised.""" 

66 

67 

68class FlakyReplay(Flaky): 

69 """Internal error raised by the conjecture engine if flaky failures are 

70 detected during replay. 

71 

72 Carries information allowing the runner to reconstruct the flakiness as 

73 a FlakyFailure exception group for final presentation. 

74 """ 

75 

76 def __init__(self, reason, interesting_origins=None): 

77 super().__init__(reason) 

78 self.reason = reason 

79 self._interesting_origins = interesting_origins 

80 

81 

82class FlakyStrategyDefinition(Flaky): 

83 """This function appears to cause inconsistent data generation. 

84 

85 Common causes for this problem are: 

86 1. The strategy depends on external state. e.g. it uses an external 

87 random number generator. Try to make a version that passes all the 

88 relevant state in from Hypothesis. 

89 """ 

90 

91 

92class _WrappedBaseException(Exception): 

93 """Used internally for wrapping BaseExceptions as components of FlakyFailure.""" 

94 

95 

96class FlakyFailure(ExceptionGroup, Flaky): 

97 """This function appears to fail non-deterministically: We have seen it 

98 fail when passed this example at least once, but a subsequent invocation 

99 did not fail, or caused a distinct error. 

100 

101 Common causes for this problem are: 

102 1. The function depends on external state. e.g. it uses an external 

103 random number generator. Try to make a version that passes all the 

104 relevant state in from Hypothesis. 

105 2. The function is suffering from too much recursion and its failure 

106 depends sensitively on where it's been called from. 

107 3. The function is timing sensitive and can fail or pass depending on 

108 how long it takes. Try breaking it up into smaller functions which 

109 don't do that and testing those instead. 

110 """ 

111 

112 def __new__(cls, msg, group): 

113 # The Exception mixin forces this an ExceptionGroup (only accepting 

114 # Exceptions, not BaseException). Usually BaseException is raised 

115 # directly and will hence not be part of a FlakyFailure, but I'm not 

116 # sure this assumption holds everywhere. So wrap any BaseExceptions. 

117 group = list(group) 

118 for i, exc in enumerate(group): 

119 if not isinstance(exc, Exception): 

120 err = _WrappedBaseException() 

121 err.__cause__ = err.__context__ = exc 

122 group[i] = err 

123 return ExceptionGroup.__new__(cls, msg, group) 

124 

125 # defining `derive` is required for `split` to return an instance of FlakyFailure 

126 # instead of ExceptionGroup. See https://github.com/python/cpython/issues/119287 

127 # and https://docs.python.org/3/library/exceptions.html#BaseExceptionGroup.derive 

128 def derive(self, excs): 

129 return type(self)(self.message, excs) 

130 

131 

132class FlakyBackendFailure(FlakyFailure): 

133 """ 

134 A failure was reported by an :ref:`alternative backend <alternative-backends>`, 

135 but this failure did not reproduce when replayed under the Hypothesis backend. 

136 

137 When an alternative backend reports a failure, Hypothesis first replays it 

138 under the standard Hypothesis backend to check for flakiness. If the failure 

139 does not reproduce, Hypothesis raises this exception. 

140 """ 

141 

142 

143class InvalidArgument(_Trimmable, TypeError): 

144 """Used to indicate that the arguments to a Hypothesis function were in 

145 some manner incorrect.""" 

146 

147 

148class ResolutionFailed(InvalidArgument): 

149 """Hypothesis had to resolve a type to a strategy, but this failed. 

150 

151 Type inference is best-effort, so this only happens when an 

152 annotation exists but could not be resolved for a required argument 

153 to the target of ``builds()``, or where the user passed ``...``. 

154 """ 

155 

156 

157class InvalidState(HypothesisException): 

158 """The system is not in a state where you were allowed to do that.""" 

159 

160 

161class InvalidDefinition(_Trimmable, TypeError): 

162 """Used to indicate that a class definition was not well put together and 

163 has something wrong with it.""" 

164 

165 

166class HypothesisWarning(HypothesisException, Warning): 

167 """A generic warning issued by Hypothesis.""" 

168 

169 

170class FailedHealthCheck(_Trimmable): 

171 """Raised when a test fails a healthcheck.""" 

172 

173 

174class NonInteractiveExampleWarning(HypothesisWarning): 

175 """SearchStrategy.example() is designed for interactive use, 

176 but should never be used in the body of a test. 

177 """ 

178 

179 

180class HypothesisDeprecationWarning(HypothesisWarning, FutureWarning): 

181 """A deprecation warning issued by Hypothesis. 

182 

183 Actually inherits from FutureWarning, because DeprecationWarning is 

184 hidden by the default warnings filter. 

185 

186 You can configure the Python :mod:`python:warnings` to handle these 

187 warnings differently to others, either turning them into errors or 

188 suppressing them entirely. Obviously we would prefer the former! 

189 """ 

190 

191 

192class HypothesisSideeffectWarning(HypothesisWarning): 

193 """A warning issued by Hypothesis when it sees actions that are 

194 discouraged at import or initialization time because they are 

195 slow or have user-visible side effects. 

196 """ 

197 

198 

199class Frozen(HypothesisException): 

200 """Raised when a mutation method has been called on a ConjectureData object 

201 after freeze() has been called.""" 

202 

203 

204def __getattr__(name: str) -> Any: 

205 if name == "MultipleFailures": 

206 from hypothesis._settings import note_deprecation 

207 from hypothesis.internal.compat import BaseExceptionGroup 

208 

209 note_deprecation( 

210 "MultipleFailures is deprecated; use the builtin `BaseExceptionGroup` type " 

211 "instead, or `exceptiongroup.BaseExceptionGroup` before Python 3.11", 

212 since="2022-08-02", 

213 has_codemod=False, # This would be a great PR though! 

214 stacklevel=1, 

215 ) 

216 return BaseExceptionGroup 

217 

218 raise AttributeError(f"Module 'hypothesis.errors' has no attribute {name}") 

219 

220 

221class DeadlineExceeded(_Trimmable): 

222 """ 

223 Raised when an input takes too long to run, relative to the |settings.deadline| 

224 setting. 

225 """ 

226 

227 def __init__(self, runtime: timedelta, deadline: timedelta) -> None: 

228 super().__init__( 

229 f"Test took {runtime.total_seconds() * 1000:.2f}ms, which exceeds " 

230 f"the deadline of {deadline.total_seconds() * 1000:.2f}ms" 

231 ) 

232 self.runtime = runtime 

233 self.deadline = deadline 

234 

235 def __reduce__( 

236 self, 

237 ) -> tuple[type["DeadlineExceeded"], tuple[timedelta, timedelta]]: 

238 return (type(self), (self.runtime, self.deadline)) 

239 

240 

241class StopTest(BaseException): 

242 """Raised when a test should stop running and return control to 

243 the Hypothesis engine, which should then continue normally. 

244 """ 

245 

246 def __init__(self, testcounter: int) -> None: 

247 super().__init__(repr(testcounter)) 

248 self.testcounter = testcounter 

249 

250 

251class DidNotReproduce(HypothesisException): 

252 pass 

253 

254 

255class Found(HypothesisException): 

256 """Signal that the example matches condition. Internal use only.""" 

257 

258 

259class RewindRecursive(Exception): 

260 """Signal that the type inference should be rewound due to recursive types. Internal use only.""" 

261 

262 def __init__(self, target: object) -> None: 

263 self.target = target 

264 

265 

266class SmallSearchSpaceWarning(HypothesisWarning): 

267 """Indicates that an inferred strategy does not span the search space 

268 in a meaningful way, for example by only creating default instances.""" 

269 

270 

271CannotProceedScopeT = Literal["verified", "exhausted", "discard_test_case", "other"] 

272 

273 

274class BackendCannotProceed(HypothesisException): 

275 """ 

276 Raised by alternative backends when a |PrimitiveProvider| cannot proceed. 

277 This is expected to occur inside one of the ``.draw_*()`` methods, or for 

278 symbolic execution perhaps in |PrimitiveProvider.realize|. 

279 

280 The optional ``scope`` argument can enable smarter integration: 

281 

282 verified: 

283 Do not request further test cases from this backend. We *may* 

284 generate more test cases with other backends; if one fails then 

285 Hypothesis will report unsound verification in the backend too. 

286 

287 exhausted: 

288 Do not request further test cases from this backend; finish testing 

289 with test cases generated with the default backend. Common if e.g. 

290 native code blocks symbolic reasoning very early. 

291 

292 discard_test_case: 

293 This particular test case could not be converted to concrete values; 

294 skip any further processing and continue with another test case from 

295 this backend. 

296 """ 

297 

298 def __init__(self, scope: CannotProceedScopeT = "other", /) -> None: 

299 self.scope = scope