Skip to content

Commit

Permalink
bpo-29620: iterate over a copy of sys.modules (pythonGH-4800)
Browse files Browse the repository at this point in the history
unittest.TestCase.assertWarns no longer raises a RuntimeException
when accessing a module's ``__warningregistry__`` causes importation of a new
module, or when a new module is imported in another thread. 

Patch by Kernc.
  • Loading branch information
kernc authored and arun-mani-j committed Jul 21, 2020
1 parent 47de5a1 commit 6833ac7
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Lib/unittest/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ class _AssertWarnsContext(_AssertRaisesBaseContext):
def __enter__(self):
# The __warningregistry__'s need to be in a pristine state for tests
# to work properly.
for v in sys.modules.values():
for v in list(sys.modules.values()):
if getattr(v, '__warningregistry__', None):
v.__warningregistry__ = {}
self.warnings_manager = warnings.catch_warnings(record=True)
Expand Down
15 changes: 15 additions & 0 deletions Lib/unittest/test/test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import warnings
import weakref
import inspect
import types

from copy import deepcopy
from test import support
Expand Down Expand Up @@ -1350,6 +1351,20 @@ class MyWarn(Warning):
pass
self.assertRaises(TypeError, self.assertWarnsRegex, MyWarn, lambda: True)

def testAssertWarnsModifySysModules(self):
# bpo-29620: handle modified sys.modules during iteration
class Foo(types.ModuleType):
@property
def __warningregistry__(self):
sys.modules['@bar@'] = 'bar'

sys.modules['@foo@'] = Foo('foo')
try:
self.assertWarns(UserWarning, warnings.warn, 'expected')
finally:
del sys.modules['@foo@']
del sys.modules['@bar@']

def testAssertRaisesRegexMismatch(self):
def Stub():
raise Exception('Unexpected')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:func:`~unittest.TestCase.assertWarns` no longer raises a ``RuntimeException``
when accessing a module's ``__warningregistry__`` causes importation of a new
module, or when a new module is imported in another thread. Patch by Kernc.

0 comments on commit 6833ac7

Please sign in to comment.