summaryrefslogtreecommitdiff
path: root/Lib/test/test_dict.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_dict.py')
-rw-r--r--Lib/test/test_dict.py83
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