blob: cd238bc6773d557cc74f7f4bbcb0310bf5f4d143 [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001"""Unit tests for collections.py."""
2
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00003import unittest, doctest, operator
Eric Snow47db7172015-05-29 22:21:39 -06004from test.support import TESTFN, forget, unlink, import_fresh_module
5import contextlib
Raymond Hettinger2d32f632009-03-02 21:24:57 +00006import inspect
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Raymond Hettinger426e0522011-01-03 02:12:02 +00008from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger2d32f632009-03-02 21:24:57 +00009from test import mapping_tests
Georg Brandlc28e1fa2008-06-10 19:20:26 +000010import pickle, copy
Raymond Hettinger2d32f632009-03-02 21:24:57 +000011from random import randrange, shuffle
Raymond Hettinger499b2ee2009-05-27 01:53:46 +000012import keyword
13import re
R. David Murray378c0cf2010-02-24 01:46:21 +000014import sys
Yury Selivanov75445082015-05-11 22:57:16 -040015import types
Raymond Hettinger573b44c2015-05-22 16:56:32 -070016from collections import UserDict, UserString, UserList
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000017from collections import ChainMap
Raymond Hettinger32ea1652015-03-21 01:37:37 -070018from collections import deque
Yury Selivanove0104ae2015-05-14 12:19:16 -040019from collections.abc import Awaitable, Coroutine, AsyncIterator, AsyncIterable
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -040020from collections.abc import Hashable, Iterable, Iterator, Generator
Raymond Hettinger57d1a882011-02-23 00:46:28 +000021from collections.abc import Sized, Container, Callable
22from collections.abc import Set, MutableSet
23from collections.abc import Mapping, MutableMapping, KeysView, ItemsView
24from collections.abc import Sequence, MutableSequence
25from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000026
Raymond Hettinger499e1932011-02-23 07:56:53 +000027
Raymond Hettinger573b44c2015-05-22 16:56:32 -070028class TestUserObjects(unittest.TestCase):
29 def _superset_test(self, a, b):
30 self.assertGreaterEqual(
31 set(dir(a)),
32 set(dir(b)),
33 '{a} should have all the methods of {b}'.format(
34 a=a.__name__,
35 b=b.__name__,
36 ),
37 )
38 def test_str_protocol(self):
39 self._superset_test(UserString, str)
40
41 def test_list_protocol(self):
42 self._superset_test(UserList, list)
43
44 def test_dict_protocol(self):
45 self._superset_test(UserDict, dict)
46
47
Raymond Hettinger499e1932011-02-23 07:56:53 +000048################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000049### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000050################################################################################
51
52class TestChainMap(unittest.TestCase):
53
54 def test_basics(self):
55 c = ChainMap()
56 c['a'] = 1
57 c['b'] = 2
58 d = c.new_child()
59 d['b'] = 20
60 d['c'] = 30
61 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
62 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
63 self.assertEqual(len(d), 3) # check len
64 for key in 'abc': # check contains
65 self.assertIn(key, d)
66 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
67 self.assertEqual(d.get(k, 100), v)
68
69 del d['b'] # unmask a value
70 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
71 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
72 self.assertEqual(len(d), 3) # check len
73 for key in 'abc': # check contains
74 self.assertIn(key, d)
75 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
76 self.assertEqual(d.get(k, 100), v)
77 self.assertIn(repr(d), [ # check repr
78 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
79 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
80 ])
81
82 for e in d.copy(), copy.copy(d): # check shallow copies
83 self.assertEqual(d, e)
84 self.assertEqual(d.maps, e.maps)
85 self.assertIsNot(d, e)
86 self.assertIsNot(d.maps[0], e.maps[0])
87 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
88 self.assertIs(m1, m2)
89
Serhiy Storchakabad12572014-12-15 14:03:42 +020090 # check deep copies
91 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
92 e = pickle.loads(pickle.dumps(d, proto))
93 self.assertEqual(d, e)
94 self.assertEqual(d.maps, e.maps)
95 self.assertIsNot(d, e)
96 for m1, m2 in zip(d.maps, e.maps):
97 self.assertIsNot(m1, m2, e)
98 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +000099 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200100 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000101 self.assertEqual(d, e)
102 self.assertEqual(d.maps, e.maps)
103 self.assertIsNot(d, e)
104 for m1, m2 in zip(d.maps, e.maps):
105 self.assertIsNot(m1, m2, e)
106
Raymond Hettingerd0321312011-02-26 06:53:58 +0000107 f = d.new_child()
108 f['b'] = 5
109 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
110 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
111 self.assertEqual(f['b'], 5) # find first in chain
112 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000113
114 def test_contructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000115 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000116 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
117
Raymond Hettingerd0321312011-02-26 06:53:58 +0000118 def test_bool(self):
119 self.assertFalse(ChainMap())
120 self.assertFalse(ChainMap({}, {}))
121 self.assertTrue(ChainMap({1:2}, {}))
122 self.assertTrue(ChainMap({}, {1:2}))
123
Raymond Hettinger499e1932011-02-23 07:56:53 +0000124 def test_missing(self):
125 class DefaultChainMap(ChainMap):
126 def __missing__(self, key):
127 return 999
128 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
129 for k, v in dict(a=1, b=2, c=30, d=999).items():
130 self.assertEqual(d[k], v) # check __getitem__ w/missing
131 for k, v in dict(a=1, b=2, c=30, d=77).items():
132 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
133 for k, v in dict(a=True, b=True, c=True, d=False).items():
134 self.assertEqual(k in d, v) # check __contains__ w/missing
135 self.assertEqual(d.pop('a', 1001), 1, d)
136 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
137 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
138 with self.assertRaises(KeyError):
139 d.popitem()
140
141 def test_dict_coercion(self):
142 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
143 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
144 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
145
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000146 def test_new_child(self):
147 'Tests for changes for issue #16613.'
148 c = ChainMap()
149 c['a'] = 1
150 c['b'] = 2
151 m = {'b':20, 'c': 30}
152 d = c.new_child(m)
153 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
154 self.assertIs(m, d.maps[0])
155
156 # Use a different map than a dict
157 class lowerdict(dict):
158 def __getitem__(self, key):
159 if isinstance(key, str):
160 key = key.lower()
161 return dict.__getitem__(self, key)
162 def __contains__(self, key):
163 if isinstance(key, str):
164 key = key.lower()
165 return dict.__contains__(self, key)
166
167 c = ChainMap()
168 c['a'] = 1
169 c['b'] = 2
170 m = lowerdict(b=20, c=30)
171 d = c.new_child(m)
172 self.assertIs(m, d.maps[0])
173 for key in 'abc': # check contains
174 self.assertIn(key, d)
175 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
176 self.assertEqual(d.get(k, 100), v)
177
Raymond Hettinger499e1932011-02-23 07:56:53 +0000178
179################################################################################
180### Named Tuples
181################################################################################
182
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000183TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000184
185class TestNamedTuple(unittest.TestCase):
186
187 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000188 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000189 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000190 self.assertEqual(Point.__slots__, ())
191 self.assertEqual(Point.__module__, __name__)
192 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000193 self.assertEqual(Point._fields, ('x', 'y'))
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700194 self.assertIn('class Point(tuple)', Point._source)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000195
196 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
197 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
198 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
199
200 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
201 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
202 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000203 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000204 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
205
206 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000207 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000208
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000209 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000210 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000211 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000212 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000213
Christian Heimesfaf2f632008-01-06 16:59:19 +0000214 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
215 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
216
R. David Murray378c0cf2010-02-24 01:46:21 +0000217 @unittest.skipIf(sys.flags.optimize >= 2,
218 "Docstrings are omitted with -O2 and above")
219 def test_factory_doc_attr(self):
220 Point = namedtuple('Point', 'x y')
221 self.assertEqual(Point.__doc__, 'Point(x, y)')
222
Raymond Hettingereac503a2015-05-13 01:09:59 -0700223 @unittest.skipIf(sys.flags.optimize >= 2,
224 "Docstrings are omitted with -O2 and above")
225 def test_doc_writable(self):
226 Point = namedtuple('Point', 'x y')
227 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
228 Point.x.__doc__ = 'docstring for Point.x'
229 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
230
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000231 def test_name_fixer(self):
232 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000233 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
234 [('abc', 'class'), ('abc', '_1')], # field has keyword
235 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
236 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
237 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
238 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000239 ]:
240 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
241
Guido van Rossumd8faa362007-04-27 19:54:29 +0000242 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000243 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000244 p = Point(11, 22)
245 self.assertEqual(p, Point(x=11, y=22))
246 self.assertEqual(p, Point(11, y=22))
247 self.assertEqual(p, Point(y=22, x=11))
248 self.assertEqual(p, Point(*(11, 22)))
249 self.assertEqual(p, Point(**dict(x=11, y=22)))
250 self.assertRaises(TypeError, Point, 1) # too few args
251 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
252 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
253 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
254 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000255 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000256 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000257 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
258 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700259 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000260
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000261 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000262 p._replace(x=1, error=2)
263 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000264 pass
265 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000266 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000267
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000268 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000269 Point = namedtuple('Point', 'x, y')
270 p = Point(x=11, y=22)
271 self.assertEqual(repr(p), 'Point(x=11, y=22)')
272
273 # verify that fieldspec can be a non-string sequence
274 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000275 p = Point(x=11, y=22)
276 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000277
278 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000279 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000280 p = Point(11, 22)
281
Ezio Melottie9615932010-01-24 19:26:24 +0000282 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000283 self.assertEqual(p, (11, 22)) # matches a real tuple
284 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
285 self.assertEqual(list(p), [11, 22]) # coercable to a list
286 self.assertEqual(max(p), 22) # iterable
287 self.assertEqual(max(*p), 22) # star-able
288 x, y = p
289 self.assertEqual(p, (x, y)) # unpacks like a tuple
290 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
291 self.assertRaises(IndexError, p.__getitem__, 3)
292
293 self.assertEqual(p.x, x)
294 self.assertEqual(p.y, y)
295 self.assertRaises(AttributeError, eval, 'p.z', locals())
296
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000297 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000298 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000299 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000300 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000301 self.assertEqual(repr(Zero()), 'Zero()')
302 self.assertEqual(Zero()._asdict(), {})
303 self.assertEqual(Zero()._fields, ())
304
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000305 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000306 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000307 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000308 self.assertEqual(Dot(1).d, 1)
309 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
310 self.assertEqual(Dot(1)._asdict(), {'d':1})
311 self.assertEqual(Dot(1)._replace(d=999), (999,))
312 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000313
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000314 # n = 5000
Christian Heimes99170a52007-12-19 02:07:34 +0000315 n = 254 # SyntaxError: more than 255 arguments:
316 import string, random
Georg Brandlb533e262008-05-25 18:19:30 +0000317 names = list(set(''.join([random.choice(string.ascii_letters)
318 for j in range(10)]) for i in range(n)))
319 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000320 Big = namedtuple('Big', names)
321 b = Big(*range(n))
322 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000323 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000324 for pos, name in enumerate(names):
325 self.assertEqual(getattr(b, name), pos)
326 repr(b) # make sure repr() doesn't blow-up
327 d = b._asdict()
328 d_expected = dict(zip(names, range(n)))
329 self.assertEqual(d, d_expected)
330 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
331 b2_expected = list(range(n))
332 b2_expected[1] = 999
333 b2_expected[-5] = 42
334 self.assertEqual(b2, tuple(b2_expected))
335 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000336
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000337 def test_pickle(self):
338 p = TestNT(x=10, y=20, z=30)
339 for module in (pickle,):
340 loads = getattr(module, 'loads')
341 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500342 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000343 q = loads(dumps(p, protocol))
344 self.assertEqual(p, q)
345 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700346 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000347
348 def test_copy(self):
349 p = TestNT(x=10, y=20, z=30)
350 for copier in copy.copy, copy.deepcopy:
351 q = copier(p)
352 self.assertEqual(p, q)
353 self.assertEqual(p._fields, q._fields)
354
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000355 def test_name_conflicts(self):
356 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
357 # failed when used as field names. Test to make sure these now work.
358 T = namedtuple('T', 'itemgetter property self cls tuple')
359 t = T(1, 2, 3, 4, 5)
360 self.assertEqual(t, (1,2,3,4,5))
361 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
362 self.assertEqual(newt, (10,20,30,40,50))
363
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000364 # Broader test of all interesting names in a template
365 with support.captured_stdout() as template:
366 T = namedtuple('T', 'x', verbose=True)
367 words = set(re.findall('[A-Za-z]+', template.getvalue()))
368 words -= set(keyword.kwlist)
369 T = namedtuple('T', words)
370 # test __new__
371 values = tuple(range(len(words)))
372 t = T(*values)
373 self.assertEqual(t, values)
374 t = T(**dict(zip(T._fields, values)))
375 self.assertEqual(t, values)
376 # test _make
377 t = T._make(values)
378 self.assertEqual(t, values)
379 # exercise __repr__
380 repr(t)
381 # test _asdict
382 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
383 # test _replace
384 t = T._make(values)
385 newvalues = tuple(v*10 for v in values)
386 newt = t._replace(**dict(zip(T._fields, newvalues)))
387 self.assertEqual(newt, newvalues)
388 # test _fields
389 self.assertEqual(T._fields, tuple(words))
390 # test __getnewargs__
391 self.assertEqual(t.__getnewargs__(), values)
392
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000393 def test_repr(self):
394 with support.captured_stdout() as template:
395 A = namedtuple('A', 'x', verbose=True)
396 self.assertEqual(repr(A(1)), 'A(x=1)')
397 # repr should show the name of the subclass
398 class B(A):
399 pass
400 self.assertEqual(repr(B(1)), 'B(x=1)')
401
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700402 def test_source(self):
403 # verify that _source can be run through exec()
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700404 tmp = namedtuple('NTColor', 'red green blue')
405 globals().pop('NTColor', None) # remove artifacts from other tests
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700406 exec(tmp._source, globals())
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700407 self.assertIn('NTColor', globals())
408 c = NTColor(10, 20, 30)
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700409 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700410 self.assertEqual(NTColor._fields, ('red', 'green', 'blue'))
411 globals().pop('NTColor', None) # clean-up after this test
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700412
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000413
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700414 def test_namedtuple_subclass_issue_24931(self):
415 class Point(namedtuple('_Point', ['x', 'y'])):
416 pass
417
418 a = Point(3, 4)
419 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
420
421 a.w = 5
422 self.assertEqual(a.__dict__, {'w': 5})
423
424
Raymond Hettinger499e1932011-02-23 07:56:53 +0000425################################################################################
426### Abstract Base Classes
427################################################################################
428
Raymond Hettingerae650182009-01-28 23:33:59 +0000429class ABCTestCase(unittest.TestCase):
430
431 def validate_abstract_methods(self, abc, *names):
432 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
433
434 # everything should work will all required methods are present
435 C = type('C', (abc,), methodstubs)
436 C()
437
438 # instantiation should fail if a required method is missing
439 for name in names:
440 stubs = methodstubs.copy()
441 del stubs[name]
442 C = type('C', (abc,), stubs)
443 self.assertRaises(TypeError, C, name)
444
Florent Xiclunace153f62010-03-08 15:34:35 +0000445 def validate_isinstance(self, abc, name):
446 stub = lambda s, *args: 0
447
448 C = type('C', (object,), {'__hash__': None})
449 setattr(C, name, stub)
450 self.assertIsInstance(C(), abc)
451 self.assertTrue(issubclass(C, abc))
452
453 C = type('C', (object,), {'__hash__': None})
454 self.assertNotIsInstance(C(), abc)
455 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000456
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000457 def validate_comparison(self, instance):
458 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
459 operators = {}
460 for op in ops:
461 name = '__' + op + '__'
462 operators[name] = getattr(operator, name)
463
464 class Other:
465 def __init__(self):
466 self.right_side = False
467 def __eq__(self, other):
468 self.right_side = True
469 return True
470 __lt__ = __eq__
471 __gt__ = __eq__
472 __le__ = __eq__
473 __ge__ = __eq__
474 __ne__ = __eq__
475 __ror__ = __eq__
476 __rand__ = __eq__
477 __rxor__ = __eq__
478 __rsub__ = __eq__
479
480 for name, op in operators.items():
481 if not hasattr(instance, name):
482 continue
483 other = Other()
484 op(instance, other)
485 self.assertTrue(other.right_side,'Right side not called for %s.%s'
486 % (type(instance), name))
487
Raymond Hettingerae650182009-01-28 23:33:59 +0000488class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000489
Yury Selivanov75445082015-05-11 22:57:16 -0400490 def test_Awaitable(self):
491 def gen():
492 yield
493
494 @types.coroutine
495 def coro():
496 yield
497
498 async def new_coro():
499 pass
500
501 class Bar:
502 def __await__(self):
503 yield
504
505 class MinimalCoro(Coroutine):
506 def send(self, value):
507 return value
508 def throw(self, typ, val=None, tb=None):
509 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400510 def __await__(self):
511 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400512
513 non_samples = [None, int(), gen(), object()]
514 for x in non_samples:
515 self.assertNotIsInstance(x, Awaitable)
516 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
517
518 samples = [Bar(), MinimalCoro()]
519 for x in samples:
520 self.assertIsInstance(x, Awaitable)
521 self.assertTrue(issubclass(type(x), Awaitable))
522
523 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400524 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
525 # flag don't have '__await__' method, hence can't be instances
526 # of Awaitable. Use inspect.isawaitable to detect them.
527 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400528
529 c = new_coro()
530 self.assertIsInstance(c, Awaitable)
531 c.close() # awoid RuntimeWarning that coro() was not awaited
532
Yury Selivanov56fc6142015-05-29 09:01:29 -0400533 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400534 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400535 self.assertTrue(isinstance(CoroLike(), Awaitable))
536 self.assertTrue(issubclass(CoroLike, Awaitable))
537 CoroLike = None
538 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400539
Yury Selivanov75445082015-05-11 22:57:16 -0400540 def test_Coroutine(self):
541 def gen():
542 yield
543
544 @types.coroutine
545 def coro():
546 yield
547
548 async def new_coro():
549 pass
550
551 class Bar:
552 def __await__(self):
553 yield
554
555 class MinimalCoro(Coroutine):
556 def send(self, value):
557 return value
558 def throw(self, typ, val=None, tb=None):
559 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400560 def __await__(self):
561 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400562
563 non_samples = [None, int(), gen(), object(), Bar()]
564 for x in non_samples:
565 self.assertNotIsInstance(x, Coroutine)
566 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
567
568 samples = [MinimalCoro()]
569 for x in samples:
570 self.assertIsInstance(x, Awaitable)
571 self.assertTrue(issubclass(type(x), Awaitable))
572
573 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400574 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
575 # flag don't have '__await__' method, hence can't be instances
576 # of Coroutine. Use inspect.isawaitable to detect them.
577 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400578
579 c = new_coro()
580 self.assertIsInstance(c, Coroutine)
581 c.close() # awoid RuntimeWarning that coro() was not awaited
582
Yury Selivanov56fc6142015-05-29 09:01:29 -0400583 class CoroLike:
584 def send(self, value):
585 pass
586 def throw(self, typ, val=None, tb=None):
587 pass
588 def close(self):
589 pass
590 def __await__(self):
591 pass
592 self.assertTrue(isinstance(CoroLike(), Coroutine))
593 self.assertTrue(issubclass(CoroLike, Coroutine))
594
595 class CoroLike:
596 def send(self, value):
597 pass
598 def close(self):
599 pass
600 def __await__(self):
601 pass
602 self.assertFalse(isinstance(CoroLike(), Coroutine))
603 self.assertFalse(issubclass(CoroLike, Coroutine))
604
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000605 def test_Hashable(self):
606 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000607 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000608 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000609 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000610 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000611 # Check some hashables
612 samples = [None,
613 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000614 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000615 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000616 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000617 ]
618 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000619 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000620 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000621 self.assertRaises(TypeError, Hashable)
622 # Check direct subclassing
623 class H(Hashable):
624 def __hash__(self):
625 return super().__hash__()
626 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000627 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000628 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000629 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000630
Yury Selivanove0104ae2015-05-14 12:19:16 -0400631 def test_AsyncIterable(self):
632 class AI:
633 async def __aiter__(self):
634 return self
635 self.assertTrue(isinstance(AI(), AsyncIterable))
636 self.assertTrue(issubclass(AI, AsyncIterable))
637 # Check some non-iterables
638 non_samples = [None, object, []]
639 for x in non_samples:
640 self.assertNotIsInstance(x, AsyncIterable)
641 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
642 self.validate_abstract_methods(AsyncIterable, '__aiter__')
643 self.validate_isinstance(AsyncIterable, '__aiter__')
644
645 def test_AsyncIterator(self):
646 class AI:
647 async def __aiter__(self):
648 return self
649 async def __anext__(self):
650 raise StopAsyncIteration
651 self.assertTrue(isinstance(AI(), AsyncIterator))
652 self.assertTrue(issubclass(AI, AsyncIterator))
653 non_samples = [None, object, []]
654 # Check some non-iterables
655 for x in non_samples:
656 self.assertNotIsInstance(x, AsyncIterator)
657 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
658 # Similarly to regular iterators (see issue 10565)
659 class AnextOnly:
660 async def __anext__(self):
661 raise StopAsyncIteration
662 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
663 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
664
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000665 def test_Iterable(self):
666 # Check some non-iterables
667 non_samples = [None, 42, 3.14, 1j]
668 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000669 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000670 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000671 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000672 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000673 tuple(), list(), set(), frozenset(), dict(),
674 dict().keys(), dict().items(), dict().values(),
675 (lambda: (yield))(),
676 (x for x in []),
677 ]
678 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000679 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000680 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000681 # Check direct subclassing
682 class I(Iterable):
683 def __iter__(self):
684 return super().__iter__()
685 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000686 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000687 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000688 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000689
690 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000691 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000692 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000693 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000694 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000695 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000696 iter(tuple()), iter(list()), iter(dict()),
697 iter(set()), iter(frozenset()),
698 iter(dict().keys()), iter(dict().items()),
699 iter(dict().values()),
700 (lambda: (yield))(),
701 (x for x in []),
702 ]
703 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000704 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000705 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000706 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
707
708 # Issue 10565
709 class NextOnly:
710 def __next__(self):
711 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800712 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000713 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000714
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400715 def test_Generator(self):
716 class NonGen1:
717 def __iter__(self): return self
718 def __next__(self): return None
719 def close(self): pass
720 def throw(self, typ, val=None, tb=None): pass
721
722 class NonGen2:
723 def __iter__(self): return self
724 def __next__(self): return None
725 def close(self): pass
726 def send(self, value): return value
727
728 class NonGen3:
729 def close(self): pass
730 def send(self, value): return value
731 def throw(self, typ, val=None, tb=None): pass
732
733 non_samples = [
734 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
735 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
736 for x in non_samples:
737 self.assertNotIsInstance(x, Generator)
738 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
739
740 class Gen:
741 def __iter__(self): return self
742 def __next__(self): return None
743 def close(self): pass
744 def send(self, value): return value
745 def throw(self, typ, val=None, tb=None): pass
746
747 class MinimalGen(Generator):
748 def send(self, value):
749 return value
750 def throw(self, typ, val=None, tb=None):
751 super().throw(typ, val, tb)
752
753 def gen():
754 yield 1
755
756 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
757 for x in samples:
758 self.assertIsInstance(x, Iterator)
759 self.assertIsInstance(x, Generator)
760 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
761 self.validate_abstract_methods(Generator, 'send', 'throw')
762
763 # mixin tests
764 mgen = MinimalGen()
765 self.assertIs(mgen, iter(mgen))
766 self.assertIs(mgen.send(None), next(mgen))
767 self.assertEqual(2, mgen.send(2))
768 self.assertIsNone(mgen.close())
769 self.assertRaises(ValueError, mgen.throw, ValueError)
770 self.assertRaisesRegex(ValueError, "^huhu$",
771 mgen.throw, ValueError, ValueError("huhu"))
772 self.assertRaises(StopIteration, mgen.throw, StopIteration())
773
774 class FailOnClose(Generator):
775 def send(self, value): return value
776 def throw(self, *args): raise ValueError
777
778 self.assertRaises(ValueError, FailOnClose().close)
779
780 class IgnoreGeneratorExit(Generator):
781 def send(self, value): return value
782 def throw(self, *args): pass
783
784 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
785
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000786 def test_Sized(self):
787 non_samples = [None, 42, 3.14, 1j,
788 (lambda: (yield))(),
789 (x for x in []),
790 ]
791 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000792 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000793 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000794 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000795 tuple(), list(), set(), frozenset(), dict(),
796 dict().keys(), dict().items(), dict().values(),
797 ]
798 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000799 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000800 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000801 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000802 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000803
804 def test_Container(self):
805 non_samples = [None, 42, 3.14, 1j,
806 (lambda: (yield))(),
807 (x for x in []),
808 ]
809 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000810 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000811 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000812 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000813 tuple(), list(), set(), frozenset(), dict(),
814 dict().keys(), dict().items(),
815 ]
816 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000817 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000818 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000819 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000820 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000821
822 def test_Callable(self):
823 non_samples = [None, 42, 3.14, 1j,
824 "", b"", (), [], {}, set(),
825 (lambda: (yield))(),
826 (x for x in []),
827 ]
828 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000829 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000830 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000831 samples = [lambda: None,
832 type, int, object,
833 len,
834 list.append, [].append,
835 ]
836 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000837 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000838 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000839 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000840 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000841
842 def test_direct_subclassing(self):
843 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
844 class C(B):
845 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000846 self.assertTrue(issubclass(C, B))
847 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000848
849 def test_registration(self):
850 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
851 class C:
852 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000853 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000854 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000855 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000856
Raymond Hettinger3f10a952009-04-01 19:05:50 +0000857class WithSet(MutableSet):
858
859 def __init__(self, it=()):
860 self.data = set(it)
861
862 def __len__(self):
863 return len(self.data)
864
865 def __iter__(self):
866 return iter(self.data)
867
868 def __contains__(self, item):
869 return item in self.data
870
871 def add(self, item):
872 self.data.add(item)
873
874 def discard(self, item):
875 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000876
Raymond Hettingerae650182009-01-28 23:33:59 +0000877class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000878
879 # XXX For now, we only test some virtual inheritance properties.
880 # We should also test the proper behavior of the collection ABCs
881 # as real base classes or mix-in classes.
882
883 def test_Set(self):
884 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +0000885 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000886 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +0000887 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000888 class MySet(Set):
889 def __contains__(self, x):
890 return False
891 def __len__(self):
892 return 0
893 def __iter__(self):
894 return iter([])
895 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000896
Benjamin Peterson41181742008-07-02 20:22:54 +0000897 def test_hash_Set(self):
898 class OneTwoThreeSet(Set):
899 def __init__(self):
900 self.contents = [1, 2, 3]
901 def __contains__(self, x):
902 return x in self.contents
903 def __len__(self):
904 return len(self.contents)
905 def __iter__(self):
906 return iter(self.contents)
907 def __hash__(self):
908 return self._hash()
909 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000910 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +0000911
Raymond Hettinger2d452ee2014-05-25 18:28:39 -0700912 def test_isdisjoint_Set(self):
913 class MySet(Set):
914 def __init__(self, itr):
915 self.contents = itr
916 def __contains__(self, x):
917 return x in self.contents
918 def __iter__(self):
919 return iter(self.contents)
920 def __len__(self):
921 return len([x for x in self.contents])
922 s1 = MySet((1, 2, 3))
923 s2 = MySet((4, 5, 6))
924 s3 = MySet((1, 5, 6))
925 self.assertTrue(s1.isdisjoint(s2))
926 self.assertFalse(s1.isdisjoint(s3))
927
928 def test_equality_Set(self):
929 class MySet(Set):
930 def __init__(self, itr):
931 self.contents = itr
932 def __contains__(self, x):
933 return x in self.contents
934 def __iter__(self):
935 return iter(self.contents)
936 def __len__(self):
937 return len([x for x in self.contents])
938 s1 = MySet((1,))
939 s2 = MySet((1, 2))
940 s3 = MySet((3, 4))
941 s4 = MySet((3, 4))
942 self.assertTrue(s2 > s1)
943 self.assertTrue(s1 < s2)
944 self.assertFalse(s2 <= s1)
945 self.assertFalse(s2 <= s3)
946 self.assertFalse(s1 >= s2)
947 self.assertEqual(s3, s4)
948 self.assertNotEqual(s2, s3)
949
950 def test_arithmetic_Set(self):
951 class MySet(Set):
952 def __init__(self, itr):
953 self.contents = itr
954 def __contains__(self, x):
955 return x in self.contents
956 def __iter__(self):
957 return iter(self.contents)
958 def __len__(self):
959 return len([x for x in self.contents])
960 s1 = MySet((1, 2, 3))
961 s2 = MySet((3, 4, 5))
962 s3 = s1 & s2
963 self.assertEqual(s3, MySet((3,)))
964
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000965 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +0000966 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000967 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +0000968 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000969 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +0000970 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
971 'add', 'discard')
972
Raymond Hettinger3f10a952009-04-01 19:05:50 +0000973 def test_issue_5647(self):
974 # MutableSet.__iand__ mutated the set during iteration
975 s = WithSet('abcd')
976 s &= WithSet('cdef') # This used to fail
977 self.assertEqual(set(s), set('cd'))
978
Raymond Hettingerae650182009-01-28 23:33:59 +0000979 def test_issue_4920(self):
980 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000981 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +0000982 __slots__=['__s']
983 def __init__(self,items=None):
984 if items is None:
985 items=[]
986 self.__s=set(items)
987 def __contains__(self,v):
988 return v in self.__s
989 def __iter__(self):
990 return iter(self.__s)
991 def __len__(self):
992 return len(self.__s)
993 def add(self,v):
994 result=v not in self.__s
995 self.__s.add(v)
996 return result
997 def discard(self,v):
998 result=v in self.__s
999 self.__s.discard(v)
1000 return result
1001 def __repr__(self):
1002 return "MySet(%s)" % repr(list(self))
1003 s = MySet([5,43,2,1])
1004 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001005
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001006 def test_issue8750(self):
1007 empty = WithSet()
1008 full = WithSet(range(10))
1009 s = WithSet(full)
1010 s -= s
1011 self.assertEqual(s, empty)
1012 s = WithSet(full)
1013 s ^= s
1014 self.assertEqual(s, empty)
1015 s = WithSet(full)
1016 s &= s
1017 self.assertEqual(s, full)
1018 s |= s
1019 self.assertEqual(s, full)
1020
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001021 def test_issue16373(self):
1022 # Recursion error comparing comparable and noncomparable
1023 # Set instances
1024 class MyComparableSet(Set):
1025 def __contains__(self, x):
1026 return False
1027 def __len__(self):
1028 return 0
1029 def __iter__(self):
1030 return iter([])
1031 class MyNonComparableSet(Set):
1032 def __contains__(self, x):
1033 return False
1034 def __len__(self):
1035 return 0
1036 def __iter__(self):
1037 return iter([])
1038 def __le__(self, x):
1039 return NotImplemented
1040 def __lt__(self, x):
1041 return NotImplemented
1042
1043 cs = MyComparableSet()
1044 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001045 self.assertFalse(ncs < cs)
1046 self.assertTrue(ncs <= cs)
1047 self.assertFalse(ncs > cs)
1048 self.assertTrue(ncs >= cs)
1049
1050 def assertSameSet(self, s1, s2):
1051 # coerce both to a real set then check equality
1052 self.assertSetEqual(set(s1), set(s2))
1053
1054 def test_Set_interoperability_with_real_sets(self):
1055 # Issue: 8743
1056 class ListSet(Set):
1057 def __init__(self, elements=()):
1058 self.data = []
1059 for elem in elements:
1060 if elem not in self.data:
1061 self.data.append(elem)
1062 def __contains__(self, elem):
1063 return elem in self.data
1064 def __iter__(self):
1065 return iter(self.data)
1066 def __len__(self):
1067 return len(self.data)
1068 def __repr__(self):
1069 return 'Set({!r})'.format(self.data)
1070
1071 r1 = set('abc')
1072 r2 = set('bcd')
1073 r3 = set('abcde')
1074 f1 = ListSet('abc')
1075 f2 = ListSet('bcd')
1076 f3 = ListSet('abcde')
1077 l1 = list('abccba')
1078 l2 = list('bcddcb')
1079 l3 = list('abcdeedcba')
1080
1081 target = r1 & r2
1082 self.assertSameSet(f1 & f2, target)
1083 self.assertSameSet(f1 & r2, target)
1084 self.assertSameSet(r2 & f1, target)
1085 self.assertSameSet(f1 & l2, target)
1086
1087 target = r1 | r2
1088 self.assertSameSet(f1 | f2, target)
1089 self.assertSameSet(f1 | r2, target)
1090 self.assertSameSet(r2 | f1, target)
1091 self.assertSameSet(f1 | l2, target)
1092
1093 fwd_target = r1 - r2
1094 rev_target = r2 - r1
1095 self.assertSameSet(f1 - f2, fwd_target)
1096 self.assertSameSet(f2 - f1, rev_target)
1097 self.assertSameSet(f1 - r2, fwd_target)
1098 self.assertSameSet(f2 - r1, rev_target)
1099 self.assertSameSet(r1 - f2, fwd_target)
1100 self.assertSameSet(r2 - f1, rev_target)
1101 self.assertSameSet(f1 - l2, fwd_target)
1102 self.assertSameSet(f2 - l1, rev_target)
1103
1104 target = r1 ^ r2
1105 self.assertSameSet(f1 ^ f2, target)
1106 self.assertSameSet(f1 ^ r2, target)
1107 self.assertSameSet(r2 ^ f1, target)
1108 self.assertSameSet(f1 ^ l2, target)
1109
1110 # Don't change the following to use assertLess or other
1111 # "more specific" unittest assertions. The current
1112 # assertTrue/assertFalse style makes the pattern of test
1113 # case combinations clear and allows us to know for sure
1114 # the exact operator being invoked.
1115
1116 # proper subset
1117 self.assertTrue(f1 < f3)
1118 self.assertFalse(f1 < f1)
1119 self.assertFalse(f1 < f2)
1120 self.assertTrue(r1 < f3)
1121 self.assertFalse(r1 < f1)
1122 self.assertFalse(r1 < f2)
1123 self.assertTrue(r1 < r3)
1124 self.assertFalse(r1 < r1)
1125 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001126 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001127 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001128 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001129 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001130 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001131 f1 < l2
1132
1133 # any subset
1134 self.assertTrue(f1 <= f3)
1135 self.assertTrue(f1 <= f1)
1136 self.assertFalse(f1 <= f2)
1137 self.assertTrue(r1 <= f3)
1138 self.assertTrue(r1 <= f1)
1139 self.assertFalse(r1 <= f2)
1140 self.assertTrue(r1 <= r3)
1141 self.assertTrue(r1 <= r1)
1142 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001143 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001144 f1 <= l3
1145 with self.assertRaises(TypeError):
1146 f1 <= l1
1147 with self.assertRaises(TypeError):
1148 f1 <= l2
1149
1150 # proper superset
1151 self.assertTrue(f3 > f1)
1152 self.assertFalse(f1 > f1)
1153 self.assertFalse(f2 > f1)
1154 self.assertTrue(r3 > r1)
1155 self.assertFalse(f1 > r1)
1156 self.assertFalse(f2 > r1)
1157 self.assertTrue(r3 > r1)
1158 self.assertFalse(r1 > r1)
1159 self.assertFalse(r2 > r1)
1160 with self.assertRaises(TypeError):
1161 f1 > l3
1162 with self.assertRaises(TypeError):
1163 f1 > l1
1164 with self.assertRaises(TypeError):
1165 f1 > l2
1166
1167 # any superset
1168 self.assertTrue(f3 >= f1)
1169 self.assertTrue(f1 >= f1)
1170 self.assertFalse(f2 >= f1)
1171 self.assertTrue(r3 >= r1)
1172 self.assertTrue(f1 >= r1)
1173 self.assertFalse(f2 >= r1)
1174 self.assertTrue(r3 >= r1)
1175 self.assertTrue(r1 >= r1)
1176 self.assertFalse(r2 >= r1)
1177 with self.assertRaises(TypeError):
1178 f1 >= l3
1179 with self.assertRaises(TypeError):
1180 f1 >=l1
1181 with self.assertRaises(TypeError):
1182 f1 >= l2
1183
1184 # equality
1185 self.assertTrue(f1 == f1)
1186 self.assertTrue(r1 == f1)
1187 self.assertTrue(f1 == r1)
1188 self.assertFalse(f1 == f3)
1189 self.assertFalse(r1 == f3)
1190 self.assertFalse(f1 == r3)
1191 self.assertFalse(f1 == l3)
1192 self.assertFalse(f1 == l1)
1193 self.assertFalse(f1 == l2)
1194
1195 # inequality
1196 self.assertFalse(f1 != f1)
1197 self.assertFalse(r1 != f1)
1198 self.assertFalse(f1 != r1)
1199 self.assertTrue(f1 != f3)
1200 self.assertTrue(r1 != f3)
1201 self.assertTrue(f1 != r3)
1202 self.assertTrue(f1 != l3)
1203 self.assertTrue(f1 != l1)
1204 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001205
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001206 def test_Mapping(self):
1207 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001208 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001209 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001210 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1211 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001212 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001213 def __len__(self):
1214 return 0
1215 def __getitem__(self, i):
1216 raise IndexError
1217 def __iter__(self):
1218 return iter(())
1219 self.validate_comparison(MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001220
1221 def test_MutableMapping(self):
1222 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001223 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001224 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001225 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1226 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001227
Raymond Hettinger9117c752010-08-22 07:44:24 +00001228 def test_MutableMapping_subclass(self):
1229 # Test issue 9214
1230 mymap = UserDict()
1231 mymap['red'] = 5
1232 self.assertIsInstance(mymap.keys(), Set)
1233 self.assertIsInstance(mymap.keys(), KeysView)
1234 self.assertIsInstance(mymap.items(), Set)
1235 self.assertIsInstance(mymap.items(), ItemsView)
1236
1237 mymap = UserDict()
1238 mymap['red'] = 5
1239 z = mymap.keys() | {'orange'}
1240 self.assertIsInstance(z, set)
1241 list(z)
1242 mymap['blue'] = 7 # Shouldn't affect 'z'
1243 self.assertEqual(sorted(z), ['orange', 'red'])
1244
1245 mymap = UserDict()
1246 mymap['red'] = 5
1247 z = mymap.items() | {('orange', 3)}
1248 self.assertIsInstance(z, set)
1249 list(z)
1250 mymap['blue'] = 7 # Shouldn't affect 'z'
1251 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1252
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001253 def test_Sequence(self):
1254 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001255 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001256 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001257 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001258 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001259 self.assertIsInstance(memoryview(b""), Sequence)
1260 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001261 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001262 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1263 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001264
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001265 def test_Sequence_mixins(self):
1266 class SequenceSubclass(Sequence):
1267 def __init__(self, seq=()):
1268 self.seq = seq
1269
1270 def __getitem__(self, index):
1271 return self.seq[index]
1272
1273 def __len__(self):
1274 return len(self.seq)
1275
1276 # Compare Sequence.index() behavior to (list|str).index() behavior
1277 def assert_index_same(seq1, seq2, index_args):
1278 try:
1279 expected = seq1.index(*index_args)
1280 except ValueError:
1281 with self.assertRaises(ValueError):
1282 seq2.index(*index_args)
1283 else:
1284 actual = seq2.index(*index_args)
1285 self.assertEqual(
1286 actual, expected, '%r.index%s' % (seq1, index_args))
1287
1288 for ty in list, str:
1289 nativeseq = ty('abracadabra')
1290 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1291 seqseq = SequenceSubclass(nativeseq)
1292 for letter in set(nativeseq) | {'z'}:
1293 assert_index_same(nativeseq, seqseq, (letter,))
1294 for start in range(-3, len(nativeseq) + 3):
1295 assert_index_same(nativeseq, seqseq, (letter, start))
1296 for stop in range(-3, len(nativeseq) + 3):
1297 assert_index_same(
1298 nativeseq, seqseq, (letter, start, stop))
1299
Guido van Rossumd05eb002007-11-21 22:26:24 +00001300 def test_ByteString(self):
1301 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001302 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001303 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001304 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001305 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001306 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001307 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001308 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001309
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001310 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001311 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001312 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001313 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001314 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001315 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001316 self.assertTrue(issubclass(sample, MutableSequence))
1317 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001318 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1319 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001320
Eli Bendersky0716a572011-03-04 10:38:14 +00001321 def test_MutableSequence_mixins(self):
1322 # Test the mixins of MutableSequence by creating a miminal concrete
1323 # class inherited from it.
1324 class MutableSequenceSubclass(MutableSequence):
1325 def __init__(self):
1326 self.lst = []
1327
1328 def __setitem__(self, index, value):
1329 self.lst[index] = value
1330
1331 def __getitem__(self, index):
1332 return self.lst[index]
1333
1334 def __len__(self):
1335 return len(self.lst)
1336
1337 def __delitem__(self, index):
1338 del self.lst[index]
1339
1340 def insert(self, index, value):
1341 self.lst.insert(index, value)
1342
1343 mss = MutableSequenceSubclass()
1344 mss.append(0)
1345 mss.extend((1, 2, 3, 4))
1346 self.assertEqual(len(mss), 5)
1347 self.assertEqual(mss[3], 3)
1348 mss.reverse()
1349 self.assertEqual(mss[3], 1)
1350 mss.pop()
1351 self.assertEqual(len(mss), 4)
1352 mss.remove(3)
1353 self.assertEqual(len(mss), 3)
1354 mss += (10, 20, 30)
1355 self.assertEqual(len(mss), 6)
1356 self.assertEqual(mss[-1], 30)
1357 mss.clear()
1358 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001359
1360################################################################################
1361### Counter
1362################################################################################
1363
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001364class CounterSubclassWithSetItem(Counter):
1365 # Test a counter subclass that overrides __setitem__
1366 def __init__(self, *args, **kwds):
1367 self.called = False
1368 Counter.__init__(self, *args, **kwds)
1369 def __setitem__(self, key, value):
1370 self.called = True
1371 Counter.__setitem__(self, key, value)
1372
1373class CounterSubclassWithGet(Counter):
1374 # Test a counter subclass that overrides get()
1375 def __init__(self, *args, **kwds):
1376 self.called = False
1377 Counter.__init__(self, *args, **kwds)
1378 def get(self, key, default):
1379 self.called = True
1380 return Counter.get(self, key, default)
1381
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001382class TestCounter(unittest.TestCase):
1383
1384 def test_basics(self):
1385 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001386 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1387 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001388 self.assertIsInstance(c, dict)
1389 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001390 self.assertTrue(issubclass(Counter, dict))
1391 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001392 self.assertEqual(len(c), 3)
1393 self.assertEqual(sum(c.values()), 6)
1394 self.assertEqual(sorted(c.values()), [1, 2, 3])
1395 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1396 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1397 self.assertEqual(sorted(c.items()),
1398 [('a', 3), ('b', 2), ('c', 1)])
1399 self.assertEqual(c['b'], 2)
1400 self.assertEqual(c['z'], 0)
1401 self.assertEqual(c.__contains__('c'), True)
1402 self.assertEqual(c.__contains__('z'), False)
1403 self.assertEqual(c.get('b', 10), 2)
1404 self.assertEqual(c.get('z', 10), 10)
1405 self.assertEqual(c, dict(a=3, b=2, c=1))
1406 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1407 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1408 for i in range(5):
1409 self.assertEqual(c.most_common(i),
1410 [('a', 3), ('b', 2), ('c', 1)][:i])
1411 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1412 c['a'] += 1 # increment an existing value
1413 c['b'] -= 2 # sub existing value to zero
1414 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001415 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001416 c['d'] -= 2 # sub from a missing value
1417 c['e'] = -5 # directly assign a missing value
1418 c['f'] += 4 # add to a missing value
1419 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1420 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1421 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001422 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001423 for i in range(3):
1424 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001425 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001426 c.clear()
1427 self.assertEqual(c, {})
1428 self.assertEqual(repr(c), 'Counter()')
1429 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1430 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001431 c.update(dict(a=5, b=3))
1432 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001433 c.update(Counter('a' * 50 + 'b' * 30))
1434 c.update() # test case with no args
1435 c.__init__('a' * 500 + 'b' * 300)
1436 c.__init__('cdc')
1437 c.__init__()
1438 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1439 self.assertEqual(c.setdefault('d', 5), 1)
1440 self.assertEqual(c['d'], 1)
1441 self.assertEqual(c.setdefault('e', 5), 5)
1442 self.assertEqual(c['e'], 5)
1443
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001444 def test_init(self):
1445 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1446 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1447 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1448 self.assertRaises(TypeError, Counter, 42)
1449 self.assertRaises(TypeError, Counter, (), ())
1450 self.assertRaises(TypeError, Counter.__init__)
1451
1452 def test_update(self):
1453 c = Counter()
1454 c.update(self=42)
1455 self.assertEqual(list(c.items()), [('self', 42)])
1456 c = Counter()
1457 c.update(iterable=42)
1458 self.assertEqual(list(c.items()), [('iterable', 42)])
1459 c = Counter()
1460 c.update(iterable=None)
1461 self.assertEqual(list(c.items()), [('iterable', None)])
1462 self.assertRaises(TypeError, Counter().update, 42)
1463 self.assertRaises(TypeError, Counter().update, {}, {})
1464 self.assertRaises(TypeError, Counter.update)
1465
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001466 def test_copying(self):
1467 # Check that counters are copyable, deepcopyable, picklable, and
1468 #have a repr/eval round-trip
1469 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001470 def check(dup):
1471 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1472 self.assertIsNot(dup, words, msg)
1473 self.assertEqual(dup, words)
1474 check(words.copy())
1475 check(copy.copy(words))
1476 check(copy.deepcopy(words))
1477 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1478 with self.subTest(proto=proto):
1479 check(pickle.loads(pickle.dumps(words, proto)))
1480 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001481 update_test = Counter()
1482 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001483 check(update_test)
1484 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001485
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001486 def test_copy_subclass(self):
1487 class MyCounter(Counter):
1488 pass
1489 c = MyCounter('slartibartfast')
1490 d = c.copy()
1491 self.assertEqual(d, c)
1492 self.assertEqual(len(d), len(c))
1493 self.assertEqual(type(d), type(c))
1494
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001495 def test_conversions(self):
1496 # Convert to: set, list, dict
1497 s = 'she sells sea shells by the sea shore'
1498 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1499 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1500 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1501 self.assertEqual(set(Counter(s)), set(s))
1502
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001503 def test_invariant_for_the_in_operator(self):
1504 c = Counter(a=10, b=-2, c=0)
1505 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001506 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001507 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001508
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001509 def test_multiset_operations(self):
1510 # Verify that adding a zero counter will strip zeros and negatives
1511 c = Counter(a=10, b=-2, c=0) + Counter()
1512 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001513
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001514 elements = 'abcd'
1515 for i in range(1000):
1516 # test random pairs of multisets
1517 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001518 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001519 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001520 q.update(h=1, i=-1, j=0)
1521 for counterop, numberop in [
1522 (Counter.__add__, lambda x, y: max(0, x+y)),
1523 (Counter.__sub__, lambda x, y: max(0, x-y)),
1524 (Counter.__or__, lambda x, y: max(0,x,y)),
1525 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001526 ]:
1527 result = counterop(p, q)
1528 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001529 self.assertEqual(numberop(p[x], q[x]), result[x],
1530 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001531 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001532 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001533
1534 elements = 'abcdef'
1535 for i in range(100):
1536 # verify that random multisets with no repeats are exactly like sets
1537 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1538 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1539 for counterop, setop in [
1540 (Counter.__sub__, set.__sub__),
1541 (Counter.__or__, set.__or__),
1542 (Counter.__and__, set.__and__),
1543 ]:
1544 counter_result = counterop(p, q)
1545 set_result = setop(set(p.elements()), set(q.elements()))
1546 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001547
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001548 def test_inplace_operations(self):
1549 elements = 'abcd'
1550 for i in range(1000):
1551 # test random pairs of multisets
1552 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1553 p.update(e=1, f=-1, g=0)
1554 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1555 q.update(h=1, i=-1, j=0)
1556 for inplace_op, regular_op in [
1557 (Counter.__iadd__, Counter.__add__),
1558 (Counter.__isub__, Counter.__sub__),
1559 (Counter.__ior__, Counter.__or__),
1560 (Counter.__iand__, Counter.__and__),
1561 ]:
1562 c = p.copy()
1563 c_id = id(c)
1564 regular_result = regular_op(c, q)
1565 inplace_result = inplace_op(c, q)
1566 self.assertEqual(inplace_result, regular_result)
1567 self.assertEqual(id(inplace_result), c_id)
1568
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001569 def test_subtract(self):
1570 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1571 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1572 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1573 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1574 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1575 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1576 c = Counter('aaabbcd')
1577 c.subtract('aaaabbcce')
1578 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001579
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001580 c = Counter()
1581 c.subtract(self=42)
1582 self.assertEqual(list(c.items()), [('self', -42)])
1583 c = Counter()
1584 c.subtract(iterable=42)
1585 self.assertEqual(list(c.items()), [('iterable', -42)])
1586 self.assertRaises(TypeError, Counter().subtract, 42)
1587 self.assertRaises(TypeError, Counter().subtract, {}, {})
1588 self.assertRaises(TypeError, Counter.subtract)
1589
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001590 def test_unary(self):
1591 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1592 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1593 self.assertEqual(dict(-c), dict(a=5))
1594
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001595 def test_repr_nonsortable(self):
1596 c = Counter(a=2, b=None)
1597 r = repr(c)
1598 self.assertIn("'a': 2", r)
1599 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001600
Raymond Hettinger426e0522011-01-03 02:12:02 +00001601 def test_helper_function(self):
1602 # two paths, one for real dicts and one for other mappings
1603 elems = list('abracadabra')
1604
1605 d = dict()
1606 _count_elements(d, elems)
1607 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1608
1609 m = OrderedDict()
1610 _count_elements(m, elems)
1611 self.assertEqual(m,
1612 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1613
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001614 # test fidelity to the pure python version
1615 c = CounterSubclassWithSetItem('abracadabra')
1616 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001617 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001618 c = CounterSubclassWithGet('abracadabra')
1619 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001620 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001621
Raymond Hettinger499e1932011-02-23 07:56:53 +00001622
1623################################################################################
1624### OrderedDict
1625################################################################################
1626
Eric Snow47db7172015-05-29 22:21:39 -06001627py_coll = import_fresh_module('collections', blocked=['_collections'])
1628c_coll = import_fresh_module('collections', fresh=['_collections'])
1629
1630
1631@contextlib.contextmanager
1632def replaced_module(name, replacement):
1633 original_module = sys.modules[name]
1634 sys.modules[name] = replacement
1635 try:
1636 yield
1637 finally:
1638 sys.modules[name] = original_module
1639
1640
1641class OrderedDictTests:
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001642
1643 def test_init(self):
Eric Snow47db7172015-05-29 22:21:39 -06001644 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001645 with self.assertRaises(TypeError):
1646 OrderedDict([('a', 1), ('b', 2)], None) # too many args
1647 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1648 self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
1649 self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
1650 self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
1651 self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
1652 c=3, e=5).items()), pairs) # mixed input
1653
1654 # make sure no positional args conflict with possible kwdargs
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001655 self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)])
1656 self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)])
1657 self.assertRaises(TypeError, OrderedDict, 42)
1658 self.assertRaises(TypeError, OrderedDict, (), ())
1659 self.assertRaises(TypeError, OrderedDict.__init__)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001660
1661 # Make sure that direct calls to __init__ do not clear previous contents
1662 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1663 d.__init__([('e', 5), ('f', 6)], g=7, d=4)
1664 self.assertEqual(list(d.items()),
1665 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1666
1667 def test_update(self):
Eric Snow47db7172015-05-29 22:21:39 -06001668 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001669 with self.assertRaises(TypeError):
1670 OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
1671 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1672 od = OrderedDict()
1673 od.update(dict(pairs))
1674 self.assertEqual(sorted(od.items()), pairs) # dict input
1675 od = OrderedDict()
1676 od.update(**dict(pairs))
1677 self.assertEqual(sorted(od.items()), pairs) # kwds input
1678 od = OrderedDict()
1679 od.update(pairs)
1680 self.assertEqual(list(od.items()), pairs) # pairs input
1681 od = OrderedDict()
1682 od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
1683 self.assertEqual(list(od.items()), pairs) # mixed input
1684
Mark Dickinsonb214e902010-07-11 18:53:06 +00001685 # Issue 9137: Named argument called 'other' or 'self'
1686 # shouldn't be treated specially.
1687 od = OrderedDict()
1688 od.update(self=23)
1689 self.assertEqual(list(od.items()), [('self', 23)])
1690 od = OrderedDict()
1691 od.update(other={})
1692 self.assertEqual(list(od.items()), [('other', {})])
1693 od = OrderedDict()
1694 od.update(red=5, blue=6, other=7, self=8)
1695 self.assertEqual(sorted(list(od.items())),
1696 [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
1697
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001698 # Make sure that direct calls to update do not clear previous contents
1699 # add that updates items are not moved to the end
1700 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1701 d.update([('e', 5), ('f', 6)], g=7, d=4)
1702 self.assertEqual(list(d.items()),
1703 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1704
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001705 self.assertRaises(TypeError, OrderedDict().update, 42)
1706 self.assertRaises(TypeError, OrderedDict().update, (), ())
1707 self.assertRaises(TypeError, OrderedDict.update)
1708
Eric Snow47db7172015-05-29 22:21:39 -06001709 self.assertRaises(TypeError, OrderedDict().update, 42)
1710 self.assertRaises(TypeError, OrderedDict().update, (), ())
1711 self.assertRaises(TypeError, OrderedDict.update)
1712
Eric Snowac02ef32015-06-02 20:42:14 -06001713 def test_fromkeys(self):
1714 OrderedDict = self.module.OrderedDict
1715 od = OrderedDict.fromkeys('abc')
1716 self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
1717 od = OrderedDict.fromkeys('abc', value=None)
1718 self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
1719 od = OrderedDict.fromkeys('abc', value=0)
1720 self.assertEqual(list(od.items()), [(c, 0) for c in 'abc'])
1721
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001722 def test_abc(self):
Eric Snow47db7172015-05-29 22:21:39 -06001723 OrderedDict = self.module.OrderedDict
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001724 self.assertIsInstance(OrderedDict(), MutableMapping)
1725 self.assertTrue(issubclass(OrderedDict, MutableMapping))
1726
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001727 def test_clear(self):
Eric Snow47db7172015-05-29 22:21:39 -06001728 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001729 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1730 shuffle(pairs)
1731 od = OrderedDict(pairs)
1732 self.assertEqual(len(od), len(pairs))
1733 od.clear()
1734 self.assertEqual(len(od), 0)
1735
1736 def test_delitem(self):
Eric Snow47db7172015-05-29 22:21:39 -06001737 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001738 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1739 od = OrderedDict(pairs)
1740 del od['a']
Benjamin Peterson577473f2010-01-19 00:09:57 +00001741 self.assertNotIn('a', od)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001742 with self.assertRaises(KeyError):
1743 del od['a']
1744 self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
1745
1746 def test_setitem(self):
Eric Snow47db7172015-05-29 22:21:39 -06001747 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001748 od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
1749 od['c'] = 10 # existing element
1750 od['f'] = 20 # new element
1751 self.assertEqual(list(od.items()),
1752 [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
1753
1754 def test_iterators(self):
Eric Snow47db7172015-05-29 22:21:39 -06001755 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001756 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1757 shuffle(pairs)
1758 od = OrderedDict(pairs)
1759 self.assertEqual(list(od), [t[0] for t in pairs])
1760 self.assertEqual(list(od.keys()), [t[0] for t in pairs])
1761 self.assertEqual(list(od.values()), [t[1] for t in pairs])
1762 self.assertEqual(list(od.items()), pairs)
1763 self.assertEqual(list(reversed(od)),
1764 [t[0] for t in reversed(pairs)])
Serhiy Storchaka578c9212014-04-04 15:19:36 +03001765 self.assertEqual(list(reversed(od.keys())),
1766 [t[0] for t in reversed(pairs)])
1767 self.assertEqual(list(reversed(od.values())),
1768 [t[1] for t in reversed(pairs)])
1769 self.assertEqual(list(reversed(od.items())), list(reversed(pairs)))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001770
Raymond Hettinger53d2c412014-05-03 21:58:45 -07001771 def test_detect_deletion_during_iteration(self):
Eric Snow47db7172015-05-29 22:21:39 -06001772 OrderedDict = self.module.OrderedDict
Raymond Hettinger53d2c412014-05-03 21:58:45 -07001773 od = OrderedDict.fromkeys('abc')
1774 it = iter(od)
1775 key = next(it)
1776 del od[key]
1777 with self.assertRaises(Exception):
1778 # Note, the exact exception raised is not guaranteed
1779 # The only guarantee that the next() will not succeed
1780 next(it)
1781
Eric Snow47db7172015-05-29 22:21:39 -06001782 def test_sorted_iterators(self):
1783 OrderedDict = self.module.OrderedDict
1784 with self.assertRaises(TypeError):
1785 OrderedDict([('a', 1), ('b', 2)], None)
1786 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1787 od = OrderedDict(pairs)
1788 self.assertEqual(sorted(od), [t[0] for t in pairs])
1789 self.assertEqual(sorted(od.keys()), [t[0] for t in pairs])
1790 self.assertEqual(sorted(od.values()), [t[1] for t in pairs])
1791 self.assertEqual(sorted(od.items()), pairs)
1792 self.assertEqual(sorted(reversed(od)),
1793 sorted([t[0] for t in reversed(pairs)]))
1794
Eric Snow67fb92e2015-05-30 11:43:36 -06001795 def test_iterators_empty(self):
1796 OrderedDict = self.module.OrderedDict
1797 od = OrderedDict()
1798 empty = []
1799 self.assertEqual(list(od), empty)
1800 self.assertEqual(list(od.keys()), empty)
1801 self.assertEqual(list(od.values()), empty)
1802 self.assertEqual(list(od.items()), empty)
1803 self.assertEqual(list(reversed(od)), empty)
1804 self.assertEqual(list(reversed(od.keys())), empty)
1805 self.assertEqual(list(reversed(od.values())), empty)
1806 self.assertEqual(list(reversed(od.items())), empty)
1807
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001808 def test_popitem(self):
Eric Snow47db7172015-05-29 22:21:39 -06001809 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001810 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1811 shuffle(pairs)
1812 od = OrderedDict(pairs)
1813 while pairs:
1814 self.assertEqual(od.popitem(), pairs.pop())
1815 with self.assertRaises(KeyError):
1816 od.popitem()
1817 self.assertEqual(len(od), 0)
1818
Eric Snow47db7172015-05-29 22:21:39 -06001819 def test_popitem_last(self):
1820 OrderedDict = self.module.OrderedDict
1821 pairs = [(i, i) for i in range(30)]
1822
1823 obj = OrderedDict(pairs)
1824 for i in range(8):
1825 obj.popitem(True)
1826 obj.popitem(True)
Eric Snowac02ef32015-06-02 20:42:14 -06001827 obj.popitem(last=True)
1828 self.assertEqual(len(obj), 20)
Eric Snow47db7172015-05-29 22:21:39 -06001829
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001830 def test_pop(self):
Eric Snow47db7172015-05-29 22:21:39 -06001831 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001832 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1833 shuffle(pairs)
1834 od = OrderedDict(pairs)
1835 shuffle(pairs)
1836 while pairs:
1837 k, v = pairs.pop()
1838 self.assertEqual(od.pop(k), v)
1839 with self.assertRaises(KeyError):
1840 od.pop('xyz')
1841 self.assertEqual(len(od), 0)
1842 self.assertEqual(od.pop(k, 12345), 12345)
1843
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001844 # make sure pop still works when __missing__ is defined
1845 class Missing(OrderedDict):
1846 def __missing__(self, key):
1847 return 0
1848 m = Missing(a=1)
1849 self.assertEqual(m.pop('b', 5), 5)
1850 self.assertEqual(m.pop('a', 6), 1)
1851 self.assertEqual(m.pop('a', 6), 6)
Eric Snowac02ef32015-06-02 20:42:14 -06001852 self.assertEqual(m.pop('a', default=6), 6)
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001853 with self.assertRaises(KeyError):
1854 m.pop('a')
1855
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001856 def test_equality(self):
Eric Snow47db7172015-05-29 22:21:39 -06001857 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001858 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1859 shuffle(pairs)
1860 od1 = OrderedDict(pairs)
1861 od2 = OrderedDict(pairs)
1862 self.assertEqual(od1, od2) # same order implies equality
1863 pairs = pairs[2:] + pairs[:2]
1864 od2 = OrderedDict(pairs)
1865 self.assertNotEqual(od1, od2) # different order implies inequality
1866 # comparison to regular dict is not order sensitive
1867 self.assertEqual(od1, dict(od2))
1868 self.assertEqual(dict(od2), od1)
1869 # different length implied inequality
1870 self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
1871
1872 def test_copying(self):
Eric Snow47db7172015-05-29 22:21:39 -06001873 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001874 # Check that ordered dicts are copyable, deepcopyable, picklable,
1875 # and have a repr/eval round-trip
1876 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1877 od = OrderedDict(pairs)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001878 def check(dup):
1879 msg = "\ncopy: %s\nod: %s" % (dup, od)
1880 self.assertIsNot(dup, od, msg)
1881 self.assertEqual(dup, od)
Eric Snow47db7172015-05-29 22:21:39 -06001882 self.assertEqual(list(dup.items()), list(od.items()))
1883 self.assertEqual(len(dup), len(od))
1884 self.assertEqual(type(dup), type(od))
Serhiy Storchakabad12572014-12-15 14:03:42 +02001885 check(od.copy())
1886 check(copy.copy(od))
1887 check(copy.deepcopy(od))
Eric Snow47db7172015-05-29 22:21:39 -06001888 # pickle directly pulls the module, so we have to fake it
1889 with replaced_module('collections', self.module):
1890 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1891 with self.subTest(proto=proto):
1892 check(pickle.loads(pickle.dumps(od, proto)))
Serhiy Storchakabad12572014-12-15 14:03:42 +02001893 check(eval(repr(od)))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001894 update_test = OrderedDict()
1895 update_test.update(od)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001896 check(update_test)
1897 check(OrderedDict(od))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001898
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001899 def test_yaml_linkage(self):
Eric Snow47db7172015-05-29 22:21:39 -06001900 OrderedDict = self.module.OrderedDict
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001901 # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
1902 # In yaml, lists are native but tuples are not.
1903 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1904 od = OrderedDict(pairs)
1905 # yaml.dump(od) -->
1906 # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001907 self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001908
Raymond Hettingerb2121572009-03-03 22:50:04 +00001909 def test_reduce_not_too_fat(self):
Eric Snow47db7172015-05-29 22:21:39 -06001910 OrderedDict = self.module.OrderedDict
Raymond Hettingerb2121572009-03-03 22:50:04 +00001911 # do not save instance dictionary if not needed
1912 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1913 od = OrderedDict(pairs)
Serhiy Storchaka3ee6dab2013-05-21 12:47:57 +03001914 self.assertIsNone(od.__reduce__()[2])
Raymond Hettingerb2121572009-03-03 22:50:04 +00001915 od.x = 10
Serhiy Storchaka3ee6dab2013-05-21 12:47:57 +03001916 self.assertIsNotNone(od.__reduce__()[2])
1917
1918 def test_pickle_recursive(self):
Eric Snow47db7172015-05-29 22:21:39 -06001919 OrderedDict = self.module.OrderedDict
Serhiy Storchaka3ee6dab2013-05-21 12:47:57 +03001920 od = OrderedDict()
1921 od[1] = od
Eric Snow47db7172015-05-29 22:21:39 -06001922
1923 # pickle directly pulls the module, so we have to fake it
1924 with replaced_module('collections', self.module):
1925 for proto in range(-1, pickle.HIGHEST_PROTOCOL + 1):
1926 dup = pickle.loads(pickle.dumps(od, proto))
1927 self.assertIsNot(dup, od)
1928 self.assertEqual(list(dup.keys()), [1])
1929 self.assertIs(dup[1], dup)
Raymond Hettingerb2121572009-03-03 22:50:04 +00001930
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001931 def test_repr(self):
Eric Snow47db7172015-05-29 22:21:39 -06001932 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001933 od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
1934 self.assertEqual(repr(od),
1935 "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
1936 self.assertEqual(eval(repr(od)), od)
1937 self.assertEqual(repr(OrderedDict()), "OrderedDict()")
1938
Raymond Hettingerdc08a142010-09-12 05:15:22 +00001939 def test_repr_recursive(self):
Eric Snow47db7172015-05-29 22:21:39 -06001940 OrderedDict = self.module.OrderedDict
Raymond Hettingerdc08a142010-09-12 05:15:22 +00001941 # See issue #9826
1942 od = OrderedDict.fromkeys('abc')
1943 od['x'] = od
1944 self.assertEqual(repr(od),
1945 "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
1946
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001947 def test_setdefault(self):
Eric Snow47db7172015-05-29 22:21:39 -06001948 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001949 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1950 shuffle(pairs)
1951 od = OrderedDict(pairs)
1952 pair_order = list(od.items())
1953 self.assertEqual(od.setdefault('a', 10), 3)
1954 # make sure order didn't change
1955 self.assertEqual(list(od.items()), pair_order)
1956 self.assertEqual(od.setdefault('x', 10), 10)
1957 # make sure 'x' is added to the end
1958 self.assertEqual(list(od.items())[-1], ('x', 10))
Eric Snowac02ef32015-06-02 20:42:14 -06001959 self.assertEqual(od.setdefault('g', default=9), 9)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001960
Raymond Hettingera673b1f2010-12-31 23:16:17 +00001961 # make sure setdefault still works when __missing__ is defined
1962 class Missing(OrderedDict):
1963 def __missing__(self, key):
1964 return 0
1965 self.assertEqual(Missing().setdefault(5, 9), 9)
1966
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001967 def test_reinsert(self):
Eric Snow47db7172015-05-29 22:21:39 -06001968 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001969 # Given insert a, insert b, delete a, re-insert a,
1970 # verify that a is now later than b.
1971 od = OrderedDict()
1972 od['a'] = 1
1973 od['b'] = 2
1974 del od['a']
Eric Snow47db7172015-05-29 22:21:39 -06001975 self.assertEqual(list(od.items()), [('b', 2)])
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001976 od['a'] = 1
1977 self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
1978
Raymond Hettingerf45abc92010-09-06 21:26:09 +00001979 def test_move_to_end(self):
Eric Snow47db7172015-05-29 22:21:39 -06001980 OrderedDict = self.module.OrderedDict
Raymond Hettingerf45abc92010-09-06 21:26:09 +00001981 od = OrderedDict.fromkeys('abcde')
1982 self.assertEqual(list(od), list('abcde'))
1983 od.move_to_end('c')
1984 self.assertEqual(list(od), list('abdec'))
1985 od.move_to_end('c', 0)
1986 self.assertEqual(list(od), list('cabde'))
1987 od.move_to_end('c', 0)
1988 self.assertEqual(list(od), list('cabde'))
1989 od.move_to_end('e')
1990 self.assertEqual(list(od), list('cabde'))
Eric Snowac02ef32015-06-02 20:42:14 -06001991 od.move_to_end('b', last=False)
1992 self.assertEqual(list(od), list('bcade'))
Raymond Hettingerf45abc92010-09-06 21:26:09 +00001993 with self.assertRaises(KeyError):
1994 od.move_to_end('x')
Eric Snow47db7172015-05-29 22:21:39 -06001995 with self.assertRaises(KeyError):
1996 od.move_to_end('x', 0)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001997
Raymond Hettinger35c87f22010-09-16 19:10:17 +00001998 def test_sizeof(self):
Eric Snow47db7172015-05-29 22:21:39 -06001999 OrderedDict = self.module.OrderedDict
Raymond Hettinger35c87f22010-09-16 19:10:17 +00002000 # Wimpy test: Just verify the reported size is larger than a regular dict
2001 d = dict(a=1)
2002 od = OrderedDict(**d)
2003 self.assertGreater(sys.getsizeof(od), sys.getsizeof(d))
2004
Raymond Hettingerc074e9d2015-05-26 01:47:58 -07002005 def test_views(self):
Eric Snowe39facf2015-05-30 13:24:54 -06002006 OrderedDict = self.module.OrderedDict
Raymond Hettingerc074e9d2015-05-26 01:47:58 -07002007 # See http://bugs.python.org/issue24286
2008 s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split()
2009 od = OrderedDict.fromkeys(s)
2010 self.assertEqual(od.keys(), dict(od).keys())
2011 self.assertEqual(od.items(), dict(od).items())
2012
Raymond Hettinger32062e92011-01-01 22:38:00 +00002013 def test_override_update(self):
Eric Snow47db7172015-05-29 22:21:39 -06002014 OrderedDict = self.module.OrderedDict
Raymond Hettinger32062e92011-01-01 22:38:00 +00002015 # Verify that subclasses can override update() without breaking __init__()
2016 class MyOD(OrderedDict):
2017 def update(self, *args, **kwds):
2018 raise Exception()
2019 items = [('a', 1), ('c', 3), ('b', 2)]
2020 self.assertEqual(list(MyOD(items).items()), items)
2021
Eric Snow47db7172015-05-29 22:21:39 -06002022
2023class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
2024
2025 module = py_coll
2026
2027
2028@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
2029class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
2030
2031 module = c_coll
2032
2033 def test_delitem_hash_collision(self):
2034 OrderedDict = self.module.OrderedDict
2035
2036 class Key:
2037 def __init__(self, hash):
2038 self._hash = hash
2039 self.value = str(id(self))
2040 def __hash__(self):
2041 return self._hash
2042 def __eq__(self, other):
2043 try:
2044 return self.value == other.value
2045 except AttributeError:
2046 return False
2047 def __repr__(self):
2048 return self.value
2049
2050 def blocking_hash(hash):
2051 # See the collision-handling in lookdict (in Objects/dictobject.c).
2052 MINSIZE = 8
2053 i = (hash & MINSIZE-1)
2054 return (i << 2) + i + hash + 1
2055
2056 COLLIDING = 1
2057
2058 key = Key(COLLIDING)
2059 colliding = Key(COLLIDING)
2060 blocking = Key(blocking_hash(COLLIDING))
2061
2062 od = OrderedDict()
2063 od[key] = ...
2064 od[blocking] = ...
2065 od[colliding] = ...
2066 od['after'] = ...
2067
2068 del od[blocking]
2069 del od[colliding]
2070 self.assertEqual(list(od.items()), [(key, ...), ('after', ...)])
2071
Eric Snow4fabf022015-06-04 00:09:56 -06002072 def test_key_change_during_iteration(self):
2073 OrderedDict = self.module.OrderedDict
2074
2075 od = OrderedDict.fromkeys('abcde')
2076 self.assertEqual(list(od), list('abcde'))
2077 with self.assertRaises(RuntimeError):
2078 for i, k in enumerate(od):
2079 od.move_to_end(k)
2080 self.assertLess(i, 5)
2081 with self.assertRaises(RuntimeError):
2082 for k in od:
2083 od['f'] = None
2084 with self.assertRaises(RuntimeError):
2085 for k in od:
2086 del od['c']
2087 self.assertEqual(list(od), list('bdeaf'))
2088
Eric Snowa762af72015-06-01 22:59:08 -06002089 def test_issue24347(self):
2090 OrderedDict = self.module.OrderedDict
2091
2092 class Key:
2093 def __hash__(self):
2094 return randrange(100000)
2095
2096 od = OrderedDict()
2097 for i in range(100):
2098 key = Key()
2099 od[key] = i
2100
2101 # These should not crash.
2102 with self.assertRaises(KeyError):
2103 repr(od)
2104 with self.assertRaises(KeyError):
2105 od.copy()
2106
Eric Snowd1719752015-06-01 23:12:13 -06002107 def test_issue24348(self):
2108 OrderedDict = self.module.OrderedDict
2109
2110 class Key:
2111 def __hash__(self):
2112 return 1
2113
2114 od = OrderedDict()
2115 od[Key()] = 0
2116 # This should not crash.
2117 od.popitem()
2118
Eric Snow8c7f9552015-08-07 17:45:12 -06002119 def test_issue24667(self):
2120 """
2121 dict resizes after a certain number of insertion operations,
2122 whether or not there were deletions that freed up slots in the
2123 hash table. During fast node lookup, OrderedDict must correctly
2124 respond to all resizes, even if the current "size" is the same
2125 as the old one. We verify that here by forcing a dict resize
2126 on a sparse odict and then perform an operation that should
2127 trigger an odict resize (e.g. popitem). One key aspect here is
2128 that we will keep the size of the odict the same at each popitem
2129 call. This verifies that we handled the dict resize properly.
2130 """
2131 OrderedDict = self.module.OrderedDict
2132
2133 od = OrderedDict()
2134 for c0 in '0123456789ABCDEF':
2135 for c1 in '0123456789ABCDEF':
2136 if len(od) == 4:
2137 # This should not raise a KeyError.
2138 od.popitem(last=False)
2139 key = c0 + c1
2140 od[key] = key
2141
Eric Snow47db7172015-05-29 22:21:39 -06002142
2143class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
2144
2145 @classmethod
2146 def setUpClass(cls):
2147 cls.type2test = py_coll.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002148
Raymond Hettingerdc879f02009-03-19 20:30:56 +00002149 def test_popitem(self):
2150 d = self._empty_mapping()
2151 self.assertRaises(KeyError, d.popitem)
2152
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002153
Eric Snow47db7172015-05-29 22:21:39 -06002154@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
2155class CPythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
2156
2157 @classmethod
2158 def setUpClass(cls):
2159 cls.type2test = c_coll.OrderedDict
2160
2161 def test_popitem(self):
2162 d = self._empty_mapping()
2163 self.assertRaises(KeyError, d.popitem)
2164
2165
2166class PurePythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
2167
2168 @classmethod
2169 def setUpClass(cls):
2170 class MyOrderedDict(py_coll.OrderedDict):
2171 pass
2172 cls.type2test = MyOrderedDict
2173
2174 def test_popitem(self):
2175 d = self._empty_mapping()
2176 self.assertRaises(KeyError, d.popitem)
2177
2178
2179@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
2180class CPythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
2181
2182 @classmethod
2183 def setUpClass(cls):
2184 class MyOrderedDict(c_coll.OrderedDict):
2185 pass
2186 cls.type2test = MyOrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002187
Raymond Hettingerdc879f02009-03-19 20:30:56 +00002188 def test_popitem(self):
2189 d = self._empty_mapping()
2190 self.assertRaises(KeyError, d.popitem)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002191
2192
Raymond Hettinger499e1932011-02-23 07:56:53 +00002193################################################################################
2194### Run tests
2195################################################################################
2196
Christian Heimes25bb7832008-01-11 16:17:00 +00002197import doctest, collections
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002198
Guido van Rossumd8faa362007-04-27 19:54:29 +00002199def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00002200 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002201 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00002202 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06002203 PurePythonOrderedDictTests, CPythonOrderedDictTests,
2204 PurePythonGeneralMappingTests, CPythonGeneralMappingTests,
2205 PurePythonSubclassMappingTests, CPythonSubclassMappingTests,
2206 TestUserObjects,
2207 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002208 support.run_unittest(*test_classes)
2209 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002210
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002211
Guido van Rossumd8faa362007-04-27 19:54:29 +00002212if __name__ == "__main__":
2213 test_main(verbose=True)