blob: 8850e8bc136893139ae200addbeb5f7a1783e722 [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
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -07004from test.support import TESTFN, forget, unlink
Raymond Hettinger2d32f632009-03-02 21:24:57 +00005import inspect
Benjamin Petersonee8712c2008-05-20 21:35:26 +00006from test import support
Raymond Hettinger426e0522011-01-03 02:12:02 +00007from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger2d32f632009-03-02 21:24:57 +00008from test import mapping_tests
Georg Brandlc28e1fa2008-06-10 19:20:26 +00009import pickle, copy
Raymond Hettinger2d32f632009-03-02 21:24:57 +000010from random import randrange, shuffle
Raymond Hettinger499b2ee2009-05-27 01:53:46 +000011import keyword
12import re
R. David Murray378c0cf2010-02-24 01:46:21 +000013import sys
Raymond Hettinger57d1a882011-02-23 00:46:28 +000014from collections import UserDict
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000015from collections import ChainMap
Raymond Hettinger57d1a882011-02-23 00:46:28 +000016from collections.abc import Hashable, Iterable, Iterator
17from collections.abc import Sized, Container, Callable
18from collections.abc import Set, MutableSet
19from collections.abc import Mapping, MutableMapping, KeysView, ItemsView
20from collections.abc import Sequence, MutableSequence
21from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000022
Raymond Hettinger499e1932011-02-23 07:56:53 +000023
24################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000025### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000026################################################################################
27
28class TestChainMap(unittest.TestCase):
29
30 def test_basics(self):
31 c = ChainMap()
32 c['a'] = 1
33 c['b'] = 2
34 d = c.new_child()
35 d['b'] = 20
36 d['c'] = 30
37 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
38 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
39 self.assertEqual(len(d), 3) # check len
40 for key in 'abc': # check contains
41 self.assertIn(key, d)
42 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
43 self.assertEqual(d.get(k, 100), v)
44
45 del d['b'] # unmask a value
46 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
47 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
48 self.assertEqual(len(d), 3) # check len
49 for key in 'abc': # check contains
50 self.assertIn(key, d)
51 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
52 self.assertEqual(d.get(k, 100), v)
53 self.assertIn(repr(d), [ # check repr
54 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
55 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
56 ])
57
58 for e in d.copy(), copy.copy(d): # check shallow copies
59 self.assertEqual(d, e)
60 self.assertEqual(d.maps, e.maps)
61 self.assertIsNot(d, e)
62 self.assertIsNot(d.maps[0], e.maps[0])
63 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
64 self.assertIs(m1, m2)
65
66 for e in [pickle.loads(pickle.dumps(d)),
67 copy.deepcopy(d),
68 eval(repr(d))
69 ]: # check deep copies
70 self.assertEqual(d, e)
71 self.assertEqual(d.maps, e.maps)
72 self.assertIsNot(d, e)
73 for m1, m2 in zip(d.maps, e.maps):
74 self.assertIsNot(m1, m2, e)
75
Raymond Hettingerd0321312011-02-26 06:53:58 +000076 f = d.new_child()
77 f['b'] = 5
78 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
79 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
80 self.assertEqual(f['b'], 5) # find first in chain
81 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +000082
83 def test_contructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +000084 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +000085 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
86
Raymond Hettingerd0321312011-02-26 06:53:58 +000087 def test_bool(self):
88 self.assertFalse(ChainMap())
89 self.assertFalse(ChainMap({}, {}))
90 self.assertTrue(ChainMap({1:2}, {}))
91 self.assertTrue(ChainMap({}, {1:2}))
92
Raymond Hettinger499e1932011-02-23 07:56:53 +000093 def test_missing(self):
94 class DefaultChainMap(ChainMap):
95 def __missing__(self, key):
96 return 999
97 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
98 for k, v in dict(a=1, b=2, c=30, d=999).items():
99 self.assertEqual(d[k], v) # check __getitem__ w/missing
100 for k, v in dict(a=1, b=2, c=30, d=77).items():
101 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
102 for k, v in dict(a=True, b=True, c=True, d=False).items():
103 self.assertEqual(k in d, v) # check __contains__ w/missing
104 self.assertEqual(d.pop('a', 1001), 1, d)
105 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
106 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
107 with self.assertRaises(KeyError):
108 d.popitem()
109
110 def test_dict_coercion(self):
111 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
112 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
113 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
114
115
116################################################################################
117### Named Tuples
118################################################################################
119
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000120TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000121
122class TestNamedTuple(unittest.TestCase):
123
124 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000125 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000126 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000127 self.assertEqual(Point.__slots__, ())
128 self.assertEqual(Point.__module__, __name__)
129 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000130 self.assertEqual(Point._fields, ('x', 'y'))
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700131 self.assertIn('class Point(tuple)', Point._source)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000132
133 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
134 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
135 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
136
137 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
138 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
139 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000140 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000141 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
142
143 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000144 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000145
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000146 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000147 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000148 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000149 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000150
Christian Heimesfaf2f632008-01-06 16:59:19 +0000151 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
152 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
153
R. David Murray378c0cf2010-02-24 01:46:21 +0000154 @unittest.skipIf(sys.flags.optimize >= 2,
155 "Docstrings are omitted with -O2 and above")
156 def test_factory_doc_attr(self):
157 Point = namedtuple('Point', 'x y')
158 self.assertEqual(Point.__doc__, 'Point(x, y)')
159
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000160 def test_name_fixer(self):
161 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000162 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
163 [('abc', 'class'), ('abc', '_1')], # field has keyword
164 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
165 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
166 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
167 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000168 ]:
169 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
170
Guido van Rossumd8faa362007-04-27 19:54:29 +0000171 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000172 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000173 p = Point(11, 22)
174 self.assertEqual(p, Point(x=11, y=22))
175 self.assertEqual(p, Point(11, y=22))
176 self.assertEqual(p, Point(y=22, x=11))
177 self.assertEqual(p, Point(*(11, 22)))
178 self.assertEqual(p, Point(**dict(x=11, y=22)))
179 self.assertRaises(TypeError, Point, 1) # too few args
180 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
181 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
182 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
183 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000184 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000185 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000186 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
187 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
188 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Raymond Hettinger3d890572011-06-02 23:40:24 -0700189 self.assertEqual(vars(p), p._asdict()) # verify that vars() works
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000190
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000191 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000192 p._replace(x=1, error=2)
193 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000194 pass
195 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000196 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000197
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000198 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000199 Point = namedtuple('Point', 'x, y')
200 p = Point(x=11, y=22)
201 self.assertEqual(repr(p), 'Point(x=11, y=22)')
202
203 # verify that fieldspec can be a non-string sequence
204 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000205 p = Point(x=11, y=22)
206 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000207
208 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000209 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000210 p = Point(11, 22)
211
Ezio Melottie9615932010-01-24 19:26:24 +0000212 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000213 self.assertEqual(p, (11, 22)) # matches a real tuple
214 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
215 self.assertEqual(list(p), [11, 22]) # coercable to a list
216 self.assertEqual(max(p), 22) # iterable
217 self.assertEqual(max(*p), 22) # star-able
218 x, y = p
219 self.assertEqual(p, (x, y)) # unpacks like a tuple
220 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
221 self.assertRaises(IndexError, p.__getitem__, 3)
222
223 self.assertEqual(p.x, x)
224 self.assertEqual(p.y, y)
225 self.assertRaises(AttributeError, eval, 'p.z', locals())
226
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000227 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000228 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000229 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000230 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000231 self.assertEqual(repr(Zero()), 'Zero()')
232 self.assertEqual(Zero()._asdict(), {})
233 self.assertEqual(Zero()._fields, ())
234
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000235 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000236 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000237 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000238 self.assertEqual(Dot(1).d, 1)
239 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
240 self.assertEqual(Dot(1)._asdict(), {'d':1})
241 self.assertEqual(Dot(1)._replace(d=999), (999,))
242 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000243
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000244 # n = 5000
Christian Heimes99170a52007-12-19 02:07:34 +0000245 n = 254 # SyntaxError: more than 255 arguments:
246 import string, random
Georg Brandlb533e262008-05-25 18:19:30 +0000247 names = list(set(''.join([random.choice(string.ascii_letters)
248 for j in range(10)]) for i in range(n)))
249 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000250 Big = namedtuple('Big', names)
251 b = Big(*range(n))
252 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000253 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000254 for pos, name in enumerate(names):
255 self.assertEqual(getattr(b, name), pos)
256 repr(b) # make sure repr() doesn't blow-up
257 d = b._asdict()
258 d_expected = dict(zip(names, range(n)))
259 self.assertEqual(d, d_expected)
260 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
261 b2_expected = list(range(n))
262 b2_expected[1] = 999
263 b2_expected[-5] = 42
264 self.assertEqual(b2, tuple(b2_expected))
265 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000266
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000267 def test_pickle(self):
268 p = TestNT(x=10, y=20, z=30)
269 for module in (pickle,):
270 loads = getattr(module, 'loads')
271 dumps = getattr(module, 'dumps')
272 for protocol in -1, 0, 1, 2:
273 q = loads(dumps(p, protocol))
274 self.assertEqual(p, q)
275 self.assertEqual(p._fields, q._fields)
276
277 def test_copy(self):
278 p = TestNT(x=10, y=20, z=30)
279 for copier in copy.copy, copy.deepcopy:
280 q = copier(p)
281 self.assertEqual(p, q)
282 self.assertEqual(p._fields, q._fields)
283
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000284 def test_name_conflicts(self):
285 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
286 # failed when used as field names. Test to make sure these now work.
287 T = namedtuple('T', 'itemgetter property self cls tuple')
288 t = T(1, 2, 3, 4, 5)
289 self.assertEqual(t, (1,2,3,4,5))
290 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
291 self.assertEqual(newt, (10,20,30,40,50))
292
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000293 # Broader test of all interesting names in a template
294 with support.captured_stdout() as template:
295 T = namedtuple('T', 'x', verbose=True)
296 words = set(re.findall('[A-Za-z]+', template.getvalue()))
297 words -= set(keyword.kwlist)
298 T = namedtuple('T', words)
299 # test __new__
300 values = tuple(range(len(words)))
301 t = T(*values)
302 self.assertEqual(t, values)
303 t = T(**dict(zip(T._fields, values)))
304 self.assertEqual(t, values)
305 # test _make
306 t = T._make(values)
307 self.assertEqual(t, values)
308 # exercise __repr__
309 repr(t)
310 # test _asdict
311 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
312 # test _replace
313 t = T._make(values)
314 newvalues = tuple(v*10 for v in values)
315 newt = t._replace(**dict(zip(T._fields, newvalues)))
316 self.assertEqual(newt, newvalues)
317 # test _fields
318 self.assertEqual(T._fields, tuple(words))
319 # test __getnewargs__
320 self.assertEqual(t.__getnewargs__(), values)
321
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000322 def test_repr(self):
323 with support.captured_stdout() as template:
324 A = namedtuple('A', 'x', verbose=True)
325 self.assertEqual(repr(A(1)), 'A(x=1)')
326 # repr should show the name of the subclass
327 class B(A):
328 pass
329 self.assertEqual(repr(B(1)), 'B(x=1)')
330
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700331 def test_source(self):
332 # verify that _source can be run through exec()
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700333 tmp = namedtuple('NTColor', 'red green blue')
334 globals().pop('NTColor', None) # remove artifacts from other tests
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700335 exec(tmp._source, globals())
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700336 self.assertIn('NTColor', globals())
337 c = NTColor(10, 20, 30)
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700338 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700339 self.assertEqual(NTColor._fields, ('red', 'green', 'blue'))
340 globals().pop('NTColor', None) # clean-up after this test
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700341
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000342
Raymond Hettinger499e1932011-02-23 07:56:53 +0000343################################################################################
344### Abstract Base Classes
345################################################################################
346
Raymond Hettingerae650182009-01-28 23:33:59 +0000347class ABCTestCase(unittest.TestCase):
348
349 def validate_abstract_methods(self, abc, *names):
350 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
351
352 # everything should work will all required methods are present
353 C = type('C', (abc,), methodstubs)
354 C()
355
356 # instantiation should fail if a required method is missing
357 for name in names:
358 stubs = methodstubs.copy()
359 del stubs[name]
360 C = type('C', (abc,), stubs)
361 self.assertRaises(TypeError, C, name)
362
Florent Xiclunace153f62010-03-08 15:34:35 +0000363 def validate_isinstance(self, abc, name):
364 stub = lambda s, *args: 0
365
366 C = type('C', (object,), {'__hash__': None})
367 setattr(C, name, stub)
368 self.assertIsInstance(C(), abc)
369 self.assertTrue(issubclass(C, abc))
370
371 C = type('C', (object,), {'__hash__': None})
372 self.assertNotIsInstance(C(), abc)
373 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000374
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000375 def validate_comparison(self, instance):
376 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
377 operators = {}
378 for op in ops:
379 name = '__' + op + '__'
380 operators[name] = getattr(operator, name)
381
382 class Other:
383 def __init__(self):
384 self.right_side = False
385 def __eq__(self, other):
386 self.right_side = True
387 return True
388 __lt__ = __eq__
389 __gt__ = __eq__
390 __le__ = __eq__
391 __ge__ = __eq__
392 __ne__ = __eq__
393 __ror__ = __eq__
394 __rand__ = __eq__
395 __rxor__ = __eq__
396 __rsub__ = __eq__
397
398 for name, op in operators.items():
399 if not hasattr(instance, name):
400 continue
401 other = Other()
402 op(instance, other)
403 self.assertTrue(other.right_side,'Right side not called for %s.%s'
404 % (type(instance), name))
405
Raymond Hettingerae650182009-01-28 23:33:59 +0000406class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000407
408 def test_Hashable(self):
409 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000410 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000411 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000412 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000413 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000414 # Check some hashables
415 samples = [None,
416 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000417 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000418 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000419 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000420 ]
421 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000422 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000423 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000424 self.assertRaises(TypeError, Hashable)
425 # Check direct subclassing
426 class H(Hashable):
427 def __hash__(self):
428 return super().__hash__()
429 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000430 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000431 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000432 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000433
434 def test_Iterable(self):
435 # Check some non-iterables
436 non_samples = [None, 42, 3.14, 1j]
437 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000438 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000439 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000440 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000441 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000442 tuple(), list(), set(), frozenset(), dict(),
443 dict().keys(), dict().items(), dict().values(),
444 (lambda: (yield))(),
445 (x for x in []),
446 ]
447 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000448 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000449 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000450 # Check direct subclassing
451 class I(Iterable):
452 def __iter__(self):
453 return super().__iter__()
454 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000455 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000456 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000457 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000458
459 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000460 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000461 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000462 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000463 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000464 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000465 iter(tuple()), iter(list()), iter(dict()),
466 iter(set()), iter(frozenset()),
467 iter(dict().keys()), iter(dict().items()),
468 iter(dict().values()),
469 (lambda: (yield))(),
470 (x for x in []),
471 ]
472 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000473 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000474 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000475 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
476
477 # Issue 10565
478 class NextOnly:
479 def __next__(self):
480 yield 1
481 raise StopIteration
482 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000483
484 def test_Sized(self):
485 non_samples = [None, 42, 3.14, 1j,
486 (lambda: (yield))(),
487 (x for x in []),
488 ]
489 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000490 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000491 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000492 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000493 tuple(), list(), set(), frozenset(), dict(),
494 dict().keys(), dict().items(), dict().values(),
495 ]
496 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000497 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000498 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000499 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000500 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000501
502 def test_Container(self):
503 non_samples = [None, 42, 3.14, 1j,
504 (lambda: (yield))(),
505 (x for x in []),
506 ]
507 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000508 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000509 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000510 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000511 tuple(), list(), set(), frozenset(), dict(),
512 dict().keys(), dict().items(),
513 ]
514 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000515 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000516 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000517 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000518 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000519
520 def test_Callable(self):
521 non_samples = [None, 42, 3.14, 1j,
522 "", b"", (), [], {}, set(),
523 (lambda: (yield))(),
524 (x for x in []),
525 ]
526 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000527 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000528 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000529 samples = [lambda: None,
530 type, int, object,
531 len,
532 list.append, [].append,
533 ]
534 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000535 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000536 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000537 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000538 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000539
540 def test_direct_subclassing(self):
541 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
542 class C(B):
543 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000544 self.assertTrue(issubclass(C, B))
545 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000546
547 def test_registration(self):
548 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
549 class C:
550 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000551 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000552 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000553 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000554
Raymond Hettinger3f10a952009-04-01 19:05:50 +0000555class WithSet(MutableSet):
556
557 def __init__(self, it=()):
558 self.data = set(it)
559
560 def __len__(self):
561 return len(self.data)
562
563 def __iter__(self):
564 return iter(self.data)
565
566 def __contains__(self, item):
567 return item in self.data
568
569 def add(self, item):
570 self.data.add(item)
571
572 def discard(self, item):
573 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000574
Raymond Hettingerae650182009-01-28 23:33:59 +0000575class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000576
577 # XXX For now, we only test some virtual inheritance properties.
578 # We should also test the proper behavior of the collection ABCs
579 # as real base classes or mix-in classes.
580
581 def test_Set(self):
582 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +0000583 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000584 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +0000585 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000586 class MySet(Set):
587 def __contains__(self, x):
588 return False
589 def __len__(self):
590 return 0
591 def __iter__(self):
592 return iter([])
593 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000594
Benjamin Peterson41181742008-07-02 20:22:54 +0000595 def test_hash_Set(self):
596 class OneTwoThreeSet(Set):
597 def __init__(self):
598 self.contents = [1, 2, 3]
599 def __contains__(self, x):
600 return x in self.contents
601 def __len__(self):
602 return len(self.contents)
603 def __iter__(self):
604 return iter(self.contents)
605 def __hash__(self):
606 return self._hash()
607 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000608 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +0000609
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000610 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +0000611 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000612 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +0000613 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000614 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +0000615 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
616 'add', 'discard')
617
Raymond Hettinger3f10a952009-04-01 19:05:50 +0000618 def test_issue_5647(self):
619 # MutableSet.__iand__ mutated the set during iteration
620 s = WithSet('abcd')
621 s &= WithSet('cdef') # This used to fail
622 self.assertEqual(set(s), set('cd'))
623
Raymond Hettingerae650182009-01-28 23:33:59 +0000624 def test_issue_4920(self):
625 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000626 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +0000627 __slots__=['__s']
628 def __init__(self,items=None):
629 if items is None:
630 items=[]
631 self.__s=set(items)
632 def __contains__(self,v):
633 return v in self.__s
634 def __iter__(self):
635 return iter(self.__s)
636 def __len__(self):
637 return len(self.__s)
638 def add(self,v):
639 result=v not in self.__s
640 self.__s.add(v)
641 return result
642 def discard(self,v):
643 result=v in self.__s
644 self.__s.discard(v)
645 return result
646 def __repr__(self):
647 return "MySet(%s)" % repr(list(self))
648 s = MySet([5,43,2,1])
649 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000650
Daniel Stutzbach31da5b22010-08-24 20:49:57 +0000651 def test_issue8750(self):
652 empty = WithSet()
653 full = WithSet(range(10))
654 s = WithSet(full)
655 s -= s
656 self.assertEqual(s, empty)
657 s = WithSet(full)
658 s ^= s
659 self.assertEqual(s, empty)
660 s = WithSet(full)
661 s &= s
662 self.assertEqual(s, full)
663 s |= s
664 self.assertEqual(s, full)
665
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +0200666 def test_issue16373(self):
667 # Recursion error comparing comparable and noncomparable
668 # Set instances
669 class MyComparableSet(Set):
670 def __contains__(self, x):
671 return False
672 def __len__(self):
673 return 0
674 def __iter__(self):
675 return iter([])
676 class MyNonComparableSet(Set):
677 def __contains__(self, x):
678 return False
679 def __len__(self):
680 return 0
681 def __iter__(self):
682 return iter([])
683 def __le__(self, x):
684 return NotImplemented
685 def __lt__(self, x):
686 return NotImplemented
687
688 cs = MyComparableSet()
689 ncs = MyNonComparableSet()
690 with self.assertRaises(TypeError):
691 ncs < cs
692 with self.assertRaises(TypeError):
693 ncs <= cs
694 with self.assertRaises(TypeError):
695 cs > ncs
696 with self.assertRaises(TypeError):
697 cs >= ncs
698
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000699 def test_Mapping(self):
700 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +0000701 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000702 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +0000703 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
704 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000705 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000706 def __len__(self):
707 return 0
708 def __getitem__(self, i):
709 raise IndexError
710 def __iter__(self):
711 return iter(())
712 self.validate_comparison(MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000713
714 def test_MutableMapping(self):
715 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +0000716 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000717 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +0000718 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
719 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000720
Raymond Hettinger9117c752010-08-22 07:44:24 +0000721 def test_MutableMapping_subclass(self):
722 # Test issue 9214
723 mymap = UserDict()
724 mymap['red'] = 5
725 self.assertIsInstance(mymap.keys(), Set)
726 self.assertIsInstance(mymap.keys(), KeysView)
727 self.assertIsInstance(mymap.items(), Set)
728 self.assertIsInstance(mymap.items(), ItemsView)
729
730 mymap = UserDict()
731 mymap['red'] = 5
732 z = mymap.keys() | {'orange'}
733 self.assertIsInstance(z, set)
734 list(z)
735 mymap['blue'] = 7 # Shouldn't affect 'z'
736 self.assertEqual(sorted(z), ['orange', 'red'])
737
738 mymap = UserDict()
739 mymap['red'] = 5
740 z = mymap.items() | {('orange', 3)}
741 self.assertIsInstance(z, set)
742 list(z)
743 mymap['blue'] = 7 # Shouldn't affect 'z'
744 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
745
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000746 def test_Sequence(self):
747 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +0000748 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000749 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +0000750 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000751 self.assertTrue(issubclass(range, Sequence))
752 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +0000753 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
754 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000755
Guido van Rossumd05eb002007-11-21 22:26:24 +0000756 def test_ByteString(self):
757 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +0000758 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000759 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +0000760 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +0000761 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000762 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +0000763 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000764 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +0000765
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000766 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +0000767 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +0000768 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000769 self.assertFalse(issubclass(sample, MutableSequence))
Guido van Rossumd05eb002007-11-21 22:26:24 +0000770 for sample in [list, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +0000771 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000772 self.assertTrue(issubclass(sample, MutableSequence))
773 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +0000774 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
775 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000776
Eli Bendersky0716a572011-03-04 10:38:14 +0000777 def test_MutableSequence_mixins(self):
778 # Test the mixins of MutableSequence by creating a miminal concrete
779 # class inherited from it.
780 class MutableSequenceSubclass(MutableSequence):
781 def __init__(self):
782 self.lst = []
783
784 def __setitem__(self, index, value):
785 self.lst[index] = value
786
787 def __getitem__(self, index):
788 return self.lst[index]
789
790 def __len__(self):
791 return len(self.lst)
792
793 def __delitem__(self, index):
794 del self.lst[index]
795
796 def insert(self, index, value):
797 self.lst.insert(index, value)
798
799 mss = MutableSequenceSubclass()
800 mss.append(0)
801 mss.extend((1, 2, 3, 4))
802 self.assertEqual(len(mss), 5)
803 self.assertEqual(mss[3], 3)
804 mss.reverse()
805 self.assertEqual(mss[3], 1)
806 mss.pop()
807 self.assertEqual(len(mss), 4)
808 mss.remove(3)
809 self.assertEqual(len(mss), 3)
810 mss += (10, 20, 30)
811 self.assertEqual(len(mss), 6)
812 self.assertEqual(mss[-1], 30)
813 mss.clear()
814 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +0000815
816################################################################################
817### Counter
818################################################################################
819
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000820class TestCounter(unittest.TestCase):
821
822 def test_basics(self):
823 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000824 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
825 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +0000826 self.assertIsInstance(c, dict)
827 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000828 self.assertTrue(issubclass(Counter, dict))
829 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000830 self.assertEqual(len(c), 3)
831 self.assertEqual(sum(c.values()), 6)
832 self.assertEqual(sorted(c.values()), [1, 2, 3])
833 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
834 self.assertEqual(sorted(c), ['a', 'b', 'c'])
835 self.assertEqual(sorted(c.items()),
836 [('a', 3), ('b', 2), ('c', 1)])
837 self.assertEqual(c['b'], 2)
838 self.assertEqual(c['z'], 0)
839 self.assertEqual(c.__contains__('c'), True)
840 self.assertEqual(c.__contains__('z'), False)
841 self.assertEqual(c.get('b', 10), 2)
842 self.assertEqual(c.get('z', 10), 10)
843 self.assertEqual(c, dict(a=3, b=2, c=1))
844 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
845 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
846 for i in range(5):
847 self.assertEqual(c.most_common(i),
848 [('a', 3), ('b', 2), ('c', 1)][:i])
849 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
850 c['a'] += 1 # increment an existing value
851 c['b'] -= 2 # sub existing value to zero
852 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000853 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000854 c['d'] -= 2 # sub from a missing value
855 c['e'] = -5 # directly assign a missing value
856 c['f'] += 4 # add to a missing value
857 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
858 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
859 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000860 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000861 for i in range(3):
862 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000863 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000864 c.clear()
865 self.assertEqual(c, {})
866 self.assertEqual(repr(c), 'Counter()')
867 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
868 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000869 c.update(dict(a=5, b=3))
870 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000871 c.update(Counter('a' * 50 + 'b' * 30))
872 c.update() # test case with no args
873 c.__init__('a' * 500 + 'b' * 300)
874 c.__init__('cdc')
875 c.__init__()
876 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
877 self.assertEqual(c.setdefault('d', 5), 1)
878 self.assertEqual(c['d'], 1)
879 self.assertEqual(c.setdefault('e', 5), 5)
880 self.assertEqual(c['e'], 5)
881
882 def test_copying(self):
883 # Check that counters are copyable, deepcopyable, picklable, and
884 #have a repr/eval round-trip
885 words = Counter('which witch had which witches wrist watch'.split())
886 update_test = Counter()
887 update_test.update(words)
888 for i, dup in enumerate([
889 words.copy(),
890 copy.copy(words),
891 copy.deepcopy(words),
892 pickle.loads(pickle.dumps(words, 0)),
893 pickle.loads(pickle.dumps(words, 1)),
894 pickle.loads(pickle.dumps(words, 2)),
895 pickle.loads(pickle.dumps(words, -1)),
896 eval(repr(words)),
897 update_test,
898 Counter(words),
899 ]):
900 msg = (i, dup, words)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000901 self.assertTrue(dup is not words)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000902 self.assertEqual(dup, words)
903 self.assertEqual(len(dup), len(words))
904 self.assertEqual(type(dup), type(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000905
Raymond Hettinger1c746c22011-04-15 13:16:46 -0700906 def test_copy_subclass(self):
907 class MyCounter(Counter):
908 pass
909 c = MyCounter('slartibartfast')
910 d = c.copy()
911 self.assertEqual(d, c)
912 self.assertEqual(len(d), len(c))
913 self.assertEqual(type(d), type(c))
914
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000915 def test_conversions(self):
916 # Convert to: set, list, dict
917 s = 'she sells sea shells by the sea shore'
918 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
919 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
920 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
921 self.assertEqual(set(Counter(s)), set(s))
922
Raymond Hettinger670eaec2009-01-21 23:14:07 +0000923 def test_invariant_for_the_in_operator(self):
924 c = Counter(a=10, b=-2, c=0)
925 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000926 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000927 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +0000928
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000929 def test_multiset_operations(self):
930 # Verify that adding a zero counter will strip zeros and negatives
931 c = Counter(a=10, b=-2, c=0) + Counter()
932 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000933
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000934 elements = 'abcd'
935 for i in range(1000):
936 # test random pairs of multisets
937 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +0000938 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000939 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +0000940 q.update(h=1, i=-1, j=0)
941 for counterop, numberop in [
942 (Counter.__add__, lambda x, y: max(0, x+y)),
943 (Counter.__sub__, lambda x, y: max(0, x-y)),
944 (Counter.__or__, lambda x, y: max(0,x,y)),
945 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000946 ]:
947 result = counterop(p, q)
948 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +0000949 self.assertEqual(numberop(p[x], q[x]), result[x],
950 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000951 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000952 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000953
954 elements = 'abcdef'
955 for i in range(100):
956 # verify that random multisets with no repeats are exactly like sets
957 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
958 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
959 for counterop, setop in [
960 (Counter.__sub__, set.__sub__),
961 (Counter.__or__, set.__or__),
962 (Counter.__and__, set.__and__),
963 ]:
964 counter_result = counterop(p, q)
965 set_result = setop(set(p.elements()), set(q.elements()))
966 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000967
Raymond Hettingerbecd5682011-10-19 13:40:37 -0700968 def test_inplace_operations(self):
969 elements = 'abcd'
970 for i in range(1000):
971 # test random pairs of multisets
972 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
973 p.update(e=1, f=-1, g=0)
974 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
975 q.update(h=1, i=-1, j=0)
976 for inplace_op, regular_op in [
977 (Counter.__iadd__, Counter.__add__),
978 (Counter.__isub__, Counter.__sub__),
979 (Counter.__ior__, Counter.__or__),
980 (Counter.__iand__, Counter.__and__),
981 ]:
982 c = p.copy()
983 c_id = id(c)
984 regular_result = regular_op(c, q)
985 inplace_result = inplace_op(c, q)
986 self.assertEqual(inplace_result, regular_result)
987 self.assertEqual(id(inplace_result), c_id)
988
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000989 def test_subtract(self):
990 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
991 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
992 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
993 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
994 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
995 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
996 c = Counter('aaabbcd')
997 c.subtract('aaaabbcce')
998 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000999
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001000 def test_unary(self):
1001 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1002 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1003 self.assertEqual(dict(-c), dict(a=5))
1004
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001005 def test_repr_nonsortable(self):
1006 c = Counter(a=2, b=None)
1007 r = repr(c)
1008 self.assertIn("'a': 2", r)
1009 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001010
Raymond Hettinger426e0522011-01-03 02:12:02 +00001011 def test_helper_function(self):
1012 # two paths, one for real dicts and one for other mappings
1013 elems = list('abracadabra')
1014
1015 d = dict()
1016 _count_elements(d, elems)
1017 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1018
1019 m = OrderedDict()
1020 _count_elements(m, elems)
1021 self.assertEqual(m,
1022 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1023
Raymond Hettinger499e1932011-02-23 07:56:53 +00001024
1025################################################################################
1026### OrderedDict
1027################################################################################
1028
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001029class TestOrderedDict(unittest.TestCase):
1030
1031 def test_init(self):
1032 with self.assertRaises(TypeError):
1033 OrderedDict([('a', 1), ('b', 2)], None) # too many args
1034 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1035 self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
1036 self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
1037 self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
1038 self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
1039 c=3, e=5).items()), pairs) # mixed input
1040
1041 # make sure no positional args conflict with possible kwdargs
1042 self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args,
1043 ['self'])
1044
1045 # Make sure that direct calls to __init__ do not clear previous contents
1046 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1047 d.__init__([('e', 5), ('f', 6)], g=7, d=4)
1048 self.assertEqual(list(d.items()),
1049 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1050
1051 def test_update(self):
1052 with self.assertRaises(TypeError):
1053 OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
1054 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1055 od = OrderedDict()
1056 od.update(dict(pairs))
1057 self.assertEqual(sorted(od.items()), pairs) # dict input
1058 od = OrderedDict()
1059 od.update(**dict(pairs))
1060 self.assertEqual(sorted(od.items()), pairs) # kwds input
1061 od = OrderedDict()
1062 od.update(pairs)
1063 self.assertEqual(list(od.items()), pairs) # pairs input
1064 od = OrderedDict()
1065 od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
1066 self.assertEqual(list(od.items()), pairs) # mixed input
1067
Mark Dickinsonb214e902010-07-11 18:53:06 +00001068 # Issue 9137: Named argument called 'other' or 'self'
1069 # shouldn't be treated specially.
1070 od = OrderedDict()
1071 od.update(self=23)
1072 self.assertEqual(list(od.items()), [('self', 23)])
1073 od = OrderedDict()
1074 od.update(other={})
1075 self.assertEqual(list(od.items()), [('other', {})])
1076 od = OrderedDict()
1077 od.update(red=5, blue=6, other=7, self=8)
1078 self.assertEqual(sorted(list(od.items())),
1079 [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
1080
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001081 # Make sure that direct calls to update do not clear previous contents
1082 # add that updates items are not moved to the end
1083 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1084 d.update([('e', 5), ('f', 6)], g=7, d=4)
1085 self.assertEqual(list(d.items()),
1086 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1087
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001088 def test_abc(self):
1089 self.assertIsInstance(OrderedDict(), MutableMapping)
1090 self.assertTrue(issubclass(OrderedDict, MutableMapping))
1091
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001092 def test_clear(self):
1093 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1094 shuffle(pairs)
1095 od = OrderedDict(pairs)
1096 self.assertEqual(len(od), len(pairs))
1097 od.clear()
1098 self.assertEqual(len(od), 0)
1099
1100 def test_delitem(self):
1101 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1102 od = OrderedDict(pairs)
1103 del od['a']
Benjamin Peterson577473f2010-01-19 00:09:57 +00001104 self.assertNotIn('a', od)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001105 with self.assertRaises(KeyError):
1106 del od['a']
1107 self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
1108
1109 def test_setitem(self):
1110 od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
1111 od['c'] = 10 # existing element
1112 od['f'] = 20 # new element
1113 self.assertEqual(list(od.items()),
1114 [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
1115
1116 def test_iterators(self):
1117 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1118 shuffle(pairs)
1119 od = OrderedDict(pairs)
1120 self.assertEqual(list(od), [t[0] for t in pairs])
1121 self.assertEqual(list(od.keys()), [t[0] for t in pairs])
1122 self.assertEqual(list(od.values()), [t[1] for t in pairs])
1123 self.assertEqual(list(od.items()), pairs)
1124 self.assertEqual(list(reversed(od)),
1125 [t[0] for t in reversed(pairs)])
1126
1127 def test_popitem(self):
1128 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1129 shuffle(pairs)
1130 od = OrderedDict(pairs)
1131 while pairs:
1132 self.assertEqual(od.popitem(), pairs.pop())
1133 with self.assertRaises(KeyError):
1134 od.popitem()
1135 self.assertEqual(len(od), 0)
1136
1137 def test_pop(self):
1138 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1139 shuffle(pairs)
1140 od = OrderedDict(pairs)
1141 shuffle(pairs)
1142 while pairs:
1143 k, v = pairs.pop()
1144 self.assertEqual(od.pop(k), v)
1145 with self.assertRaises(KeyError):
1146 od.pop('xyz')
1147 self.assertEqual(len(od), 0)
1148 self.assertEqual(od.pop(k, 12345), 12345)
1149
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001150 # make sure pop still works when __missing__ is defined
1151 class Missing(OrderedDict):
1152 def __missing__(self, key):
1153 return 0
1154 m = Missing(a=1)
1155 self.assertEqual(m.pop('b', 5), 5)
1156 self.assertEqual(m.pop('a', 6), 1)
1157 self.assertEqual(m.pop('a', 6), 6)
1158 with self.assertRaises(KeyError):
1159 m.pop('a')
1160
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001161 def test_equality(self):
1162 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1163 shuffle(pairs)
1164 od1 = OrderedDict(pairs)
1165 od2 = OrderedDict(pairs)
1166 self.assertEqual(od1, od2) # same order implies equality
1167 pairs = pairs[2:] + pairs[:2]
1168 od2 = OrderedDict(pairs)
1169 self.assertNotEqual(od1, od2) # different order implies inequality
1170 # comparison to regular dict is not order sensitive
1171 self.assertEqual(od1, dict(od2))
1172 self.assertEqual(dict(od2), od1)
1173 # different length implied inequality
1174 self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
1175
1176 def test_copying(self):
1177 # Check that ordered dicts are copyable, deepcopyable, picklable,
1178 # and have a repr/eval round-trip
1179 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1180 od = OrderedDict(pairs)
1181 update_test = OrderedDict()
1182 update_test.update(od)
1183 for i, dup in enumerate([
1184 od.copy(),
1185 copy.copy(od),
1186 copy.deepcopy(od),
1187 pickle.loads(pickle.dumps(od, 0)),
1188 pickle.loads(pickle.dumps(od, 1)),
1189 pickle.loads(pickle.dumps(od, 2)),
1190 pickle.loads(pickle.dumps(od, 3)),
1191 pickle.loads(pickle.dumps(od, -1)),
1192 eval(repr(od)),
1193 update_test,
1194 OrderedDict(od),
1195 ]):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001196 self.assertTrue(dup is not od)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001197 self.assertEqual(dup, od)
1198 self.assertEqual(list(dup.items()), list(od.items()))
1199 self.assertEqual(len(dup), len(od))
1200 self.assertEqual(type(dup), type(od))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001201
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001202 def test_yaml_linkage(self):
1203 # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
1204 # In yaml, lists are native but tuples are not.
1205 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1206 od = OrderedDict(pairs)
1207 # yaml.dump(od) -->
1208 # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001209 self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001210
Raymond Hettingerb2121572009-03-03 22:50:04 +00001211 def test_reduce_not_too_fat(self):
1212 # do not save instance dictionary if not needed
1213 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1214 od = OrderedDict(pairs)
1215 self.assertEqual(len(od.__reduce__()), 2)
1216 od.x = 10
1217 self.assertEqual(len(od.__reduce__()), 3)
1218
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001219 def test_repr(self):
1220 od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
1221 self.assertEqual(repr(od),
1222 "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
1223 self.assertEqual(eval(repr(od)), od)
1224 self.assertEqual(repr(OrderedDict()), "OrderedDict()")
1225
Raymond Hettingerdc08a142010-09-12 05:15:22 +00001226 def test_repr_recursive(self):
1227 # See issue #9826
1228 od = OrderedDict.fromkeys('abc')
1229 od['x'] = od
1230 self.assertEqual(repr(od),
1231 "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
1232
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001233 def test_setdefault(self):
1234 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1235 shuffle(pairs)
1236 od = OrderedDict(pairs)
1237 pair_order = list(od.items())
1238 self.assertEqual(od.setdefault('a', 10), 3)
1239 # make sure order didn't change
1240 self.assertEqual(list(od.items()), pair_order)
1241 self.assertEqual(od.setdefault('x', 10), 10)
1242 # make sure 'x' is added to the end
1243 self.assertEqual(list(od.items())[-1], ('x', 10))
1244
Raymond Hettingera673b1f2010-12-31 23:16:17 +00001245 # make sure setdefault still works when __missing__ is defined
1246 class Missing(OrderedDict):
1247 def __missing__(self, key):
1248 return 0
1249 self.assertEqual(Missing().setdefault(5, 9), 9)
1250
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001251 def test_reinsert(self):
1252 # Given insert a, insert b, delete a, re-insert a,
1253 # verify that a is now later than b.
1254 od = OrderedDict()
1255 od['a'] = 1
1256 od['b'] = 2
1257 del od['a']
1258 od['a'] = 1
1259 self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
1260
Raymond Hettingerf45abc92010-09-06 21:26:09 +00001261 def test_move_to_end(self):
1262 od = OrderedDict.fromkeys('abcde')
1263 self.assertEqual(list(od), list('abcde'))
1264 od.move_to_end('c')
1265 self.assertEqual(list(od), list('abdec'))
1266 od.move_to_end('c', 0)
1267 self.assertEqual(list(od), list('cabde'))
1268 od.move_to_end('c', 0)
1269 self.assertEqual(list(od), list('cabde'))
1270 od.move_to_end('e')
1271 self.assertEqual(list(od), list('cabde'))
1272 with self.assertRaises(KeyError):
1273 od.move_to_end('x')
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001274
Raymond Hettinger35c87f22010-09-16 19:10:17 +00001275 def test_sizeof(self):
1276 # Wimpy test: Just verify the reported size is larger than a regular dict
1277 d = dict(a=1)
1278 od = OrderedDict(**d)
1279 self.assertGreater(sys.getsizeof(od), sys.getsizeof(d))
1280
Raymond Hettinger32062e92011-01-01 22:38:00 +00001281 def test_override_update(self):
1282 # Verify that subclasses can override update() without breaking __init__()
1283 class MyOD(OrderedDict):
1284 def update(self, *args, **kwds):
1285 raise Exception()
1286 items = [('a', 1), ('c', 3), ('b', 2)]
1287 self.assertEqual(list(MyOD(items).items()), items)
1288
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001289class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
1290 type2test = OrderedDict
1291
Raymond Hettingerdc879f02009-03-19 20:30:56 +00001292 def test_popitem(self):
1293 d = self._empty_mapping()
1294 self.assertRaises(KeyError, d.popitem)
1295
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001296class MyOrderedDict(OrderedDict):
1297 pass
1298
1299class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
1300 type2test = MyOrderedDict
1301
Raymond Hettingerdc879f02009-03-19 20:30:56 +00001302 def test_popitem(self):
1303 d = self._empty_mapping()
1304 self.assertRaises(KeyError, d.popitem)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001305
1306
Raymond Hettinger499e1932011-02-23 07:56:53 +00001307################################################################################
1308### Run tests
1309################################################################################
1310
Christian Heimes25bb7832008-01-11 16:17:00 +00001311import doctest, collections
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001312
Guido van Rossumd8faa362007-04-27 19:54:29 +00001313def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001314 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001315 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001316 TestCollectionABCs, TestCounter, TestChainMap,
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001317 TestOrderedDict, GeneralMappingTests, SubclassMappingTests]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001318 support.run_unittest(*test_classes)
1319 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001320
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001321
Guido van Rossumd8faa362007-04-27 19:54:29 +00001322if __name__ == "__main__":
1323 test_main(verbose=True)