bpo-30441: Fix bug when modifying os.environ while iterating over it (#2409)

This commit is contained in:
Osvaldo Santana Neto 2017-07-01 14:34:45 -03:00 committed by Serhiy Storchaka
parent 85f643023f
commit 8a8d28501f
4 changed files with 29 additions and 1 deletions

View File

@ -697,7 +697,9 @@ class _Environ(MutableMapping):
raise KeyError(key) from None raise KeyError(key) from None
def __iter__(self): def __iter__(self):
for key in self._data: # list() from dict object is an atomic operation
keys = list(self._data)
for key in keys:
yield self.decodekey(key) yield self.decodekey(key)
def __len__(self): def __len__(self):

View File

@ -835,6 +835,30 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol):
self.assertIs(cm.exception.args[0], missing) self.assertIs(cm.exception.args[0], missing)
self.assertTrue(cm.exception.__suppress_context__) self.assertTrue(cm.exception.__suppress_context__)
def _test_environ_iteration(self, collection):
iterator = iter(collection)
new_key = "__new_key__"
next(iterator) # start iteration over os.environ.items
# add a new key in os.environ mapping
os.environ[new_key] = "test_environ_iteration"
try:
next(iterator) # force iteration over modified mapping
self.assertEqual(os.environ[new_key], "test_environ_iteration")
finally:
del os.environ[new_key]
def test_iter_error_when_changing_os_environ(self):
self._test_environ_iteration(os.environ)
def test_iter_error_when_changing_os_environ_items(self):
self._test_environ_iteration(os.environ.items())
def test_iter_error_when_changing_os_environ_values(self):
self._test_environ_iteration(os.environ.values())
class WalkTests(unittest.TestCase): class WalkTests(unittest.TestCase):
"""Tests for os.walk().""" """Tests for os.walk()."""

View File

@ -1088,6 +1088,7 @@ Fredrik Nehr
Tony Nelson Tony Nelson
Trent Nelson Trent Nelson
Andrew Nester Andrew Nester
Osvaldo Santana Neto
Chad Netzer Chad Netzer
Max Neunhöffer Max Neunhöffer
Anthon van der Neut Anthon van der Neut

View File

@ -0,0 +1 @@
Fix bug when modifying os.environ while iterating over it