Message288370
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
... # Ensure one of the imported modules is a module-like object as above
class Case(unittest.TestCase):
def test_assertWarns(self):
with self.assertWarns(UserWarning):
warnings.warn('Some warning')
fails with:
======================================================================
ERROR: test_assertWarns (example.Case)
----------------------------------------------------------------------
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.
https://github.com/python/cpython/blob/16ea19fc6653ee4ec1be7cd0206073962119ac08/Lib/unittest/case.py#L226-L227
The simple proposed fix with no foreseen side-effects is to wrap sys.modules.values() call as a tuple(). |
|
Date |
User |
Action |
Args |
2017-02-22 16:22:51 | kernc | set | recipients:
+ kernc |
2017-02-22 16:22:51 | kernc | set | messageid: <1487780571.93.0.503711972358.issue29620@psf.upfronthosting.co.za> |
2017-02-22 16:22:51 | kernc | link | issue29620 messages |
2017-02-22 16:22:51 | kernc | create | |
|