New submission from kernc:

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().

----------
components: Library (Lib)
messages: 288370
nosy: kernc
priority: normal
severity: normal
status: open
title: unittest.TestCase.assertWarns raises RuntimeEror if sys.modules changes 
size
type: behavior
versions: Python 3.4, Python 3.5, Python 3.6, Python 3.7

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue29620>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to