@@ -116,6 +116,9 @@ def _formatwarnmsg(msg):
116
116
msg .filename , msg .lineno , line = msg .line )
117
117
return _formatwarnmsg_impl (msg )
118
118
119
+ def _registrycleared (registry ):
120
+ """Hook that notifies when a module warning registry is cleared."""
121
+
119
122
def filterwarnings (action , message = "" , category = Warning , module = "" , lineno = 0 ,
120
123
append = False ):
121
124
"""Insert an entry into the list of warnings filters (at the front).
@@ -328,6 +331,7 @@ def warn_explicit(message, category, filename, lineno,
328
331
if registry is None :
329
332
registry = {}
330
333
if registry .get ('version' , 0 ) != _filters_version :
334
+ _registrycleared (registry )
331
335
registry .clear ()
332
336
registry ['version' ] = _filters_version
333
337
if isinstance (message , Warning ):
@@ -438,6 +442,7 @@ def __init__(self, *, record=False, module=None):
438
442
self ._record = record
439
443
self ._module = sys .modules ['warnings' ] if module is None else module
440
444
self ._entered = False
445
+ self ._old_registries = []
441
446
442
447
def __repr__ (self ):
443
448
args = []
@@ -454,7 +459,9 @@ def __enter__(self):
454
459
self ._entered = True
455
460
self ._filters = self ._module .filters
456
461
self ._module .filters = self ._filters [:]
457
- self ._module ._filters_mutated ()
462
+ self ._orig_registrycleared = self ._module ._registrycleared
463
+ self ._module ._registrycleared = self ._registrycleared
464
+ self ._filters_version = self ._module ._filters_mutated ()
458
465
self ._showwarning = self ._module .showwarning
459
466
self ._showwarnmsg_impl = self ._module ._showwarnmsg_impl
460
467
if self ._record :
@@ -471,10 +478,17 @@ def __exit__(self, *exc_info):
471
478
if not self ._entered :
472
479
raise RuntimeError ("Cannot exit %r without entering first" % self )
473
480
self ._module .filters = self ._filters
474
- self ._module ._filters_mutated ()
481
+ self ._module ._registrycleared = self ._orig_registrycleared
482
+ self ._module ._set_filters_version (self ._filters_version )
483
+ for registry , registry_copy in self ._old_registries :
484
+ registry .clear ()
485
+ registry .update (registry_copy )
475
486
self ._module .showwarning = self ._showwarning
476
487
self ._module ._showwarnmsg_impl = self ._showwarnmsg_impl
477
488
489
+ def _registrycleared (self , registry ):
490
+ self ._old_registries .append ((registry , registry .copy ()))
491
+
478
492
479
493
# Private utility function called by _PyErr_WarnUnawaitedCoroutine
480
494
def _warn_unawaited_coroutine (coro ):
@@ -509,7 +523,8 @@ def extract():
509
523
# If either if the compiled regexs are None, match anything.
510
524
try :
511
525
from _warnings import (filters , _defaultaction , _onceregistry ,
512
- warn , warn_explicit , _filters_mutated )
526
+ warn , warn_explicit , _filters_mutated ,
527
+ _set_filters_version )
513
528
defaultaction = _defaultaction
514
529
onceregistry = _onceregistry
515
530
_warnings_defaults = True
@@ -522,7 +537,12 @@ def extract():
522
537
523
538
def _filters_mutated ():
524
539
global _filters_version
540
+ old_filters_version = _filters_version
525
541
_filters_version += 1
542
+ return old_filters_version
543
+
544
+ def _set_filters_version (filters_version ):
545
+ _filters_version = filters_version
526
546
527
547
_warnings_defaults = False
528
548
0 commit comments