@@ -281,6 +281,11 @@ def __init__(
281
281
self .expected_warning = expected_warning_tup
282
282
self .match_expr = match_expr
283
283
284
+ def matches (self , warning ) -> bool :
285
+ return issubclass (warning .category , self .expected_warning ) and (
286
+ self .match_expr is None or re .search (self .match_expr , str (warning .message ))
287
+ )
288
+
284
289
def __exit__ (
285
290
self ,
286
291
exc_type : Optional [Type [BaseException ]],
@@ -291,56 +296,39 @@ def __exit__(
291
296
292
297
__tracebackhide__ = True
293
298
294
- def found_str ():
295
- return pformat ([record .message for record in self ], indent = 2 )
299
+ if self .expected_warning is None :
300
+ # nothing to do in this deprecated case, see WARNS_NONE_ARG above
301
+ return
296
302
297
- def re_emit () -> None :
298
- for r in self :
299
- if matches ( r ):
300
- continue
303
+ if not ( exc_type is None and exc_val is None and exc_tb is None ) :
304
+ # We currently ignore missing warnings if an exception is active.
305
+ # TODO: fix this, because it means things are surprisingly order-sensitive.
306
+ return
301
307
302
- assert issubclass (r .message .__class__ , Warning )
308
+ def found_str ():
309
+ return pformat ([record .message for record in self ], indent = 2 )
303
310
304
- warnings .warn_explicit (
305
- str (r .message ),
306
- r .message .__class__ ,
307
- r .filename ,
308
- r .lineno ,
309
- module = r .__module__ ,
310
- source = r .source ,
311
+ try :
312
+ if not any (issubclass (w .category , self .expected_warning ) for w in self ):
313
+ fail (
314
+ f"DID NOT WARN. No warnings of type { self .expected_warning } were emitted.\n "
315
+ f" Emitted warnings: { found_str ()} ."
311
316
)
312
-
313
- def matches (warning ) -> bool :
314
- if self .expected_warning is not None :
315
- if issubclass (warning .category , self .expected_warning ):
316
- if self .match_expr is not None :
317
- if re .compile (self .match_expr ).search (str (warning .message )):
318
- return True
319
- return False
320
- return True
321
- return False
322
-
323
- # only check if we're not currently handling an exception
324
- if exc_type is None and exc_val is None and exc_tb is None :
325
- if self .expected_warning is not None :
326
- if not any (issubclass (r .category , self .expected_warning ) for r in self ):
327
- __tracebackhide__ = True
328
- fail (
329
- f"DID NOT WARN. No warnings of type { self .expected_warning } were emitted.\n "
330
- f"The list of emitted warnings is: { found_str ()} ."
317
+ elif not any (self .matches (w ) for w in self ):
318
+ fail (
319
+ f"DID NOT WARN. No warnings of type { self .expected_warning } matching the regex were emitted.\n "
320
+ f" Regex: { self .match_expr } \n "
321
+ f" Emitted warnings: { found_str ()} ."
322
+ )
323
+ finally :
324
+ # Whether or not any warnings matched, we want to re-emit all unmatched warnings.
325
+ for w in self :
326
+ if not self .matches (w ):
327
+ warnings .warn_explicit (
328
+ str (w .message ),
329
+ w .message .__class__ ,
330
+ w .filename ,
331
+ w .lineno ,
332
+ module = w .__module__ ,
333
+ source = w .source ,
331
334
)
332
- elif self .match_expr is not None :
333
- for r in self :
334
- if issubclass (r .category , self .expected_warning ):
335
- if re .compile (self .match_expr ).search (str (r .message )):
336
- re_emit ()
337
- break
338
- else :
339
- fail (
340
- f"""\
341
- DID NOT WARN. No warnings of type { self .expected_warning } matching the regex were emitted.
342
- Regex: { self .match_expr }
343
- Emitted warnings: { found_str ()} """
344
- )
345
- else :
346
- re_emit ()
0 commit comments