blob: 4ef27ce2c50773d979167f7f9623e9d340a9f9a2 [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('__dict__', dir(p)) # verify instance has no dict
185 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000186 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000187 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
188 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
189 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
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()
333 tmp = namedtuple('Color', 'red green blue')
334 self.assertNotIn('Color', globals())
335 exec(tmp._source, globals())
336 self.assertIn('Color', globals())
337 c = Color(10, 20, 30)
338 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
339 self.assertEqual(Color._fields, ('red', 'green', 'blue'))
340
341 def test_source_importable(self):
342 tmp = namedtuple('Color', 'hue sat val')
343
344 compiled = None
345 source = TESTFN + '.py'
346 with open(source, 'w') as f:
347 print(tmp._source, file=f)
348
349 if TESTFN in sys.modules:
350 del sys.modules[TESTFN]
351 try:
352 mod = __import__(TESTFN)
353 compiled = mod.__file__
354 Color = mod.Color
355 c = Color(10, 20, 30)
356 self.assertEqual((c.hue, c.sat, c.val), (10, 20, 30))
357 self.assertEqual(Color._fields, ('hue', 'sat', 'val'))
358 finally:
359 forget(TESTFN)
360 if compiled:
361 unlink(compiled)
362 unlink(source)
363
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000364
Raymond Hettinger499e1932011-02-23 07:56:53 +0000365################################################################################
366### Abstract Base Classes
367################################################################################
368
Raymond Hettingerae650182009-01-28 23:33:59 +0000369class ABCTestCase(unittest.TestCase):
370
371 def validate_abstract_methods(self, abc, *names):
372 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
373
374 # everything should work will all required methods are present
375 C = type('C', (abc,), methodstubs)
376 C()
377
378 # instantiation should fail if a required method is missing
379 for name in names:
380 stubs = methodstubs.copy()
381 del stubs[name]
382 C = type('C', (abc,), stubs)
383 self.assertRaises(TypeError, C, name)
384
Florent Xiclunace153f62010-03-08 15:34:35 +0000385 def validate_isinstance(self, abc, name):
386 stub = lambda s, *args: 0
387
388 C = type('C', (object,), {'__hash__': None})
389 setattr(C, name, stub)
390 self.assertIsInstance(C(), abc)
391 self.assertTrue(issubclass(C, abc))
392
393 C = type('C', (object,), {'__hash__': None})
394 self.assertNotIsInstance(C(), abc)
395 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000396
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000397 def validate_comparison(self, instance):
398 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
399 operators = {}
400 for op in ops:
401 name = '__' + op + '__'
402 operators[name] = getattr(operator, name)
403
404 class Other:
405 def __init__(self):
406 self.right_side = False
407 def __eq__(self, other):
408 self.right_side = True
409 return True
410 __lt__ = __eq__
411 __gt__ = __eq__
412 __le__ = __eq__
413 __ge__ = __eq__
414 __ne__ = __eq__
415 __ror__ = __eq__
416 __rand__ = __eq__
417 __rxor__ = __eq__
418 __rsub__ = __eq__
419
420 for name, op in operators.items():
421 if not hasattr(instance, name):
422 continue
423 other = Other()
424 op(instance, other)
425 self.assertTrue(other.right_side,'Right side not called for %s.%s'
426 % (type(instance), name))
427
Raymond Hettingerae650182009-01-28 23:33:59 +0000428class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000429
430 def test_Hashable(self):
431 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000432 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000433 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000434 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000435 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000436 # Check some hashables
437 samples = [None,
438 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000439 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000440 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000441 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000442 ]
443 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000444 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000445 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000446 self.assertRaises(TypeError, Hashable)
447 # Check direct subclassing
448 class H(Hashable):
449 def __hash__(self):
450 return super().__hash__()
451 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000452 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000453 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000454 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000455
456 def test_Iterable(self):
457 # Check some non-iterables
458 non_samples = [None, 42, 3.14, 1j]
459 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000460 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000461 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000462 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000463 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000464 tuple(), list(), set(), frozenset(), dict(),
465 dict().keys(), dict().items(), dict().values(),
466 (lambda: (yield))(),
467 (x for x in []),
468 ]
469 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000470 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000471 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000472 # Check direct subclassing
473 class I(Iterable):
474 def __iter__(self):
475 return super().__iter__()
476 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000477 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000478 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000479 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000480
481 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000482 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000483 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000484 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000485 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000486 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000487 iter(tuple()), iter(list()), iter(dict()),
488 iter(set()), iter(frozenset()),
489 iter(dict().keys()), iter(dict().items()),
490 iter(dict().values()),
491 (lambda: (yield))(),
492 (x for x in []),
493 ]
494 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000495 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000496 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000497 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
498
499 # Issue 10565
500 class NextOnly:
501 def __next__(self):
502 yield 1
503 raise StopIteration
504 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000505
506 def test_Sized(self):
507 non_samples = [None, 42, 3.14, 1j,
508 (lambda: (yield))(),
509 (x for x in []),
510 ]
511 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000512 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000513 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000514 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000515 tuple(), list(), set(), frozenset(), dict(),
516 dict().keys(), dict().items(), dict().values(),
517 ]
518 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000519 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000520 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000521 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000522 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000523
524 def test_Container(self):
525 non_samples = [None, 42, 3.14, 1j,
526 (lambda: (yield))(),
527 (x for x in []),
528 ]
529 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000530 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000531 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000532 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000533 tuple(), list(), set(), frozenset(), dict(),
534 dict().keys(), dict().items(),
535 ]
536 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000537 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000538 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000539 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000540 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000541
542 def test_Callable(self):
543 non_samples = [None, 42, 3.14, 1j,
544 "", b"", (), [], {}, set(),
545 (lambda: (yield))(),
546 (x for x in []),
547 ]
548 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000549 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000550 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000551 samples = [lambda: None,
552 type, int, object,
553 len,
554 list.append, [].append,
555 ]
556 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000557 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000558 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000559 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000560 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000561
562 def test_direct_subclassing(self):
563 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
564 class C(B):
565 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000566 self.assertTrue(issubclass(C, B))
567 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000568
569 def test_registration(self):
570 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
571 class C:
572 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000573 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000574 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000575 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000576
Raymond Hettinger3f10a952009-04-01 19:05:50 +0000577class WithSet(MutableSet):
578
579 def __init__(self, it=()):
580 self.data = set(it)
581
582 def __len__(self):
583 return len(self.data)
584
585 def __iter__(self):
586 return iter(self.data)
587
588 def __contains__(self, item):
589 return item in self.data
590
591 def add(self, item):
592 self.data.add(item)
593
594 def discard(self, item):
595 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000596
Raymond Hettingerae650182009-01-28 23:33:59 +0000597class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000598
599 # XXX For now, we only test some virtual inheritance properties.
600 # We should also test the proper behavior of the collection ABCs
601 # as real base classes or mix-in classes.
602
603 def test_Set(self):
604 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +0000605 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000606 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +0000607 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000608 class MySet(Set):
609 def __contains__(self, x):
610 return False
611 def __len__(self):
612 return 0
613 def __iter__(self):
614 return iter([])
615 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000616
Benjamin Peterson41181742008-07-02 20:22:54 +0000617 def test_hash_Set(self):
618 class OneTwoThreeSet(Set):
619 def __init__(self):
620 self.contents = [1, 2, 3]
621 def __contains__(self, x):
622 return x in self.contents
623 def __len__(self):
624 return len(self.contents)
625 def __iter__(self):
626 return iter(self.contents)
627 def __hash__(self):
628 return self._hash()
629 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000630 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +0000631
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000632 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +0000633 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000634 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +0000635 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000636 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +0000637 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
638 'add', 'discard')
639
Raymond Hettinger3f10a952009-04-01 19:05:50 +0000640 def test_issue_5647(self):
641 # MutableSet.__iand__ mutated the set during iteration
642 s = WithSet('abcd')
643 s &= WithSet('cdef') # This used to fail
644 self.assertEqual(set(s), set('cd'))
645
Raymond Hettingerae650182009-01-28 23:33:59 +0000646 def test_issue_4920(self):
647 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000648 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +0000649 __slots__=['__s']
650 def __init__(self,items=None):
651 if items is None:
652 items=[]
653 self.__s=set(items)
654 def __contains__(self,v):
655 return v in self.__s
656 def __iter__(self):
657 return iter(self.__s)
658 def __len__(self):
659 return len(self.__s)
660 def add(self,v):
661 result=v not in self.__s
662 self.__s.add(v)
663 return result
664 def discard(self,v):
665 result=v in self.__s
666 self.__s.discard(v)
667 return result
668 def __repr__(self):
669 return "MySet(%s)" % repr(list(self))
670 s = MySet([5,43,2,1])
671 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000672
Daniel Stutzbach31da5b22010-08-24 20:49:57 +0000673 def test_issue8750(self):
674 empty = WithSet()
675 full = WithSet(range(10))
676 s = WithSet(full)
677 s -= s
678 self.assertEqual(s, empty)
679 s = WithSet(full)
680 s ^= s
681 self.assertEqual(s, empty)
682 s = WithSet(full)
683 s &= s
684 self.assertEqual(s, full)
685 s |= s
686 self.assertEqual(s, full)
687
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000688 def test_Mapping(self):
689 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +0000690 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000691 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +0000692 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
693 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000694 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000695 def __len__(self):
696 return 0
697 def __getitem__(self, i):
698 raise IndexError
699 def __iter__(self):
700 return iter(())
701 self.validate_comparison(MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000702
703 def test_MutableMapping(self):
704 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +0000705 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000706 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +0000707 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
708 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000709
Raymond Hettinger9117c752010-08-22 07:44:24 +0000710 def test_MutableMapping_subclass(self):
711 # Test issue 9214
712 mymap = UserDict()
713 mymap['red'] = 5
714 self.assertIsInstance(mymap.keys(), Set)
715 self.assertIsInstance(mymap.keys(), KeysView)
716 self.assertIsInstance(mymap.items(), Set)
717 self.assertIsInstance(mymap.items(), ItemsView)
718
719 mymap = UserDict()
720 mymap['red'] = 5
721 z = mymap.keys() | {'orange'}
722 self.assertIsInstance(z, set)
723 list(z)
724 mymap['blue'] = 7 # Shouldn't affect 'z'
725 self.assertEqual(sorted(z), ['orange', 'red'])
726
727 mymap = UserDict()
728 mymap['red'] = 5
729 z = mymap.items() | {('orange', 3)}
730 self.assertIsInstance(z, set)
731 list(z)
732 mymap['blue'] = 7 # Shouldn't affect 'z'
733 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
734
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000735 def test_Sequence(self):
736 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +0000737 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000738 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +0000739 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000740 self.assertTrue(issubclass(range, Sequence))
741 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +0000742 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
743 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000744
Guido van Rossumd05eb002007-11-21 22:26:24 +0000745 def test_ByteString(self):
746 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +0000747 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000748 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +0000749 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +0000750 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000751 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +0000752 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000753 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +0000754
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000755 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +0000756 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +0000757 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000758 self.assertFalse(issubclass(sample, MutableSequence))
Guido van Rossumd05eb002007-11-21 22:26:24 +0000759 for sample in [list, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +0000760 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000761 self.assertTrue(issubclass(sample, MutableSequence))
762 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +0000763 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
764 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000765
Eli Bendersky0716a572011-03-04 10:38:14 +0000766 def test_MutableSequence_mixins(self):
767 # Test the mixins of MutableSequence by creating a miminal concrete
768 # class inherited from it.
769 class MutableSequenceSubclass(MutableSequence):
770 def __init__(self):
771 self.lst = []
772
773 def __setitem__(self, index, value):
774 self.lst[index] = value
775
776 def __getitem__(self, index):
777 return self.lst[index]
778
779 def __len__(self):
780 return len(self.lst)
781
782 def __delitem__(self, index):
783 del self.lst[index]
784
785 def insert(self, index, value):
786 self.lst.insert(index, value)
787
788 mss = MutableSequenceSubclass()
789 mss.append(0)
790 mss.extend((1, 2, 3, 4))
791 self.assertEqual(len(mss), 5)
792 self.assertEqual(mss[3], 3)
793 mss.reverse()
794 self.assertEqual(mss[3], 1)
795 mss.pop()
796 self.assertEqual(len(mss), 4)
797 mss.remove(3)
798 self.assertEqual(len(mss), 3)
799 mss += (10, 20, 30)
800 self.assertEqual(len(mss), 6)
801 self.assertEqual(mss[-1], 30)
802 mss.clear()
803 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +0000804
805################################################################################
806### Counter
807################################################################################
808
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000809class TestCounter(unittest.TestCase):
810
811 def test_basics(self):
812 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000813 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
814 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +0000815 self.assertIsInstance(c, dict)
816 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000817 self.assertTrue(issubclass(Counter, dict))
818 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000819 self.assertEqual(len(c), 3)
820 self.assertEqual(sum(c.values()), 6)
821 self.assertEqual(sorted(c.values()), [1, 2, 3])
822 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
823 self.assertEqual(sorted(c), ['a', 'b', 'c'])
824 self.assertEqual(sorted(c.items()),
825 [('a', 3), ('b', 2), ('c', 1)])
826 self.assertEqual(c['b'], 2)
827 self.assertEqual(c['z'], 0)
828 self.assertEqual(c.__contains__('c'), True)
829 self.assertEqual(c.__contains__('z'), False)
830 self.assertEqual(c.get('b', 10), 2)
831 self.assertEqual(c.get('z', 10), 10)
832 self.assertEqual(c, dict(a=3, b=2, c=1))
833 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
834 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
835 for i in range(5):
836 self.assertEqual(c.most_common(i),
837 [('a', 3), ('b', 2), ('c', 1)][:i])
838 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
839 c['a'] += 1 # increment an existing value
840 c['b'] -= 2 # sub existing value to zero
841 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000842 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000843 c['d'] -= 2 # sub from a missing value
844 c['e'] = -5 # directly assign a missing value
845 c['f'] += 4 # add to a missing value
846 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
847 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
848 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000849 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000850 for i in range(3):
851 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000852 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000853 c.clear()
854 self.assertEqual(c, {})
855 self.assertEqual(repr(c), 'Counter()')
856 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
857 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000858 c.update(dict(a=5, b=3))
859 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000860 c.update(Counter('a' * 50 + 'b' * 30))
861 c.update() # test case with no args
862 c.__init__('a' * 500 + 'b' * 300)
863 c.__init__('cdc')
864 c.__init__()
865 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
866 self.assertEqual(c.setdefault('d', 5), 1)
867 self.assertEqual(c['d'], 1)
868 self.assertEqual(c.setdefault('e', 5), 5)
869 self.assertEqual(c['e'], 5)
870
871 def test_copying(self):
872 # Check that counters are copyable, deepcopyable, picklable, and
873 #have a repr/eval round-trip
874 words = Counter('which witch had which witches wrist watch'.split())
875 update_test = Counter()
876 update_test.update(words)
877 for i, dup in enumerate([
878 words.copy(),
879 copy.copy(words),
880 copy.deepcopy(words),
881 pickle.loads(pickle.dumps(words, 0)),
882 pickle.loads(pickle.dumps(words, 1)),
883 pickle.loads(pickle.dumps(words, 2)),
884 pickle.loads(pickle.dumps(words, -1)),
885 eval(repr(words)),
886 update_test,
887 Counter(words),
888 ]):
889 msg = (i, dup, words)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000890 self.assertTrue(dup is not words)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000891 self.assertEqual(dup, words)
892 self.assertEqual(len(dup), len(words))
893 self.assertEqual(type(dup), type(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000894
895 def test_conversions(self):
896 # Convert to: set, list, dict
897 s = 'she sells sea shells by the sea shore'
898 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
899 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
900 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
901 self.assertEqual(set(Counter(s)), set(s))
902
Raymond Hettinger670eaec2009-01-21 23:14:07 +0000903 def test_invariant_for_the_in_operator(self):
904 c = Counter(a=10, b=-2, c=0)
905 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000906 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000907 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +0000908
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000909 def test_multiset_operations(self):
910 # Verify that adding a zero counter will strip zeros and negatives
911 c = Counter(a=10, b=-2, c=0) + Counter()
912 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000913
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000914 elements = 'abcd'
915 for i in range(1000):
916 # test random pairs of multisets
917 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +0000918 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000919 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +0000920 q.update(h=1, i=-1, j=0)
921 for counterop, numberop in [
922 (Counter.__add__, lambda x, y: max(0, x+y)),
923 (Counter.__sub__, lambda x, y: max(0, x-y)),
924 (Counter.__or__, lambda x, y: max(0,x,y)),
925 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000926 ]:
927 result = counterop(p, q)
928 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +0000929 self.assertEqual(numberop(p[x], q[x]), result[x],
930 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000931 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000932 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000933
934 elements = 'abcdef'
935 for i in range(100):
936 # verify that random multisets with no repeats are exactly like sets
937 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
938 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
939 for counterop, setop in [
940 (Counter.__sub__, set.__sub__),
941 (Counter.__or__, set.__or__),
942 (Counter.__and__, set.__and__),
943 ]:
944 counter_result = counterop(p, q)
945 set_result = setop(set(p.elements()), set(q.elements()))
946 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000947
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000948 def test_subtract(self):
949 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
950 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
951 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
952 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
953 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
954 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
955 c = Counter('aaabbcd')
956 c.subtract('aaaabbcce')
957 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000958
Raymond Hettinger426e0522011-01-03 02:12:02 +0000959 def test_helper_function(self):
960 # two paths, one for real dicts and one for other mappings
961 elems = list('abracadabra')
962
963 d = dict()
964 _count_elements(d, elems)
965 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
966
967 m = OrderedDict()
968 _count_elements(m, elems)
969 self.assertEqual(m,
970 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
971
Raymond Hettinger499e1932011-02-23 07:56:53 +0000972
973################################################################################
974### OrderedDict
975################################################################################
976
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000977class TestOrderedDict(unittest.TestCase):
978
979 def test_init(self):
980 with self.assertRaises(TypeError):
981 OrderedDict([('a', 1), ('b', 2)], None) # too many args
982 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
983 self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
984 self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
985 self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
986 self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
987 c=3, e=5).items()), pairs) # mixed input
988
989 # make sure no positional args conflict with possible kwdargs
990 self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args,
991 ['self'])
992
993 # Make sure that direct calls to __init__ do not clear previous contents
994 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
995 d.__init__([('e', 5), ('f', 6)], g=7, d=4)
996 self.assertEqual(list(d.items()),
997 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
998
999 def test_update(self):
1000 with self.assertRaises(TypeError):
1001 OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
1002 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1003 od = OrderedDict()
1004 od.update(dict(pairs))
1005 self.assertEqual(sorted(od.items()), pairs) # dict input
1006 od = OrderedDict()
1007 od.update(**dict(pairs))
1008 self.assertEqual(sorted(od.items()), pairs) # kwds input
1009 od = OrderedDict()
1010 od.update(pairs)
1011 self.assertEqual(list(od.items()), pairs) # pairs input
1012 od = OrderedDict()
1013 od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
1014 self.assertEqual(list(od.items()), pairs) # mixed input
1015
Mark Dickinsonb214e902010-07-11 18:53:06 +00001016 # Issue 9137: Named argument called 'other' or 'self'
1017 # shouldn't be treated specially.
1018 od = OrderedDict()
1019 od.update(self=23)
1020 self.assertEqual(list(od.items()), [('self', 23)])
1021 od = OrderedDict()
1022 od.update(other={})
1023 self.assertEqual(list(od.items()), [('other', {})])
1024 od = OrderedDict()
1025 od.update(red=5, blue=6, other=7, self=8)
1026 self.assertEqual(sorted(list(od.items())),
1027 [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
1028
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001029 # Make sure that direct calls to update do not clear previous contents
1030 # add that updates items are not moved to the end
1031 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1032 d.update([('e', 5), ('f', 6)], g=7, d=4)
1033 self.assertEqual(list(d.items()),
1034 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1035
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001036 def test_abc(self):
1037 self.assertIsInstance(OrderedDict(), MutableMapping)
1038 self.assertTrue(issubclass(OrderedDict, MutableMapping))
1039
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001040 def test_clear(self):
1041 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1042 shuffle(pairs)
1043 od = OrderedDict(pairs)
1044 self.assertEqual(len(od), len(pairs))
1045 od.clear()
1046 self.assertEqual(len(od), 0)
1047
1048 def test_delitem(self):
1049 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1050 od = OrderedDict(pairs)
1051 del od['a']
Benjamin Peterson577473f2010-01-19 00:09:57 +00001052 self.assertNotIn('a', od)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001053 with self.assertRaises(KeyError):
1054 del od['a']
1055 self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
1056
1057 def test_setitem(self):
1058 od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
1059 od['c'] = 10 # existing element
1060 od['f'] = 20 # new element
1061 self.assertEqual(list(od.items()),
1062 [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
1063
1064 def test_iterators(self):
1065 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1066 shuffle(pairs)
1067 od = OrderedDict(pairs)
1068 self.assertEqual(list(od), [t[0] for t in pairs])
1069 self.assertEqual(list(od.keys()), [t[0] for t in pairs])
1070 self.assertEqual(list(od.values()), [t[1] for t in pairs])
1071 self.assertEqual(list(od.items()), pairs)
1072 self.assertEqual(list(reversed(od)),
1073 [t[0] for t in reversed(pairs)])
1074
1075 def test_popitem(self):
1076 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1077 shuffle(pairs)
1078 od = OrderedDict(pairs)
1079 while pairs:
1080 self.assertEqual(od.popitem(), pairs.pop())
1081 with self.assertRaises(KeyError):
1082 od.popitem()
1083 self.assertEqual(len(od), 0)
1084
1085 def test_pop(self):
1086 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1087 shuffle(pairs)
1088 od = OrderedDict(pairs)
1089 shuffle(pairs)
1090 while pairs:
1091 k, v = pairs.pop()
1092 self.assertEqual(od.pop(k), v)
1093 with self.assertRaises(KeyError):
1094 od.pop('xyz')
1095 self.assertEqual(len(od), 0)
1096 self.assertEqual(od.pop(k, 12345), 12345)
1097
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001098 # make sure pop still works when __missing__ is defined
1099 class Missing(OrderedDict):
1100 def __missing__(self, key):
1101 return 0
1102 m = Missing(a=1)
1103 self.assertEqual(m.pop('b', 5), 5)
1104 self.assertEqual(m.pop('a', 6), 1)
1105 self.assertEqual(m.pop('a', 6), 6)
1106 with self.assertRaises(KeyError):
1107 m.pop('a')
1108
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001109 def test_equality(self):
1110 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1111 shuffle(pairs)
1112 od1 = OrderedDict(pairs)
1113 od2 = OrderedDict(pairs)
1114 self.assertEqual(od1, od2) # same order implies equality
1115 pairs = pairs[2:] + pairs[:2]
1116 od2 = OrderedDict(pairs)
1117 self.assertNotEqual(od1, od2) # different order implies inequality
1118 # comparison to regular dict is not order sensitive
1119 self.assertEqual(od1, dict(od2))
1120 self.assertEqual(dict(od2), od1)
1121 # different length implied inequality
1122 self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
1123
1124 def test_copying(self):
1125 # Check that ordered dicts are copyable, deepcopyable, picklable,
1126 # and have a repr/eval round-trip
1127 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1128 od = OrderedDict(pairs)
1129 update_test = OrderedDict()
1130 update_test.update(od)
1131 for i, dup in enumerate([
1132 od.copy(),
1133 copy.copy(od),
1134 copy.deepcopy(od),
1135 pickle.loads(pickle.dumps(od, 0)),
1136 pickle.loads(pickle.dumps(od, 1)),
1137 pickle.loads(pickle.dumps(od, 2)),
1138 pickle.loads(pickle.dumps(od, 3)),
1139 pickle.loads(pickle.dumps(od, -1)),
1140 eval(repr(od)),
1141 update_test,
1142 OrderedDict(od),
1143 ]):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001144 self.assertTrue(dup is not od)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001145 self.assertEqual(dup, od)
1146 self.assertEqual(list(dup.items()), list(od.items()))
1147 self.assertEqual(len(dup), len(od))
1148 self.assertEqual(type(dup), type(od))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001149
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001150 def test_yaml_linkage(self):
1151 # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
1152 # In yaml, lists are native but tuples are not.
1153 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1154 od = OrderedDict(pairs)
1155 # yaml.dump(od) -->
1156 # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001157 self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001158
Raymond Hettingerb2121572009-03-03 22:50:04 +00001159 def test_reduce_not_too_fat(self):
1160 # do not save instance dictionary if not needed
1161 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1162 od = OrderedDict(pairs)
1163 self.assertEqual(len(od.__reduce__()), 2)
1164 od.x = 10
1165 self.assertEqual(len(od.__reduce__()), 3)
1166
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001167 def test_repr(self):
1168 od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
1169 self.assertEqual(repr(od),
1170 "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
1171 self.assertEqual(eval(repr(od)), od)
1172 self.assertEqual(repr(OrderedDict()), "OrderedDict()")
1173
Raymond Hettingerdc08a142010-09-12 05:15:22 +00001174 def test_repr_recursive(self):
1175 # See issue #9826
1176 od = OrderedDict.fromkeys('abc')
1177 od['x'] = od
1178 self.assertEqual(repr(od),
1179 "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
1180
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001181 def test_setdefault(self):
1182 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1183 shuffle(pairs)
1184 od = OrderedDict(pairs)
1185 pair_order = list(od.items())
1186 self.assertEqual(od.setdefault('a', 10), 3)
1187 # make sure order didn't change
1188 self.assertEqual(list(od.items()), pair_order)
1189 self.assertEqual(od.setdefault('x', 10), 10)
1190 # make sure 'x' is added to the end
1191 self.assertEqual(list(od.items())[-1], ('x', 10))
1192
Raymond Hettingera673b1f2010-12-31 23:16:17 +00001193 # make sure setdefault still works when __missing__ is defined
1194 class Missing(OrderedDict):
1195 def __missing__(self, key):
1196 return 0
1197 self.assertEqual(Missing().setdefault(5, 9), 9)
1198
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001199 def test_reinsert(self):
1200 # Given insert a, insert b, delete a, re-insert a,
1201 # verify that a is now later than b.
1202 od = OrderedDict()
1203 od['a'] = 1
1204 od['b'] = 2
1205 del od['a']
1206 od['a'] = 1
1207 self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
1208
Raymond Hettingerf45abc92010-09-06 21:26:09 +00001209 def test_move_to_end(self):
1210 od = OrderedDict.fromkeys('abcde')
1211 self.assertEqual(list(od), list('abcde'))
1212 od.move_to_end('c')
1213 self.assertEqual(list(od), list('abdec'))
1214 od.move_to_end('c', 0)
1215 self.assertEqual(list(od), list('cabde'))
1216 od.move_to_end('c', 0)
1217 self.assertEqual(list(od), list('cabde'))
1218 od.move_to_end('e')
1219 self.assertEqual(list(od), list('cabde'))
1220 with self.assertRaises(KeyError):
1221 od.move_to_end('x')
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001222
Raymond Hettinger35c87f22010-09-16 19:10:17 +00001223 def test_sizeof(self):
1224 # Wimpy test: Just verify the reported size is larger than a regular dict
1225 d = dict(a=1)
1226 od = OrderedDict(**d)
1227 self.assertGreater(sys.getsizeof(od), sys.getsizeof(d))
1228
Raymond Hettinger32062e92011-01-01 22:38:00 +00001229 def test_override_update(self):
1230 # Verify that subclasses can override update() without breaking __init__()
1231 class MyOD(OrderedDict):
1232 def update(self, *args, **kwds):
1233 raise Exception()
1234 items = [('a', 1), ('c', 3), ('b', 2)]
1235 self.assertEqual(list(MyOD(items).items()), items)
1236
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001237class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
1238 type2test = OrderedDict
1239
Raymond Hettingerdc879f02009-03-19 20:30:56 +00001240 def test_popitem(self):
1241 d = self._empty_mapping()
1242 self.assertRaises(KeyError, d.popitem)
1243
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001244class MyOrderedDict(OrderedDict):
1245 pass
1246
1247class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
1248 type2test = MyOrderedDict
1249
Raymond Hettingerdc879f02009-03-19 20:30:56 +00001250 def test_popitem(self):
1251 d = self._empty_mapping()
1252 self.assertRaises(KeyError, d.popitem)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001253
1254
Raymond Hettinger499e1932011-02-23 07:56:53 +00001255################################################################################
1256### Run tests
1257################################################################################
1258
Christian Heimes25bb7832008-01-11 16:17:00 +00001259import doctest, collections
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001260
Guido van Rossumd8faa362007-04-27 19:54:29 +00001261def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001262 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001263 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001264 TestCollectionABCs, TestCounter, TestChainMap,
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001265 TestOrderedDict, GeneralMappingTests, SubclassMappingTests]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001266 support.run_unittest(*test_classes)
1267 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001268
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001269
Guido van Rossumd8faa362007-04-27 19:54:29 +00001270if __name__ == "__main__":
1271 test_main(verbose=True)