-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unittest.TestCase.assertWarns raises RuntimeEror if sys.modules changes size #73806
Comments
If any of the objects in sys.modules is a module-like object that performs some additional imports in its __getattribute__ (as appropriate) handler, the following simple unit test test case: import unittest
import warnings
class Case(unittest.TestCase):
def test_assertWarns(self):
with self.assertWarns(UserWarning):
warnings.warn('Some warning') fails with:
Traceback (most recent call last):
File "/tmp/example.py", line 9, in test_assertWarns
with self.assertWarns(UserWarning):
File "/usr/lib/python3.4/unittest/case.py", line 205, in __enter__
for v in sys.modules.values():
RuntimeError: dictionary changed size during iteration
The problem is in the iteration over sys.modules in unittest.case._AssertWarnsContext.__enter__() and accessing every module's __warningregistry__ attribute. On this access, the module-like objects may perform arbitrary actions including importing of further modules which extends sys.modules. Lines 226 to 227 in 16ea19f
The simple proposed fix with no foreseen side-effects is to wrap sys.modules.values() call as a tuple(). |
I am also running into this problem. I'm not 100%, but I'm pretty sure that looping over sys.modules and accessing __warningregistry__ on each module triggers one of my module's __getattr__ functions (PEP-562), which in turn uses setuptools entry points to import an arbitrary set of other modules. Bizarrely, however, I cannot reproduce on macOS, only Linux. Presumably there's something platform dependent about how the default unittest test runner orders my tests, and hence which modules have already been loaded by the time I call assertWarnsRegex. |
Confirmed this behavior on
|
Ran into the same issue using Python 3.6.8 [GCC 5.4.0 20160609] on Linux. The same code worked on Windows 10 with Python 3.7 32-bit and 64-bit. |
Changes applied to master, 3.8, and 3.7. Thanks! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: