diff options
Diffstat (limited to 'Lib/test/test_dict.py')
-rw-r--r-- | Lib/test/test_dict.py | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index d2740a3384..b43e20d055 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -2,7 +2,9 @@ import unittest from test import support import collections, random, string +import collections.abc import gc, weakref +import pickle class DictTest(unittest.TestCase): @@ -379,7 +381,7 @@ class DictTest(unittest.TestCase): x.fail = True self.assertRaises(Exc, d.pop, x) - def test_mutatingiteration(self): + def test_mutating_iteration(self): # changing dict size during iteration d = {} d[1] = 1 @@ -387,6 +389,33 @@ class DictTest(unittest.TestCase): for i in d: d[i+1] = 1 + def test_mutating_lookup(self): + # changing dict during a lookup + class NastyKey: + mutate_dict = None + + def __init__(self, value): + self.value = value + + def __hash__(self): + # hash collision! + return 1 + + def __eq__(self, other): + if NastyKey.mutate_dict: + mydict, key = NastyKey.mutate_dict + NastyKey.mutate_dict = None + del mydict[key] + return self.value == other.value + + key1 = NastyKey(1) + key2 = NastyKey(2) + d = {key1: 1} + NastyKey.mutate_dict = (d, key1) + with self.assertRaisesRegex(RuntimeError, + 'dictionary changed size during lookup'): + d[key2] = 2 + def test_repr(self): d = {} self.assertEqual(repr(d), '{}') @@ -776,6 +805,58 @@ class DictTest(unittest.TestCase): pass self._tracked(MyDict()) + def test_iterator_pickling(self): + data = {1:"a", 2:"b", 3:"c"} + it = iter(data) + d = pickle.dumps(it) + it = pickle.loads(d) + self.assertEqual(sorted(it), sorted(data)) + + it = pickle.loads(d) + try: + drop = next(it) + except StopIteration: + return + d = pickle.dumps(it) + it = pickle.loads(d) + del data[drop] + self.assertEqual(sorted(it), sorted(data)) + + def test_itemiterator_pickling(self): + data = {1:"a", 2:"b", 3:"c"} + # dictviews aren't picklable, only their iterators + itorg = iter(data.items()) + d = pickle.dumps(itorg) + it = pickle.loads(d) + # note that the type of type of the unpickled iterator + # is not necessarily the same as the original. It is + # merely an object supporting the iterator protocol, yielding + # the same objects as the original one. + # self.assertEqual(type(itorg), type(it)) + self.assertTrue(isinstance(it, collections.abc.Iterator)) + self.assertEqual(dict(it), data) + + it = pickle.loads(d) + drop = next(it) + d = pickle.dumps(it) + it = pickle.loads(d) + del data[drop[0]] + self.assertEqual(dict(it), data) + + def test_valuesiterator_pickling(self): + data = {1:"a", 2:"b", 3:"c"} + # data.values() isn't picklable, only its iterator + it = iter(data.values()) + d = pickle.dumps(it) + it = pickle.loads(d) + self.assertEqual(sorted(list(it)), sorted(list(data.values()))) + + it = pickle.loads(d) + drop = next(it) + d = pickle.dumps(it) + it = pickle.loads(d) + values = list(it) + [drop] + self.assertEqual(sorted(values), sorted(list(data.values()))) from test import mapping_tests |