blob: ec2093891791b238c706719a59bfa66eb45e1d70 [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
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000666 def test_Mapping(self):
667 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +0000668 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000669 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +0000670 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
671 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000672 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000673 def __len__(self):
674 return 0
675 def __getitem__(self, i):
676 raise IndexError
677 def __iter__(self):
678 return iter(())
679 self.validate_comparison(MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000680
681 def test_MutableMapping(self):
682 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +0000683 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000684 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +0000685 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
686 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000687
Raymond Hettinger9117c752010-08-22 07:44:24 +0000688 def test_MutableMapping_subclass(self):
689 # Test issue 9214
690 mymap = UserDict()
691 mymap['red'] = 5
692 self.assertIsInstance(mymap.keys(), Set)
693 self.assertIsInstance(mymap.keys(), KeysView)
694 self.assertIsInstance(mymap.items(), Set)
695 self.assertIsInstance(mymap.items(), ItemsView)
696
697 mymap = UserDict()
698 mymap['red'] = 5
699 z = mymap.keys() | {'orange'}
700 self.assertIsInstance(z, set)
701 list(z)
702 mymap['blue'] = 7 # Shouldn't affect 'z'
703 self.assertEqual(sorted(z), ['orange', 'red'])
704
705 mymap = UserDict()
706 mymap['red'] = 5
707 z = mymap.items() | {('orange', 3)}
708 self.assertIsInstance(z, set)
709 list(z)
710 mymap['blue'] = 7 # Shouldn't affect 'z'
711 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
712
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000713 def test_Sequence(self):
714 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +0000715 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000716 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +0000717 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000718 self.assertTrue(issubclass(range, Sequence))
719 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +0000720 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
721 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000722
Guido van Rossumd05eb002007-11-21 22:26:24 +0000723 def test_ByteString(self):
724 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +0000725 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000726 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +0000727 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +0000728 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000729 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +0000730 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000731 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +0000732
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000733 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +0000734 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +0000735 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000736 self.assertFalse(issubclass(sample, MutableSequence))
Guido van Rossumd05eb002007-11-21 22:26:24 +0000737 for sample in [list, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +0000738 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000739 self.assertTrue(issubclass(sample, MutableSequence))
740 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +0000741 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
742 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000743
Eli Bendersky0716a572011-03-04 10:38:14 +0000744 def test_MutableSequence_mixins(self):
745 # Test the mixins of MutableSequence by creating a miminal concrete
746 # class inherited from it.
747 class MutableSequenceSubclass(MutableSequence):
748 def __init__(self):
749 self.lst = []
750
751 def __setitem__(self, index, value):
752 self.lst[index] = value
753
754 def __getitem__(self, index):
755 return self.lst[index]
756
757 def __len__(self):
758 return len(self.lst)
759
760 def __delitem__(self, index):
761 del self.lst[index]
762
763 def insert(self, index, value):
764 self.lst.insert(index, value)
765
766 mss = MutableSequenceSubclass()
767 mss.append(0)
768 mss.extend((1, 2, 3, 4))
769 self.assertEqual(len(mss), 5)
770 self.assertEqual(mss[3], 3)
771 mss.reverse()
772 self.assertEqual(mss[3], 1)
773 mss.pop()
774 self.assertEqual(len(mss), 4)
775 mss.remove(3)
776 self.assertEqual(len(mss), 3)
777 mss += (10, 20, 30)
778 self.assertEqual(len(mss), 6)
779 self.assertEqual(mss[-1], 30)
780 mss.clear()
781 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +0000782
783################################################################################
784### Counter
785################################################################################
786
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000787class TestCounter(unittest.TestCase):
788
789 def test_basics(self):
790 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000791 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
792 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +0000793 self.assertIsInstance(c, dict)
794 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000795 self.assertTrue(issubclass(Counter, dict))
796 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000797 self.assertEqual(len(c), 3)
798 self.assertEqual(sum(c.values()), 6)
799 self.assertEqual(sorted(c.values()), [1, 2, 3])
800 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
801 self.assertEqual(sorted(c), ['a', 'b', 'c'])
802 self.assertEqual(sorted(c.items()),
803 [('a', 3), ('b', 2), ('c', 1)])
804 self.assertEqual(c['b'], 2)
805 self.assertEqual(c['z'], 0)
806 self.assertEqual(c.__contains__('c'), True)
807 self.assertEqual(c.__contains__('z'), False)
808 self.assertEqual(c.get('b', 10), 2)
809 self.assertEqual(c.get('z', 10), 10)
810 self.assertEqual(c, dict(a=3, b=2, c=1))
811 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
812 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
813 for i in range(5):
814 self.assertEqual(c.most_common(i),
815 [('a', 3), ('b', 2), ('c', 1)][:i])
816 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
817 c['a'] += 1 # increment an existing value
818 c['b'] -= 2 # sub existing value to zero
819 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000820 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000821 c['d'] -= 2 # sub from a missing value
822 c['e'] = -5 # directly assign a missing value
823 c['f'] += 4 # add to a missing value
824 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
825 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
826 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000827 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000828 for i in range(3):
829 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000830 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000831 c.clear()
832 self.assertEqual(c, {})
833 self.assertEqual(repr(c), 'Counter()')
834 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
835 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000836 c.update(dict(a=5, b=3))
837 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000838 c.update(Counter('a' * 50 + 'b' * 30))
839 c.update() # test case with no args
840 c.__init__('a' * 500 + 'b' * 300)
841 c.__init__('cdc')
842 c.__init__()
843 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
844 self.assertEqual(c.setdefault('d', 5), 1)
845 self.assertEqual(c['d'], 1)
846 self.assertEqual(c.setdefault('e', 5), 5)
847 self.assertEqual(c['e'], 5)
848
849 def test_copying(self):
850 # Check that counters are copyable, deepcopyable, picklable, and
851 #have a repr/eval round-trip
852 words = Counter('which witch had which witches wrist watch'.split())
853 update_test = Counter()
854 update_test.update(words)
855 for i, dup in enumerate([
856 words.copy(),
857 copy.copy(words),
858 copy.deepcopy(words),
859 pickle.loads(pickle.dumps(words, 0)),
860 pickle.loads(pickle.dumps(words, 1)),
861 pickle.loads(pickle.dumps(words, 2)),
862 pickle.loads(pickle.dumps(words, -1)),
863 eval(repr(words)),
864 update_test,
865 Counter(words),
866 ]):
867 msg = (i, dup, words)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000868 self.assertTrue(dup is not words)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000869 self.assertEqual(dup, words)
870 self.assertEqual(len(dup), len(words))
871 self.assertEqual(type(dup), type(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000872
Raymond Hettinger1c746c22011-04-15 13:16:46 -0700873 def test_copy_subclass(self):
874 class MyCounter(Counter):
875 pass
876 c = MyCounter('slartibartfast')
877 d = c.copy()
878 self.assertEqual(d, c)
879 self.assertEqual(len(d), len(c))
880 self.assertEqual(type(d), type(c))
881
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000882 def test_conversions(self):
883 # Convert to: set, list, dict
884 s = 'she sells sea shells by the sea shore'
885 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
886 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
887 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
888 self.assertEqual(set(Counter(s)), set(s))
889
Raymond Hettinger670eaec2009-01-21 23:14:07 +0000890 def test_invariant_for_the_in_operator(self):
891 c = Counter(a=10, b=-2, c=0)
892 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000893 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000894 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +0000895
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000896 def test_multiset_operations(self):
897 # Verify that adding a zero counter will strip zeros and negatives
898 c = Counter(a=10, b=-2, c=0) + Counter()
899 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000900
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000901 elements = 'abcd'
902 for i in range(1000):
903 # test random pairs of multisets
904 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +0000905 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000906 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +0000907 q.update(h=1, i=-1, j=0)
908 for counterop, numberop in [
909 (Counter.__add__, lambda x, y: max(0, x+y)),
910 (Counter.__sub__, lambda x, y: max(0, x-y)),
911 (Counter.__or__, lambda x, y: max(0,x,y)),
912 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000913 ]:
914 result = counterop(p, q)
915 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +0000916 self.assertEqual(numberop(p[x], q[x]), result[x],
917 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000918 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000919 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000920
921 elements = 'abcdef'
922 for i in range(100):
923 # verify that random multisets with no repeats are exactly like sets
924 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
925 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
926 for counterop, setop in [
927 (Counter.__sub__, set.__sub__),
928 (Counter.__or__, set.__or__),
929 (Counter.__and__, set.__and__),
930 ]:
931 counter_result = counterop(p, q)
932 set_result = setop(set(p.elements()), set(q.elements()))
933 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000934
Raymond Hettingerbecd5682011-10-19 13:40:37 -0700935 def test_inplace_operations(self):
936 elements = 'abcd'
937 for i in range(1000):
938 # test random pairs of multisets
939 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
940 p.update(e=1, f=-1, g=0)
941 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
942 q.update(h=1, i=-1, j=0)
943 for inplace_op, regular_op in [
944 (Counter.__iadd__, Counter.__add__),
945 (Counter.__isub__, Counter.__sub__),
946 (Counter.__ior__, Counter.__or__),
947 (Counter.__iand__, Counter.__and__),
948 ]:
949 c = p.copy()
950 c_id = id(c)
951 regular_result = regular_op(c, q)
952 inplace_result = inplace_op(c, q)
953 self.assertEqual(inplace_result, regular_result)
954 self.assertEqual(id(inplace_result), c_id)
955
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000956 def test_subtract(self):
957 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
958 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
959 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
960 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
961 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
962 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
963 c = Counter('aaabbcd')
964 c.subtract('aaaabbcce')
965 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000966
Raymond Hettingerfcb393c2011-08-09 13:00:40 -0700967 def test_unary(self):
968 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
969 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
970 self.assertEqual(dict(-c), dict(a=5))
971
Raymond Hettinger426e0522011-01-03 02:12:02 +0000972 def test_helper_function(self):
973 # two paths, one for real dicts and one for other mappings
974 elems = list('abracadabra')
975
976 d = dict()
977 _count_elements(d, elems)
978 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
979
980 m = OrderedDict()
981 _count_elements(m, elems)
982 self.assertEqual(m,
983 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
984
Raymond Hettinger499e1932011-02-23 07:56:53 +0000985
986################################################################################
987### OrderedDict
988################################################################################
989
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000990class TestOrderedDict(unittest.TestCase):
991
992 def test_init(self):
993 with self.assertRaises(TypeError):
994 OrderedDict([('a', 1), ('b', 2)], None) # too many args
995 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
996 self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
997 self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
998 self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
999 self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
1000 c=3, e=5).items()), pairs) # mixed input
1001
1002 # make sure no positional args conflict with possible kwdargs
1003 self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args,
1004 ['self'])
1005
1006 # Make sure that direct calls to __init__ do not clear previous contents
1007 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1008 d.__init__([('e', 5), ('f', 6)], g=7, d=4)
1009 self.assertEqual(list(d.items()),
1010 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1011
1012 def test_update(self):
1013 with self.assertRaises(TypeError):
1014 OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
1015 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1016 od = OrderedDict()
1017 od.update(dict(pairs))
1018 self.assertEqual(sorted(od.items()), pairs) # dict input
1019 od = OrderedDict()
1020 od.update(**dict(pairs))
1021 self.assertEqual(sorted(od.items()), pairs) # kwds input
1022 od = OrderedDict()
1023 od.update(pairs)
1024 self.assertEqual(list(od.items()), pairs) # pairs input
1025 od = OrderedDict()
1026 od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
1027 self.assertEqual(list(od.items()), pairs) # mixed input
1028
Mark Dickinsonb214e902010-07-11 18:53:06 +00001029 # Issue 9137: Named argument called 'other' or 'self'
1030 # shouldn't be treated specially.
1031 od = OrderedDict()
1032 od.update(self=23)
1033 self.assertEqual(list(od.items()), [('self', 23)])
1034 od = OrderedDict()
1035 od.update(other={})
1036 self.assertEqual(list(od.items()), [('other', {})])
1037 od = OrderedDict()
1038 od.update(red=5, blue=6, other=7, self=8)
1039 self.assertEqual(sorted(list(od.items())),
1040 [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
1041
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001042 # Make sure that direct calls to update do not clear previous contents
1043 # add that updates items are not moved to the end
1044 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1045 d.update([('e', 5), ('f', 6)], g=7, d=4)
1046 self.assertEqual(list(d.items()),
1047 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1048
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001049 def test_abc(self):
1050 self.assertIsInstance(OrderedDict(), MutableMapping)
1051 self.assertTrue(issubclass(OrderedDict, MutableMapping))
1052
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001053 def test_clear(self):
1054 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1055 shuffle(pairs)
1056 od = OrderedDict(pairs)
1057 self.assertEqual(len(od), len(pairs))
1058 od.clear()
1059 self.assertEqual(len(od), 0)
1060
1061 def test_delitem(self):
1062 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1063 od = OrderedDict(pairs)
1064 del od['a']
Benjamin Peterson577473f2010-01-19 00:09:57 +00001065 self.assertNotIn('a', od)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001066 with self.assertRaises(KeyError):
1067 del od['a']
1068 self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
1069
1070 def test_setitem(self):
1071 od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
1072 od['c'] = 10 # existing element
1073 od['f'] = 20 # new element
1074 self.assertEqual(list(od.items()),
1075 [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
1076
1077 def test_iterators(self):
1078 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1079 shuffle(pairs)
1080 od = OrderedDict(pairs)
1081 self.assertEqual(list(od), [t[0] for t in pairs])
1082 self.assertEqual(list(od.keys()), [t[0] for t in pairs])
1083 self.assertEqual(list(od.values()), [t[1] for t in pairs])
1084 self.assertEqual(list(od.items()), pairs)
1085 self.assertEqual(list(reversed(od)),
1086 [t[0] for t in reversed(pairs)])
1087
1088 def test_popitem(self):
1089 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1090 shuffle(pairs)
1091 od = OrderedDict(pairs)
1092 while pairs:
1093 self.assertEqual(od.popitem(), pairs.pop())
1094 with self.assertRaises(KeyError):
1095 od.popitem()
1096 self.assertEqual(len(od), 0)
1097
1098 def test_pop(self):
1099 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1100 shuffle(pairs)
1101 od = OrderedDict(pairs)
1102 shuffle(pairs)
1103 while pairs:
1104 k, v = pairs.pop()
1105 self.assertEqual(od.pop(k), v)
1106 with self.assertRaises(KeyError):
1107 od.pop('xyz')
1108 self.assertEqual(len(od), 0)
1109 self.assertEqual(od.pop(k, 12345), 12345)
1110
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001111 # make sure pop still works when __missing__ is defined
1112 class Missing(OrderedDict):
1113 def __missing__(self, key):
1114 return 0
1115 m = Missing(a=1)
1116 self.assertEqual(m.pop('b', 5), 5)
1117 self.assertEqual(m.pop('a', 6), 1)
1118 self.assertEqual(m.pop('a', 6), 6)
1119 with self.assertRaises(KeyError):
1120 m.pop('a')
1121
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001122 def test_equality(self):
1123 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1124 shuffle(pairs)
1125 od1 = OrderedDict(pairs)
1126 od2 = OrderedDict(pairs)
1127 self.assertEqual(od1, od2) # same order implies equality
1128 pairs = pairs[2:] + pairs[:2]
1129 od2 = OrderedDict(pairs)
1130 self.assertNotEqual(od1, od2) # different order implies inequality
1131 # comparison to regular dict is not order sensitive
1132 self.assertEqual(od1, dict(od2))
1133 self.assertEqual(dict(od2), od1)
1134 # different length implied inequality
1135 self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
1136
1137 def test_copying(self):
1138 # Check that ordered dicts are copyable, deepcopyable, picklable,
1139 # and have a repr/eval round-trip
1140 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1141 od = OrderedDict(pairs)
1142 update_test = OrderedDict()
1143 update_test.update(od)
1144 for i, dup in enumerate([
1145 od.copy(),
1146 copy.copy(od),
1147 copy.deepcopy(od),
1148 pickle.loads(pickle.dumps(od, 0)),
1149 pickle.loads(pickle.dumps(od, 1)),
1150 pickle.loads(pickle.dumps(od, 2)),
1151 pickle.loads(pickle.dumps(od, 3)),
1152 pickle.loads(pickle.dumps(od, -1)),
1153 eval(repr(od)),
1154 update_test,
1155 OrderedDict(od),
1156 ]):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001157 self.assertTrue(dup is not od)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001158 self.assertEqual(dup, od)
1159 self.assertEqual(list(dup.items()), list(od.items()))
1160 self.assertEqual(len(dup), len(od))
1161 self.assertEqual(type(dup), type(od))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001162
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001163 def test_yaml_linkage(self):
1164 # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
1165 # In yaml, lists are native but tuples are not.
1166 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1167 od = OrderedDict(pairs)
1168 # yaml.dump(od) -->
1169 # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001170 self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001171
Raymond Hettingerb2121572009-03-03 22:50:04 +00001172 def test_reduce_not_too_fat(self):
1173 # do not save instance dictionary if not needed
1174 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1175 od = OrderedDict(pairs)
1176 self.assertEqual(len(od.__reduce__()), 2)
1177 od.x = 10
1178 self.assertEqual(len(od.__reduce__()), 3)
1179
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001180 def test_repr(self):
1181 od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
1182 self.assertEqual(repr(od),
1183 "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
1184 self.assertEqual(eval(repr(od)), od)
1185 self.assertEqual(repr(OrderedDict()), "OrderedDict()")
1186
Raymond Hettingerdc08a142010-09-12 05:15:22 +00001187 def test_repr_recursive(self):
1188 # See issue #9826
1189 od = OrderedDict.fromkeys('abc')
1190 od['x'] = od
1191 self.assertEqual(repr(od),
1192 "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
1193
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001194 def test_setdefault(self):
1195 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1196 shuffle(pairs)
1197 od = OrderedDict(pairs)
1198 pair_order = list(od.items())
1199 self.assertEqual(od.setdefault('a', 10), 3)
1200 # make sure order didn't change
1201 self.assertEqual(list(od.items()), pair_order)
1202 self.assertEqual(od.setdefault('x', 10), 10)
1203 # make sure 'x' is added to the end
1204 self.assertEqual(list(od.items())[-1], ('x', 10))
1205
Raymond Hettingera673b1f2010-12-31 23:16:17 +00001206 # make sure setdefault still works when __missing__ is defined
1207 class Missing(OrderedDict):
1208 def __missing__(self, key):
1209 return 0
1210 self.assertEqual(Missing().setdefault(5, 9), 9)
1211
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001212 def test_reinsert(self):
1213 # Given insert a, insert b, delete a, re-insert a,
1214 # verify that a is now later than b.
1215 od = OrderedDict()
1216 od['a'] = 1
1217 od['b'] = 2
1218 del od['a']
1219 od['a'] = 1
1220 self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
1221
Raymond Hettingerf45abc92010-09-06 21:26:09 +00001222 def test_move_to_end(self):
1223 od = OrderedDict.fromkeys('abcde')
1224 self.assertEqual(list(od), list('abcde'))
1225 od.move_to_end('c')
1226 self.assertEqual(list(od), list('abdec'))
1227 od.move_to_end('c', 0)
1228 self.assertEqual(list(od), list('cabde'))
1229 od.move_to_end('c', 0)
1230 self.assertEqual(list(od), list('cabde'))
1231 od.move_to_end('e')
1232 self.assertEqual(list(od), list('cabde'))
1233 with self.assertRaises(KeyError):
1234 od.move_to_end('x')
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001235
Raymond Hettinger35c87f22010-09-16 19:10:17 +00001236 def test_sizeof(self):
1237 # Wimpy test: Just verify the reported size is larger than a regular dict
1238 d = dict(a=1)
1239 od = OrderedDict(**d)
1240 self.assertGreater(sys.getsizeof(od), sys.getsizeof(d))
1241
Raymond Hettinger32062e92011-01-01 22:38:00 +00001242 def test_override_update(self):
1243 # Verify that subclasses can override update() without breaking __init__()
1244 class MyOD(OrderedDict):
1245 def update(self, *args, **kwds):
1246 raise Exception()
1247 items = [('a', 1), ('c', 3), ('b', 2)]
1248 self.assertEqual(list(MyOD(items).items()), items)
1249
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001250class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
1251 type2test = OrderedDict
1252
Raymond Hettingerdc879f02009-03-19 20:30:56 +00001253 def test_popitem(self):
1254 d = self._empty_mapping()
1255 self.assertRaises(KeyError, d.popitem)
1256
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001257class MyOrderedDict(OrderedDict):
1258 pass
1259
1260class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
1261 type2test = MyOrderedDict
1262
Raymond Hettingerdc879f02009-03-19 20:30:56 +00001263 def test_popitem(self):
1264 d = self._empty_mapping()
1265 self.assertRaises(KeyError, d.popitem)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001266
1267
Raymond Hettinger499e1932011-02-23 07:56:53 +00001268################################################################################
1269### Run tests
1270################################################################################
1271
Christian Heimes25bb7832008-01-11 16:17:00 +00001272import doctest, collections
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001273
Guido van Rossumd8faa362007-04-27 19:54:29 +00001274def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001275 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001276 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001277 TestCollectionABCs, TestCounter, TestChainMap,
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001278 TestOrderedDict, GeneralMappingTests, SubclassMappingTests]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001279 support.run_unittest(*test_classes)
1280 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001281
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001282
Guido van Rossumd8faa362007-04-27 19:54:29 +00001283if __name__ == "__main__":
1284 test_main(verbose=True)