@@ -190,3 +190,115 @@ class AnnotationsInsteadOfElements(enum.Enum):
190
190
def test_suggests_elements_instead_of_annotations ():
191
191
with pytest .raises (InvalidArgument , match = "Cannot sample.*annotations.*dataclass" ):
192
192
st .sampled_from (AnnotationsInsteadOfElements ).example ()
193
+
194
+
195
+ class TestErrorNoteBehavior3819 :
196
+ elements = (st .booleans (), st .decimals (), st .integers (), st .text ())
197
+
198
+ @staticmethod
199
+ @given (st .data ())
200
+ def direct_without_error (data ):
201
+ data .draw (st .sampled_from ((st .floats (), st .binary ())))
202
+
203
+ @staticmethod
204
+ @given (st .data ())
205
+ def direct_with_non_type_error (data ):
206
+ data .draw (st .sampled_from (st .characters (), st .floats ()))
207
+ raise Exception ("Contains SearchStrategy, but no note addition!" )
208
+
209
+ @staticmethod
210
+ @given (st .data ())
211
+ def direct_with_type_error_without_substring (data ):
212
+ data .draw (st .sampled_from (st .booleans (), st .binary ()))
213
+ raise TypeError ("Substring not in message!" )
214
+
215
+ @staticmethod
216
+ @given (st .data ())
217
+ def direct_with_type_error_with_substring_but_not_all_strategies (data ):
218
+ data .draw (st .sampled_from (st .booleans (), False , True ))
219
+ raise TypeError ("Contains SearchStrategy, but no note addition!" )
220
+
221
+ @staticmethod
222
+ @given (st .data ())
223
+ def direct_all_strategies_with_type_error_with_substring (data ):
224
+ data .draw (st .sampled_from ((st .dates (), st .datetimes ())))
225
+ raise TypeError ("This message contains SearchStrategy as substring!" )
226
+
227
+ @staticmethod
228
+ @given (st .lists (st .sampled_from (elements )))
229
+ def indirect_without_error (_ ):
230
+ return
231
+
232
+ @staticmethod
233
+ @given (st .lists (st .sampled_from (elements )))
234
+ def indirect_with_non_type_error (_ ):
235
+ raise Exception ("Contains SearchStrategy, but no note addition!" )
236
+
237
+ @staticmethod
238
+ @given (st .lists (st .sampled_from (elements )))
239
+ def indirect_with_type_error_without_substring (_ ):
240
+ raise TypeError ("Substring not in message!" )
241
+
242
+ @staticmethod
243
+ @given (st .lists (st .sampled_from ((* elements , False , True ))))
244
+ def indirect_with_type_error_with_substring_but_not_all_strategies (_ ):
245
+ raise TypeError ("Contains SearchStrategy, but no note addition!" )
246
+
247
+ @staticmethod
248
+ @given (st .lists (st .sampled_from (elements ), min_size = 1 ))
249
+ def indirect_all_strategies_with_type_error_with_substring (objs ):
250
+ raise TypeError ("Contains SearchStrategy in message, trigger note!" )
251
+
252
+ @pytest .mark .parametrize (
253
+ ["func_to_call" , "exp_err_cls" , "should_exp_msg" ],
254
+ [
255
+ pytest .param (f .__func__ , err , msg_exp , id = f .__func__ .__name__ )
256
+ for f , err , msg_exp in [
257
+ (f , TypeError , True )
258
+ for f in (
259
+ direct_all_strategies_with_type_error_with_substring ,
260
+ indirect_all_strategies_with_type_error_with_substring ,
261
+ )
262
+ ]
263
+ + [
264
+ (f , TypeError , False )
265
+ for f in (
266
+ direct_with_type_error_without_substring ,
267
+ direct_with_type_error_with_substring_but_not_all_strategies ,
268
+ indirect_with_type_error_without_substring ,
269
+ indirect_with_type_error_with_substring_but_not_all_strategies ,
270
+ )
271
+ ]
272
+ + [
273
+ (f , Exception , False )
274
+ for f in (
275
+ direct_with_non_type_error ,
276
+ indirect_with_non_type_error ,
277
+ )
278
+ ]
279
+ + [
280
+ (f , None , False )
281
+ for f in (
282
+ direct_without_error ,
283
+ indirect_without_error ,
284
+ )
285
+ ]
286
+ ],
287
+ )
288
+ def test_error_appropriate_error_note_3819 (
289
+ self , func_to_call , exp_err_cls , should_exp_msg
290
+ ):
291
+ if exp_err_cls is None :
292
+ # Here we only care that no exception was raised, so nothing to assert.
293
+ func_to_call ()
294
+ else :
295
+ with pytest .raises (exp_err_cls ) as err_ctx :
296
+ func_to_call ()
297
+ notes = getattr (err_ctx .value , "__notes__" , [])
298
+ matching_messages = [
299
+ n
300
+ for n in notes
301
+ if n .startswith ("sample_from was given a collection of strategies" )
302
+ and n .endswith ("Was one_of intended?" )
303
+ ]
304
+ assert len (matching_messages ) == (1 if should_exp_msg else 0 )
0 commit comments