blob: 0207823f5aab7262e625ce45799b2dcd3529014a [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001"""Unit tests for collections.py."""
2
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02003import collections
4import copy
5import doctest
Serhiy Storchaka052b2df2018-12-31 14:15:16 +02006import inspect
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02007import operator
8import pickle
9from random import choice, randrange
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020010import string
R. David Murray378c0cf2010-02-24 01:46:21 +000011import sys
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020012from test import support
Yury Selivanov75445082015-05-11 22:57:16 -040013import types
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020014import unittest
15
Victor Stinner8f4ef3b2019-07-01 18:28:25 +020016from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger573b44c2015-05-22 16:56:32 -070017from collections import UserDict, UserString, UserList
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000018from collections import ChainMap
Raymond Hettinger32ea1652015-03-21 01:37:37 -070019from collections import deque
Yury Selivanov22214ab2016-11-16 18:25:04 -050020from collections.abc import Awaitable, Coroutine
21from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator
Guido van Rossum16ca06b2016-04-04 10:59:29 -070022from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
Guido van Rossumf0666942016-08-23 10:47:07 -070023from collections.abc import Sized, Container, Callable, Collection
Raymond Hettinger57d1a882011-02-23 00:46:28 +000024from collections.abc import Set, MutableSet
Raymond Hettinger584e8ae2016-05-05 11:14:06 +030025from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
Raymond Hettinger57d1a882011-02-23 00:46:28 +000026from collections.abc import Sequence, MutableSequence
27from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000028
Raymond Hettinger499e1932011-02-23 07:56:53 +000029
Raymond Hettinger573b44c2015-05-22 16:56:32 -070030class TestUserObjects(unittest.TestCase):
31 def _superset_test(self, a, b):
32 self.assertGreaterEqual(
33 set(dir(a)),
34 set(dir(b)),
35 '{a} should have all the methods of {b}'.format(
36 a=a.__name__,
37 b=b.__name__,
38 ),
39 )
Bar Harelf4e1bab2019-05-19 16:57:13 +030040
41 def _copy_test(self, obj):
42 # Test internal copy
43 obj_copy = obj.copy()
44 self.assertIsNot(obj.data, obj_copy.data)
45 self.assertEqual(obj.data, obj_copy.data)
46
47 # Test copy.copy
48 obj.test = [1234] # Make sure instance vars are also copied.
49 obj_copy = copy.copy(obj)
50 self.assertIsNot(obj.data, obj_copy.data)
51 self.assertEqual(obj.data, obj_copy.data)
52 self.assertIs(obj.test, obj_copy.test)
53
Raymond Hettinger573b44c2015-05-22 16:56:32 -070054 def test_str_protocol(self):
55 self._superset_test(UserString, str)
56
57 def test_list_protocol(self):
58 self._superset_test(UserList, list)
59
60 def test_dict_protocol(self):
61 self._superset_test(UserDict, dict)
62
Bar Harelf4e1bab2019-05-19 16:57:13 +030063 def test_list_copy(self):
64 obj = UserList()
65 obj.append(123)
66 self._copy_test(obj)
67
68 def test_dict_copy(self):
69 obj = UserDict()
70 obj[123] = "abc"
71 self._copy_test(obj)
72
Raymond Hettinger573b44c2015-05-22 16:56:32 -070073
Raymond Hettinger499e1932011-02-23 07:56:53 +000074################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000075### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000076################################################################################
77
78class TestChainMap(unittest.TestCase):
79
80 def test_basics(self):
81 c = ChainMap()
82 c['a'] = 1
83 c['b'] = 2
84 d = c.new_child()
85 d['b'] = 20
86 d['c'] = 30
87 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
88 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
89 self.assertEqual(len(d), 3) # check len
90 for key in 'abc': # check contains
91 self.assertIn(key, d)
92 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
93 self.assertEqual(d.get(k, 100), v)
94
95 del d['b'] # unmask a value
96 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
97 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
98 self.assertEqual(len(d), 3) # check len
99 for key in 'abc': # check contains
100 self.assertIn(key, d)
101 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
102 self.assertEqual(d.get(k, 100), v)
103 self.assertIn(repr(d), [ # check repr
104 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
105 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
106 ])
107
108 for e in d.copy(), copy.copy(d): # check shallow copies
109 self.assertEqual(d, e)
110 self.assertEqual(d.maps, e.maps)
111 self.assertIsNot(d, e)
112 self.assertIsNot(d.maps[0], e.maps[0])
113 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
114 self.assertIs(m1, m2)
115
Serhiy Storchakabad12572014-12-15 14:03:42 +0200116 # check deep copies
117 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
118 e = pickle.loads(pickle.dumps(d, proto))
119 self.assertEqual(d, e)
120 self.assertEqual(d.maps, e.maps)
121 self.assertIsNot(d, e)
122 for m1, m2 in zip(d.maps, e.maps):
123 self.assertIsNot(m1, m2, e)
124 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +0000125 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200126 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000127 self.assertEqual(d, e)
128 self.assertEqual(d.maps, e.maps)
129 self.assertIsNot(d, e)
130 for m1, m2 in zip(d.maps, e.maps):
131 self.assertIsNot(m1, m2, e)
132
Raymond Hettingerd0321312011-02-26 06:53:58 +0000133 f = d.new_child()
134 f['b'] = 5
135 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
136 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
137 self.assertEqual(f['b'], 5) # find first in chain
138 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000139
Raymond Hettinger86f093f2019-02-21 09:12:15 -0800140 def test_ordering(self):
141 # Combined order matches a series of dict updates from last to first.
142 # This test relies on the ordering of the underlying dicts.
143
144 baseline = {'music': 'bach', 'art': 'rembrandt'}
145 adjustments = {'art': 'van gogh', 'opera': 'carmen'}
146
147 cm = ChainMap(adjustments, baseline)
148
149 combined = baseline.copy()
150 combined.update(adjustments)
151
152 self.assertEqual(list(combined.items()), list(cm.items()))
153
Martin Pantereb995702016-07-28 01:11:04 +0000154 def test_constructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000155 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000156 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
157
Raymond Hettingerd0321312011-02-26 06:53:58 +0000158 def test_bool(self):
159 self.assertFalse(ChainMap())
160 self.assertFalse(ChainMap({}, {}))
161 self.assertTrue(ChainMap({1:2}, {}))
162 self.assertTrue(ChainMap({}, {1:2}))
163
Raymond Hettinger499e1932011-02-23 07:56:53 +0000164 def test_missing(self):
165 class DefaultChainMap(ChainMap):
166 def __missing__(self, key):
167 return 999
168 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
169 for k, v in dict(a=1, b=2, c=30, d=999).items():
170 self.assertEqual(d[k], v) # check __getitem__ w/missing
171 for k, v in dict(a=1, b=2, c=30, d=77).items():
172 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
173 for k, v in dict(a=True, b=True, c=True, d=False).items():
174 self.assertEqual(k in d, v) # check __contains__ w/missing
175 self.assertEqual(d.pop('a', 1001), 1, d)
176 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
177 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
178 with self.assertRaises(KeyError):
179 d.popitem()
180
Raymond Hettinger3793f952018-02-11 00:30:31 -0800181 def test_order_preservation(self):
182 d = ChainMap(
183 OrderedDict(j=0, h=88888),
184 OrderedDict(),
185 OrderedDict(i=9999, d=4444, c=3333),
186 OrderedDict(f=666, b=222, g=777, c=333, h=888),
187 OrderedDict(),
188 OrderedDict(e=55, b=22),
189 OrderedDict(a=1, b=2, c=3, d=4, e=5),
190 OrderedDict(),
191 )
192 self.assertEqual(''.join(d), 'abcdefghij')
193 self.assertEqual(list(d.items()),
194 [('a', 1), ('b', 222), ('c', 3333), ('d', 4444),
195 ('e', 55), ('f', 666), ('g', 777), ('h', 88888),
196 ('i', 9999), ('j', 0)])
197
Raymond Hettinger499e1932011-02-23 07:56:53 +0000198 def test_dict_coercion(self):
199 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
200 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
201 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
202
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000203 def test_new_child(self):
204 'Tests for changes for issue #16613.'
205 c = ChainMap()
206 c['a'] = 1
207 c['b'] = 2
208 m = {'b':20, 'c': 30}
209 d = c.new_child(m)
210 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
211 self.assertIs(m, d.maps[0])
212
213 # Use a different map than a dict
214 class lowerdict(dict):
215 def __getitem__(self, key):
216 if isinstance(key, str):
217 key = key.lower()
218 return dict.__getitem__(self, key)
219 def __contains__(self, key):
220 if isinstance(key, str):
221 key = key.lower()
222 return dict.__contains__(self, key)
223
224 c = ChainMap()
225 c['a'] = 1
226 c['b'] = 2
227 m = lowerdict(b=20, c=30)
228 d = c.new_child(m)
229 self.assertIs(m, d.maps[0])
230 for key in 'abc': # check contains
231 self.assertIn(key, d)
232 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
233 self.assertEqual(d.get(k, 100), v)
234
Curtis Bucherf393b2c2020-03-23 12:02:05 -0700235 def test_union_operators(self):
236 cm1 = ChainMap(dict(a=1, b=2), dict(c=3, d=4))
237 cm2 = ChainMap(dict(a=10, e=5), dict(b=20, d=4))
238 cm3 = cm1.copy()
239 d = dict(a=10, c=30)
240 pairs = [('c', 3), ('p',0)]
241
242 tmp = cm1 | cm2 # testing between chainmaps
243 self.assertEqual(tmp.maps, [cm1.maps[0] | dict(cm2), *cm1.maps[1:]])
244 cm1 |= cm2
245 self.assertEqual(tmp, cm1)
246
247 tmp = cm2 | d # testing between chainmap and mapping
248 self.assertEqual(tmp.maps, [cm2.maps[0] | d, *cm2.maps[1:]])
249 self.assertEqual((d | cm2).maps, [d | dict(cm2)])
250 cm2 |= d
251 self.assertEqual(tmp, cm2)
252
253 # testing behavior between chainmap and iterable key-value pairs
254 with self.assertRaises(TypeError):
255 cm3 | pairs
Curtis Bucher0c5ad542020-03-30 09:50:57 -0700256 tmp = cm3.copy()
Curtis Bucherf393b2c2020-03-23 12:02:05 -0700257 cm3 |= pairs
Curtis Bucher0c5ad542020-03-30 09:50:57 -0700258 self.assertEqual(cm3.maps, [tmp.maps[0] | dict(pairs), *tmp.maps[1:]])
Curtis Bucherf393b2c2020-03-23 12:02:05 -0700259
260 # testing proper return types for ChainMap and it's subclasses
261 class Subclass(ChainMap):
262 pass
263
264 class SubclassRor(ChainMap):
265 def __ror__(self, other):
266 return super().__ror__(other)
267
268 tmp = ChainMap() | ChainMap()
269 self.assertIs(type(tmp), ChainMap)
270 self.assertIs(type(tmp.maps[0]), dict)
271 tmp = ChainMap() | Subclass()
272 self.assertIs(type(tmp), ChainMap)
273 self.assertIs(type(tmp.maps[0]), dict)
274 tmp = Subclass() | ChainMap()
275 self.assertIs(type(tmp), Subclass)
276 self.assertIs(type(tmp.maps[0]), dict)
277 tmp = ChainMap() | SubclassRor()
278 self.assertIs(type(tmp), SubclassRor)
279 self.assertIs(type(tmp.maps[0]), dict)
280
Raymond Hettinger499e1932011-02-23 07:56:53 +0000281
282################################################################################
283### Named Tuples
284################################################################################
285
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000286TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000287
288class TestNamedTuple(unittest.TestCase):
289
290 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000291 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000292 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000293 self.assertEqual(Point.__slots__, ())
294 self.assertEqual(Point.__module__, __name__)
295 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000296 self.assertEqual(Point._fields, ('x', 'y'))
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000297
298 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
299 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
300 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
301
302 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
303 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
304 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000305 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000306 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
307
308 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000309 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000310
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000311 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000312 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000313 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000314 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000315
Christian Heimesfaf2f632008-01-06 16:59:19 +0000316 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
317 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
318
Raymond Hettinger39482072018-01-10 21:45:19 -0800319 def test_defaults(self):
320 Point = namedtuple('Point', 'x y', defaults=(10, 20)) # 2 defaults
Raymond Hettinger23581c02019-03-18 00:27:39 -0700321 self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
Raymond Hettinger39482072018-01-10 21:45:19 -0800322 self.assertEqual(Point(1, 2), (1, 2))
323 self.assertEqual(Point(1), (1, 20))
324 self.assertEqual(Point(), (10, 20))
325
326 Point = namedtuple('Point', 'x y', defaults=(20,)) # 1 default
Raymond Hettinger23581c02019-03-18 00:27:39 -0700327 self.assertEqual(Point._field_defaults, {'y': 20})
Raymond Hettinger39482072018-01-10 21:45:19 -0800328 self.assertEqual(Point(1, 2), (1, 2))
329 self.assertEqual(Point(1), (1, 20))
330
331 Point = namedtuple('Point', 'x y', defaults=()) # 0 defaults
Raymond Hettinger23581c02019-03-18 00:27:39 -0700332 self.assertEqual(Point._field_defaults, {})
Raymond Hettinger39482072018-01-10 21:45:19 -0800333 self.assertEqual(Point(1, 2), (1, 2))
334 with self.assertRaises(TypeError):
335 Point(1)
336
337 with self.assertRaises(TypeError): # catch too few args
338 Point()
339 with self.assertRaises(TypeError): # catch too many args
340 Point(1, 2, 3)
341 with self.assertRaises(TypeError): # too many defaults
342 Point = namedtuple('Point', 'x y', defaults=(10, 20, 30))
343 with self.assertRaises(TypeError): # non-iterable defaults
344 Point = namedtuple('Point', 'x y', defaults=10)
345 with self.assertRaises(TypeError): # another non-iterable default
346 Point = namedtuple('Point', 'x y', defaults=False)
347
348 Point = namedtuple('Point', 'x y', defaults=None) # default is None
Raymond Hettinger23581c02019-03-18 00:27:39 -0700349 self.assertEqual(Point._field_defaults, {})
Raymond Hettinger39482072018-01-10 21:45:19 -0800350 self.assertIsNone(Point.__new__.__defaults__, None)
351 self.assertEqual(Point(10, 20), (10, 20))
352 with self.assertRaises(TypeError): # catch too few args
353 Point(10)
354
355 Point = namedtuple('Point', 'x y', defaults=[10, 20]) # allow non-tuple iterable
Raymond Hettinger23581c02019-03-18 00:27:39 -0700356 self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
Raymond Hettinger39482072018-01-10 21:45:19 -0800357 self.assertEqual(Point.__new__.__defaults__, (10, 20))
358 self.assertEqual(Point(1, 2), (1, 2))
359 self.assertEqual(Point(1), (1, 20))
360 self.assertEqual(Point(), (10, 20))
361
362 Point = namedtuple('Point', 'x y', defaults=iter([10, 20])) # allow plain iterator
Raymond Hettinger23581c02019-03-18 00:27:39 -0700363 self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
Raymond Hettinger39482072018-01-10 21:45:19 -0800364 self.assertEqual(Point.__new__.__defaults__, (10, 20))
365 self.assertEqual(Point(1, 2), (1, 2))
366 self.assertEqual(Point(1), (1, 20))
367 self.assertEqual(Point(), (10, 20))
368
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200369 def test_readonly(self):
370 Point = namedtuple('Point', 'x y')
371 p = Point(11, 22)
372 with self.assertRaises(AttributeError):
373 p.x = 33
374 with self.assertRaises(AttributeError):
375 del p.x
376 with self.assertRaises(TypeError):
377 p[0] = 33
378 with self.assertRaises(TypeError):
379 del p[0]
380 self.assertEqual(p.x, 11)
381 self.assertEqual(p[0], 11)
Raymond Hettinger39482072018-01-10 21:45:19 -0800382
R. David Murray378c0cf2010-02-24 01:46:21 +0000383 @unittest.skipIf(sys.flags.optimize >= 2,
384 "Docstrings are omitted with -O2 and above")
385 def test_factory_doc_attr(self):
386 Point = namedtuple('Point', 'x y')
387 self.assertEqual(Point.__doc__, 'Point(x, y)')
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200388 Point.__doc__ = '2D point'
389 self.assertEqual(Point.__doc__, '2D point')
R. David Murray378c0cf2010-02-24 01:46:21 +0000390
Raymond Hettingereac503a2015-05-13 01:09:59 -0700391 @unittest.skipIf(sys.flags.optimize >= 2,
392 "Docstrings are omitted with -O2 and above")
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200393 def test_field_doc(self):
Raymond Hettingereac503a2015-05-13 01:09:59 -0700394 Point = namedtuple('Point', 'x y')
395 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200396 self.assertEqual(Point.y.__doc__, 'Alias for field number 1')
Raymond Hettingereac503a2015-05-13 01:09:59 -0700397 Point.x.__doc__ = 'docstring for Point.x'
398 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200399 # namedtuple can mutate doc of descriptors independently
400 Vector = namedtuple('Vector', 'x y')
401 self.assertEqual(Vector.x.__doc__, 'Alias for field number 0')
402 Vector.x.__doc__ = 'docstring for Vector.x'
403 self.assertEqual(Vector.x.__doc__, 'docstring for Vector.x')
404
405 @support.cpython_only
406 @unittest.skipIf(sys.flags.optimize >= 2,
407 "Docstrings are omitted with -O2 and above")
408 def test_field_doc_reuse(self):
409 P = namedtuple('P', ['m', 'n'])
410 Q = namedtuple('Q', ['o', 'p'])
411 self.assertIs(P.m.__doc__, Q.o.__doc__)
412 self.assertIs(P.n.__doc__, Q.p.__doc__)
Raymond Hettingereac503a2015-05-13 01:09:59 -0700413
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000414 def test_name_fixer(self):
415 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000416 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
417 [('abc', 'class'), ('abc', '_1')], # field has keyword
418 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
419 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
420 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
421 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000422 ]:
423 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
424
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700425 def test_module_parameter(self):
426 NT = namedtuple('NT', ['x', 'y'], module=collections)
427 self.assertEqual(NT.__module__, collections)
428
Guido van Rossumd8faa362007-04-27 19:54:29 +0000429 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000430 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000431 p = Point(11, 22)
432 self.assertEqual(p, Point(x=11, y=22))
433 self.assertEqual(p, Point(11, y=22))
434 self.assertEqual(p, Point(y=22, x=11))
435 self.assertEqual(p, Point(*(11, 22)))
436 self.assertEqual(p, Point(**dict(x=11, y=22)))
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200437 self.assertRaises(TypeError, Point, 1) # too few args
438 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
439 with self.assertRaises(TypeError): # wrong keyword argument
440 Point(XXX=1, y=2)
441 with self.assertRaises(TypeError): # missing keyword argument
442 Point(x=1)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000443 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000444 self.assertNotIn('__weakref__', dir(p))
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200445 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
446 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
447 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
448 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000449
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000450 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000451 p._replace(x=1, error=2)
452 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000453 pass
454 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000455 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000456
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000457 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000458 Point = namedtuple('Point', 'x, y')
459 p = Point(x=11, y=22)
460 self.assertEqual(repr(p), 'Point(x=11, y=22)')
461
462 # verify that fieldspec can be a non-string sequence
463 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000464 p = Point(x=11, y=22)
465 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000466
467 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000468 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000469 p = Point(11, 22)
470
Ezio Melottie9615932010-01-24 19:26:24 +0000471 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000472 self.assertEqual(p, (11, 22)) # matches a real tuple
Min ho Kimc4cacc82019-07-31 08:16:13 +1000473 self.assertEqual(tuple(p), (11, 22)) # coercible to a real tuple
474 self.assertEqual(list(p), [11, 22]) # coercible to a list
Guido van Rossumd8faa362007-04-27 19:54:29 +0000475 self.assertEqual(max(p), 22) # iterable
476 self.assertEqual(max(*p), 22) # star-able
477 x, y = p
478 self.assertEqual(p, (x, y)) # unpacks like a tuple
479 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200480 with self.assertRaises(IndexError):
481 p[3]
482 self.assertEqual(p[-1], 22)
483 self.assertEqual(hash(p), hash((11, 22)))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000484
485 self.assertEqual(p.x, x)
486 self.assertEqual(p.y, y)
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200487 with self.assertRaises(AttributeError):
488 p.z
Guido van Rossumd8faa362007-04-27 19:54:29 +0000489
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000490 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000491 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000492 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000493 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000494 self.assertEqual(repr(Zero()), 'Zero()')
495 self.assertEqual(Zero()._asdict(), {})
496 self.assertEqual(Zero()._fields, ())
497
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000498 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000499 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000500 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000501 self.assertEqual(Dot(1).d, 1)
502 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
503 self.assertEqual(Dot(1)._asdict(), {'d':1})
504 self.assertEqual(Dot(1)._replace(d=999), (999,))
505 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000506
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200507 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200508 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000509 for j in range(10)]) for i in range(n)))
510 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000511 Big = namedtuple('Big', names)
512 b = Big(*range(n))
513 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000514 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000515 for pos, name in enumerate(names):
516 self.assertEqual(getattr(b, name), pos)
517 repr(b) # make sure repr() doesn't blow-up
518 d = b._asdict()
519 d_expected = dict(zip(names, range(n)))
520 self.assertEqual(d, d_expected)
521 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
522 b2_expected = list(range(n))
523 b2_expected[1] = 999
524 b2_expected[-5] = 42
525 self.assertEqual(b2, tuple(b2_expected))
526 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000527
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000528 def test_pickle(self):
529 p = TestNT(x=10, y=20, z=30)
530 for module in (pickle,):
531 loads = getattr(module, 'loads')
532 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500533 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000534 q = loads(dumps(p, protocol))
535 self.assertEqual(p, q)
536 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700537 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000538
539 def test_copy(self):
540 p = TestNT(x=10, y=20, z=30)
541 for copier in copy.copy, copy.deepcopy:
542 q = copier(p)
543 self.assertEqual(p, q)
544 self.assertEqual(p._fields, q._fields)
545
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000546 def test_name_conflicts(self):
547 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
548 # failed when used as field names. Test to make sure these now work.
549 T = namedtuple('T', 'itemgetter property self cls tuple')
550 t = T(1, 2, 3, 4, 5)
551 self.assertEqual(t, (1,2,3,4,5))
552 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
553 self.assertEqual(newt, (10,20,30,40,50))
554
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700555 # Broader test of all interesting names taken from the code, old
556 # template, and an example
557 words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create',
558 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper',
559 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note',
560 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError',
561 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add',
562 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments',
563 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot',
564 'class_namespace', 'classmethod', 'cls', 'collections', 'convert',
565 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict',
566 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect',
567 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f',
568 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame',
569 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater',
570 'has', 'help', 'identifiers', 'index', 'indexable', 'instance',
571 'instantiate', 'interning', 'introspection', 'isidentifier',
572 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords',
573 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata',
574 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named',
575 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new',
576 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option',
577 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional',
578 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr',
579 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen',
580 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start',
581 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys',
582 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new',
583 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use',
584 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where',
585 'which', 'work', 'x', 'y', 'z', 'zip'}
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000586 T = namedtuple('T', words)
587 # test __new__
588 values = tuple(range(len(words)))
589 t = T(*values)
590 self.assertEqual(t, values)
591 t = T(**dict(zip(T._fields, values)))
592 self.assertEqual(t, values)
593 # test _make
594 t = T._make(values)
595 self.assertEqual(t, values)
596 # exercise __repr__
597 repr(t)
598 # test _asdict
599 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
600 # test _replace
601 t = T._make(values)
602 newvalues = tuple(v*10 for v in values)
603 newt = t._replace(**dict(zip(T._fields, newvalues)))
604 self.assertEqual(newt, newvalues)
605 # test _fields
606 self.assertEqual(T._fields, tuple(words))
607 # test __getnewargs__
608 self.assertEqual(t.__getnewargs__(), values)
609
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000610 def test_repr(self):
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700611 A = namedtuple('A', 'x')
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000612 self.assertEqual(repr(A(1)), 'A(x=1)')
613 # repr should show the name of the subclass
614 class B(A):
615 pass
616 self.assertEqual(repr(B(1)), 'B(x=1)')
617
Raymond Hettinger6538b432016-08-16 10:55:43 -0700618 def test_keyword_only_arguments(self):
619 # See issue 25628
Raymond Hettinger6538b432016-08-16 10:55:43 -0700620 with self.assertRaises(TypeError):
621 NT = namedtuple('NT', ['x', 'y'], True)
622
623 NT = namedtuple('NT', ['abc', 'def'], rename=True)
624 self.assertEqual(NT._fields, ('abc', '_1'))
625 with self.assertRaises(TypeError):
626 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000627
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700628 def test_namedtuple_subclass_issue_24931(self):
629 class Point(namedtuple('_Point', ['x', 'y'])):
630 pass
631
632 a = Point(3, 4)
633 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
634
635 a.w = 5
636 self.assertEqual(a.__dict__, {'w': 5})
637
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200638 def test_field_descriptor(self):
639 Point = namedtuple('Point', 'x y')
640 p = Point(11, 22)
641 self.assertTrue(inspect.isdatadescriptor(Point.x))
642 self.assertEqual(Point.x.__get__(p), 11)
643 self.assertRaises(AttributeError, Point.x.__set__, p, 33)
644 self.assertRaises(AttributeError, Point.x.__delete__, p)
Pablo Galindo3f5fc702018-12-30 09:24:03 +0000645
Joe Jevnikf36f8922019-02-21 16:00:40 -0500646 class NewPoint(tuple):
647 x = pickle.loads(pickle.dumps(Point.x))
648 y = pickle.loads(pickle.dumps(Point.y))
649
650 np = NewPoint([1, 2])
651
652 self.assertEqual(np.x, 1)
653 self.assertEqual(np.y, 2)
654
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700655
Raymond Hettinger499e1932011-02-23 07:56:53 +0000656################################################################################
657### Abstract Base Classes
658################################################################################
659
Raymond Hettingerae650182009-01-28 23:33:59 +0000660class ABCTestCase(unittest.TestCase):
661
662 def validate_abstract_methods(self, abc, *names):
663 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
664
665 # everything should work will all required methods are present
666 C = type('C', (abc,), methodstubs)
667 C()
668
669 # instantiation should fail if a required method is missing
670 for name in names:
671 stubs = methodstubs.copy()
672 del stubs[name]
673 C = type('C', (abc,), stubs)
674 self.assertRaises(TypeError, C, name)
675
Florent Xiclunace153f62010-03-08 15:34:35 +0000676 def validate_isinstance(self, abc, name):
677 stub = lambda s, *args: 0
678
679 C = type('C', (object,), {'__hash__': None})
680 setattr(C, name, stub)
681 self.assertIsInstance(C(), abc)
682 self.assertTrue(issubclass(C, abc))
683
684 C = type('C', (object,), {'__hash__': None})
685 self.assertNotIsInstance(C(), abc)
686 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000687
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000688 def validate_comparison(self, instance):
689 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
690 operators = {}
691 for op in ops:
692 name = '__' + op + '__'
693 operators[name] = getattr(operator, name)
694
695 class Other:
696 def __init__(self):
697 self.right_side = False
698 def __eq__(self, other):
699 self.right_side = True
700 return True
701 __lt__ = __eq__
702 __gt__ = __eq__
703 __le__ = __eq__
704 __ge__ = __eq__
705 __ne__ = __eq__
706 __ror__ = __eq__
707 __rand__ = __eq__
708 __rxor__ = __eq__
709 __rsub__ = __eq__
710
711 for name, op in operators.items():
712 if not hasattr(instance, name):
713 continue
714 other = Other()
715 op(instance, other)
716 self.assertTrue(other.right_side,'Right side not called for %s.%s'
717 % (type(instance), name))
718
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700719def _test_gen():
720 yield
721
Raymond Hettingerae650182009-01-28 23:33:59 +0000722class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000723
Yury Selivanov75445082015-05-11 22:57:16 -0400724 def test_Awaitable(self):
725 def gen():
726 yield
727
728 @types.coroutine
729 def coro():
730 yield
731
732 async def new_coro():
733 pass
734
735 class Bar:
736 def __await__(self):
737 yield
738
739 class MinimalCoro(Coroutine):
740 def send(self, value):
741 return value
742 def throw(self, typ, val=None, tb=None):
743 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400744 def __await__(self):
745 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400746
747 non_samples = [None, int(), gen(), object()]
748 for x in non_samples:
749 self.assertNotIsInstance(x, Awaitable)
750 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
751
752 samples = [Bar(), MinimalCoro()]
753 for x in samples:
754 self.assertIsInstance(x, Awaitable)
755 self.assertTrue(issubclass(type(x), Awaitable))
756
757 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400758 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
759 # flag don't have '__await__' method, hence can't be instances
760 # of Awaitable. Use inspect.isawaitable to detect them.
761 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400762
763 c = new_coro()
764 self.assertIsInstance(c, Awaitable)
Mike53f7a7c2017-12-14 14:04:53 +0300765 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400766
Yury Selivanov56fc6142015-05-29 09:01:29 -0400767 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400768 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400769 self.assertTrue(isinstance(CoroLike(), Awaitable))
770 self.assertTrue(issubclass(CoroLike, Awaitable))
771 CoroLike = None
772 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400773
Yury Selivanov75445082015-05-11 22:57:16 -0400774 def test_Coroutine(self):
775 def gen():
776 yield
777
778 @types.coroutine
779 def coro():
780 yield
781
782 async def new_coro():
783 pass
784
785 class Bar:
786 def __await__(self):
787 yield
788
789 class MinimalCoro(Coroutine):
790 def send(self, value):
791 return value
792 def throw(self, typ, val=None, tb=None):
793 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400794 def __await__(self):
795 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400796
797 non_samples = [None, int(), gen(), object(), Bar()]
798 for x in non_samples:
799 self.assertNotIsInstance(x, Coroutine)
800 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
801
802 samples = [MinimalCoro()]
803 for x in samples:
804 self.assertIsInstance(x, Awaitable)
805 self.assertTrue(issubclass(type(x), Awaitable))
806
807 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400808 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
809 # flag don't have '__await__' method, hence can't be instances
810 # of Coroutine. Use inspect.isawaitable to detect them.
811 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400812
813 c = new_coro()
814 self.assertIsInstance(c, Coroutine)
Mike53f7a7c2017-12-14 14:04:53 +0300815 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400816
Yury Selivanov56fc6142015-05-29 09:01:29 -0400817 class CoroLike:
818 def send(self, value):
819 pass
820 def throw(self, typ, val=None, tb=None):
821 pass
822 def close(self):
823 pass
824 def __await__(self):
825 pass
826 self.assertTrue(isinstance(CoroLike(), Coroutine))
827 self.assertTrue(issubclass(CoroLike, Coroutine))
828
829 class CoroLike:
830 def send(self, value):
831 pass
832 def close(self):
833 pass
834 def __await__(self):
835 pass
836 self.assertFalse(isinstance(CoroLike(), Coroutine))
837 self.assertFalse(issubclass(CoroLike, Coroutine))
838
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000839 def test_Hashable(self):
840 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000841 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000842 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000843 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000844 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000845 # Check some hashables
846 samples = [None,
847 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000848 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000849 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000850 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000851 ]
852 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000853 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000854 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000855 self.assertRaises(TypeError, Hashable)
856 # Check direct subclassing
857 class H(Hashable):
858 def __hash__(self):
859 return super().__hash__()
860 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000861 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000862 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000863 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000864
Yury Selivanove0104ae2015-05-14 12:19:16 -0400865 def test_AsyncIterable(self):
866 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400867 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400868 return self
869 self.assertTrue(isinstance(AI(), AsyncIterable))
870 self.assertTrue(issubclass(AI, AsyncIterable))
871 # Check some non-iterables
872 non_samples = [None, object, []]
873 for x in non_samples:
874 self.assertNotIsInstance(x, AsyncIterable)
875 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
876 self.validate_abstract_methods(AsyncIterable, '__aiter__')
877 self.validate_isinstance(AsyncIterable, '__aiter__')
878
879 def test_AsyncIterator(self):
880 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400881 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400882 return self
883 async def __anext__(self):
884 raise StopAsyncIteration
885 self.assertTrue(isinstance(AI(), AsyncIterator))
886 self.assertTrue(issubclass(AI, AsyncIterator))
887 non_samples = [None, object, []]
888 # Check some non-iterables
889 for x in non_samples:
890 self.assertNotIsInstance(x, AsyncIterator)
891 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
892 # Similarly to regular iterators (see issue 10565)
893 class AnextOnly:
894 async def __anext__(self):
895 raise StopAsyncIteration
896 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
897 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
898
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000899 def test_Iterable(self):
900 # Check some non-iterables
901 non_samples = [None, 42, 3.14, 1j]
902 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000903 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000904 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000905 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000906 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000907 tuple(), list(), set(), frozenset(), dict(),
908 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700909 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000910 (x for x in []),
911 ]
912 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000913 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000914 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000915 # Check direct subclassing
916 class I(Iterable):
917 def __iter__(self):
918 return super().__iter__()
919 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000920 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000921 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000922 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700923 # Check None blocking
924 class It:
925 def __iter__(self): return iter([])
926 class ItBlocked(It):
927 __iter__ = None
928 self.assertTrue(issubclass(It, Iterable))
929 self.assertTrue(isinstance(It(), Iterable))
930 self.assertFalse(issubclass(ItBlocked, Iterable))
931 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000932
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700933 def test_Reversible(self):
934 # Check some non-reversibles
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100935 non_samples = [None, 42, 3.14, 1j, set(), frozenset()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700936 for x in non_samples:
937 self.assertNotIsInstance(x, Reversible)
938 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700939 # Check some non-reversible iterables
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100940 non_reversibles = [_test_gen(), (x for x in []), iter([]), reversed([])]
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700941 for x in non_reversibles:
942 self.assertNotIsInstance(x, Reversible)
943 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
944 # Check some reversible iterables
945 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
946 OrderedDict().keys(), OrderedDict().items(),
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100947 OrderedDict().values(), Counter(), Counter().keys(),
948 Counter().items(), Counter().values(), dict(),
949 dict().keys(), dict().items(), dict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700950 for x in samples:
951 self.assertIsInstance(x, Reversible)
952 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
953 # Check also Mapping, MutableMapping, and Sequence
954 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
955 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
956 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
957 # Check direct subclassing
958 class R(Reversible):
959 def __iter__(self):
960 return iter(list())
961 def __reversed__(self):
962 return iter(list())
963 self.assertEqual(list(reversed(R())), [])
964 self.assertFalse(issubclass(float, R))
965 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700966 # Check reversible non-iterable (which is not Reversible)
967 class RevNoIter:
968 def __reversed__(self): return reversed([])
969 class RevPlusIter(RevNoIter):
970 def __iter__(self): return iter([])
971 self.assertFalse(issubclass(RevNoIter, Reversible))
972 self.assertFalse(isinstance(RevNoIter(), Reversible))
973 self.assertTrue(issubclass(RevPlusIter, Reversible))
974 self.assertTrue(isinstance(RevPlusIter(), Reversible))
975 # Check None blocking
976 class Rev:
977 def __iter__(self): return iter([])
978 def __reversed__(self): return reversed([])
979 class RevItBlocked(Rev):
980 __iter__ = None
981 class RevRevBlocked(Rev):
982 __reversed__ = None
983 self.assertTrue(issubclass(Rev, Reversible))
984 self.assertTrue(isinstance(Rev(), Reversible))
985 self.assertFalse(issubclass(RevItBlocked, Reversible))
986 self.assertFalse(isinstance(RevItBlocked(), Reversible))
987 self.assertFalse(issubclass(RevRevBlocked, Reversible))
988 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700989
Guido van Rossumf0666942016-08-23 10:47:07 -0700990 def test_Collection(self):
991 # Check some non-collections
992 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
993 for x in non_collections:
994 self.assertNotIsInstance(x, Collection)
995 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
996 # Check some non-collection iterables
997 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800998 (x for x in [])]
Guido van Rossumf0666942016-08-23 10:47:07 -0700999 for x in non_col_iterables:
1000 self.assertNotIsInstance(x, Collection)
1001 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
1002 # Check some collections
1003 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
Raymond Hettinger02556fb2018-01-11 21:53:49 -08001004 list(), dict().keys(), dict().items(), dict().values()]
Guido van Rossumf0666942016-08-23 10:47:07 -07001005 for x in samples:
1006 self.assertIsInstance(x, Collection)
1007 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
1008 # Check also Mapping, MutableMapping, etc.
1009 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
1010 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
1011 self.assertTrue(issubclass(MutableMapping, Collection),
1012 repr(MutableMapping))
1013 self.assertTrue(issubclass(Set, Collection), repr(Set))
1014 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
1015 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
1016 # Check direct subclassing
1017 class Col(Collection):
1018 def __iter__(self):
1019 return iter(list())
1020 def __len__(self):
1021 return 0
1022 def __contains__(self, item):
1023 return False
1024 class DerCol(Col): pass
1025 self.assertEqual(list(iter(Col())), [])
1026 self.assertFalse(issubclass(list, Col))
1027 self.assertFalse(issubclass(set, Col))
1028 self.assertFalse(issubclass(float, Col))
1029 self.assertEqual(list(iter(DerCol())), [])
1030 self.assertFalse(issubclass(list, DerCol))
1031 self.assertFalse(issubclass(set, DerCol))
1032 self.assertFalse(issubclass(float, DerCol))
1033 self.validate_abstract_methods(Collection, '__len__', '__iter__',
1034 '__contains__')
1035 # Check sized container non-iterable (which is not Collection) etc.
1036 class ColNoIter:
1037 def __len__(self): return 0
1038 def __contains__(self, item): return False
1039 class ColNoSize:
1040 def __iter__(self): return iter([])
1041 def __contains__(self, item): return False
1042 class ColNoCont:
1043 def __iter__(self): return iter([])
1044 def __len__(self): return 0
1045 self.assertFalse(issubclass(ColNoIter, Collection))
1046 self.assertFalse(isinstance(ColNoIter(), Collection))
1047 self.assertFalse(issubclass(ColNoSize, Collection))
1048 self.assertFalse(isinstance(ColNoSize(), Collection))
1049 self.assertFalse(issubclass(ColNoCont, Collection))
1050 self.assertFalse(isinstance(ColNoCont(), Collection))
1051 # Check None blocking
1052 class SizeBlock:
1053 def __iter__(self): return iter([])
1054 def __contains__(self): return False
1055 __len__ = None
1056 class IterBlock:
1057 def __len__(self): return 0
1058 def __contains__(self): return True
1059 __iter__ = None
1060 self.assertFalse(issubclass(SizeBlock, Collection))
1061 self.assertFalse(isinstance(SizeBlock(), Collection))
1062 self.assertFalse(issubclass(IterBlock, Collection))
1063 self.assertFalse(isinstance(IterBlock(), Collection))
1064 # Check None blocking in subclass
1065 class ColImpl:
1066 def __iter__(self):
1067 return iter(list())
1068 def __len__(self):
1069 return 0
1070 def __contains__(self, item):
1071 return False
1072 class NonCol(ColImpl):
1073 __contains__ = None
1074 self.assertFalse(issubclass(NonCol, Collection))
1075 self.assertFalse(isinstance(NonCol(), Collection))
1076
1077
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001078 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +00001079 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001080 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001081 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001082 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001083 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001084 iter(tuple()), iter(list()), iter(dict()),
1085 iter(set()), iter(frozenset()),
1086 iter(dict().keys()), iter(dict().items()),
1087 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001088 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001089 (x for x in []),
1090 ]
1091 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001092 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001093 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +00001094 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
1095
1096 # Issue 10565
1097 class NextOnly:
1098 def __next__(self):
1099 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -08001100 return
Raymond Hettingeread22222010-11-29 03:56:12 +00001101 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001102
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -04001103 def test_Generator(self):
1104 class NonGen1:
1105 def __iter__(self): return self
1106 def __next__(self): return None
1107 def close(self): pass
1108 def throw(self, typ, val=None, tb=None): pass
1109
1110 class NonGen2:
1111 def __iter__(self): return self
1112 def __next__(self): return None
1113 def close(self): pass
1114 def send(self, value): return value
1115
1116 class NonGen3:
1117 def close(self): pass
1118 def send(self, value): return value
1119 def throw(self, typ, val=None, tb=None): pass
1120
1121 non_samples = [
1122 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1123 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
1124 for x in non_samples:
1125 self.assertNotIsInstance(x, Generator)
1126 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
1127
1128 class Gen:
1129 def __iter__(self): return self
1130 def __next__(self): return None
1131 def close(self): pass
1132 def send(self, value): return value
1133 def throw(self, typ, val=None, tb=None): pass
1134
1135 class MinimalGen(Generator):
1136 def send(self, value):
1137 return value
1138 def throw(self, typ, val=None, tb=None):
1139 super().throw(typ, val, tb)
1140
1141 def gen():
1142 yield 1
1143
1144 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
1145 for x in samples:
1146 self.assertIsInstance(x, Iterator)
1147 self.assertIsInstance(x, Generator)
1148 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
1149 self.validate_abstract_methods(Generator, 'send', 'throw')
1150
1151 # mixin tests
1152 mgen = MinimalGen()
1153 self.assertIs(mgen, iter(mgen))
1154 self.assertIs(mgen.send(None), next(mgen))
1155 self.assertEqual(2, mgen.send(2))
1156 self.assertIsNone(mgen.close())
1157 self.assertRaises(ValueError, mgen.throw, ValueError)
1158 self.assertRaisesRegex(ValueError, "^huhu$",
1159 mgen.throw, ValueError, ValueError("huhu"))
1160 self.assertRaises(StopIteration, mgen.throw, StopIteration())
1161
1162 class FailOnClose(Generator):
1163 def send(self, value): return value
1164 def throw(self, *args): raise ValueError
1165
1166 self.assertRaises(ValueError, FailOnClose().close)
1167
1168 class IgnoreGeneratorExit(Generator):
1169 def send(self, value): return value
1170 def throw(self, *args): pass
1171
1172 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
1173
Yury Selivanov22214ab2016-11-16 18:25:04 -05001174 def test_AsyncGenerator(self):
1175 class NonAGen1:
1176 def __aiter__(self): return self
1177 def __anext__(self): return None
1178 def aclose(self): pass
1179 def athrow(self, typ, val=None, tb=None): pass
1180
1181 class NonAGen2:
1182 def __aiter__(self): return self
1183 def __anext__(self): return None
1184 def aclose(self): pass
1185 def asend(self, value): return value
1186
1187 class NonAGen3:
1188 def aclose(self): pass
1189 def asend(self, value): return value
1190 def athrow(self, typ, val=None, tb=None): pass
1191
1192 non_samples = [
1193 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1194 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
1195 for x in non_samples:
1196 self.assertNotIsInstance(x, AsyncGenerator)
1197 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
1198
1199 class Gen:
1200 def __aiter__(self): return self
1201 async def __anext__(self): return None
1202 async def aclose(self): pass
1203 async def asend(self, value): return value
1204 async def athrow(self, typ, val=None, tb=None): pass
1205
1206 class MinimalAGen(AsyncGenerator):
1207 async def asend(self, value):
1208 return value
1209 async def athrow(self, typ, val=None, tb=None):
1210 await super().athrow(typ, val, tb)
1211
1212 async def gen():
1213 yield 1
1214
1215 samples = [gen(), Gen(), MinimalAGen()]
1216 for x in samples:
1217 self.assertIsInstance(x, AsyncIterator)
1218 self.assertIsInstance(x, AsyncGenerator)
1219 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1220 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1221
1222 def run_async(coro):
1223 result = None
1224 while True:
1225 try:
1226 coro.send(None)
1227 except StopIteration as ex:
1228 result = ex.args[0] if ex.args else None
1229 break
1230 return result
1231
1232 # mixin tests
1233 mgen = MinimalAGen()
1234 self.assertIs(mgen, mgen.__aiter__())
1235 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1236 self.assertEqual(2, run_async(mgen.asend(2)))
1237 self.assertIsNone(run_async(mgen.aclose()))
1238 with self.assertRaises(ValueError):
1239 run_async(mgen.athrow(ValueError))
1240
1241 class FailOnClose(AsyncGenerator):
1242 async def asend(self, value): return value
1243 async def athrow(self, *args): raise ValueError
1244
1245 with self.assertRaises(ValueError):
1246 run_async(FailOnClose().aclose())
1247
1248 class IgnoreGeneratorExit(AsyncGenerator):
1249 async def asend(self, value): return value
1250 async def athrow(self, *args): pass
1251
1252 with self.assertRaises(RuntimeError):
1253 run_async(IgnoreGeneratorExit().aclose())
1254
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001255 def test_Sized(self):
1256 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001257 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001258 (x for x in []),
1259 ]
1260 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001261 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001262 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001263 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001264 tuple(), list(), set(), frozenset(), dict(),
1265 dict().keys(), dict().items(), dict().values(),
1266 ]
1267 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001268 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001269 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001270 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001271 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001272
1273 def test_Container(self):
1274 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001275 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001276 (x for x in []),
1277 ]
1278 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001279 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001280 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001281 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001282 tuple(), list(), set(), frozenset(), dict(),
1283 dict().keys(), dict().items(),
1284 ]
1285 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001286 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001287 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001288 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001289 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001290
1291 def test_Callable(self):
1292 non_samples = [None, 42, 3.14, 1j,
1293 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001294 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001295 (x for x in []),
1296 ]
1297 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001298 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001299 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001300 samples = [lambda: None,
1301 type, int, object,
1302 len,
1303 list.append, [].append,
1304 ]
1305 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001306 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001307 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001308 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001309 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001310
1311 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001312 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001313 class C(B):
1314 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001315 self.assertTrue(issubclass(C, B))
1316 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001317
1318 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001319 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001320 class C:
1321 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001322 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001323 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001324 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001325
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001326class WithSet(MutableSet):
1327
1328 def __init__(self, it=()):
1329 self.data = set(it)
1330
1331 def __len__(self):
1332 return len(self.data)
1333
1334 def __iter__(self):
1335 return iter(self.data)
1336
1337 def __contains__(self, item):
1338 return item in self.data
1339
1340 def add(self, item):
1341 self.data.add(item)
1342
1343 def discard(self, item):
1344 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001345
Raymond Hettingerae650182009-01-28 23:33:59 +00001346class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001347
1348 # XXX For now, we only test some virtual inheritance properties.
1349 # We should also test the proper behavior of the collection ABCs
1350 # as real base classes or mix-in classes.
1351
1352 def test_Set(self):
1353 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001354 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001355 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001356 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001357 class MySet(Set):
1358 def __contains__(self, x):
1359 return False
1360 def __len__(self):
1361 return 0
1362 def __iter__(self):
1363 return iter([])
1364 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001365
Benjamin Peterson41181742008-07-02 20:22:54 +00001366 def test_hash_Set(self):
1367 class OneTwoThreeSet(Set):
1368 def __init__(self):
1369 self.contents = [1, 2, 3]
1370 def __contains__(self, x):
1371 return x in self.contents
1372 def __len__(self):
1373 return len(self.contents)
1374 def __iter__(self):
1375 return iter(self.contents)
1376 def __hash__(self):
1377 return self._hash()
1378 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001379 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001380
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001381 def test_isdisjoint_Set(self):
1382 class MySet(Set):
1383 def __init__(self, itr):
1384 self.contents = itr
1385 def __contains__(self, x):
1386 return x in self.contents
1387 def __iter__(self):
1388 return iter(self.contents)
1389 def __len__(self):
1390 return len([x for x in self.contents])
1391 s1 = MySet((1, 2, 3))
1392 s2 = MySet((4, 5, 6))
1393 s3 = MySet((1, 5, 6))
1394 self.assertTrue(s1.isdisjoint(s2))
1395 self.assertFalse(s1.isdisjoint(s3))
1396
1397 def test_equality_Set(self):
1398 class MySet(Set):
1399 def __init__(self, itr):
1400 self.contents = itr
1401 def __contains__(self, x):
1402 return x in self.contents
1403 def __iter__(self):
1404 return iter(self.contents)
1405 def __len__(self):
1406 return len([x for x in self.contents])
1407 s1 = MySet((1,))
1408 s2 = MySet((1, 2))
1409 s3 = MySet((3, 4))
1410 s4 = MySet((3, 4))
1411 self.assertTrue(s2 > s1)
1412 self.assertTrue(s1 < s2)
1413 self.assertFalse(s2 <= s1)
1414 self.assertFalse(s2 <= s3)
1415 self.assertFalse(s1 >= s2)
1416 self.assertEqual(s3, s4)
1417 self.assertNotEqual(s2, s3)
1418
1419 def test_arithmetic_Set(self):
1420 class MySet(Set):
1421 def __init__(self, itr):
1422 self.contents = itr
1423 def __contains__(self, x):
1424 return x in self.contents
1425 def __iter__(self):
1426 return iter(self.contents)
1427 def __len__(self):
1428 return len([x for x in self.contents])
1429 s1 = MySet((1, 2, 3))
1430 s2 = MySet((3, 4, 5))
1431 s3 = s1 & s2
1432 self.assertEqual(s3, MySet((3,)))
1433
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001434 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001435 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001436 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001437 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001438 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001439 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1440 'add', 'discard')
1441
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001442 def test_issue_5647(self):
1443 # MutableSet.__iand__ mutated the set during iteration
1444 s = WithSet('abcd')
1445 s &= WithSet('cdef') # This used to fail
1446 self.assertEqual(set(s), set('cd'))
1447
Raymond Hettingerae650182009-01-28 23:33:59 +00001448 def test_issue_4920(self):
1449 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001450 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001451 __slots__=['__s']
1452 def __init__(self,items=None):
1453 if items is None:
1454 items=[]
1455 self.__s=set(items)
1456 def __contains__(self,v):
1457 return v in self.__s
1458 def __iter__(self):
1459 return iter(self.__s)
1460 def __len__(self):
1461 return len(self.__s)
1462 def add(self,v):
1463 result=v not in self.__s
1464 self.__s.add(v)
1465 return result
1466 def discard(self,v):
1467 result=v in self.__s
1468 self.__s.discard(v)
1469 return result
1470 def __repr__(self):
1471 return "MySet(%s)" % repr(list(self))
1472 s = MySet([5,43,2,1])
1473 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001474
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001475 def test_issue8750(self):
1476 empty = WithSet()
1477 full = WithSet(range(10))
1478 s = WithSet(full)
1479 s -= s
1480 self.assertEqual(s, empty)
1481 s = WithSet(full)
1482 s ^= s
1483 self.assertEqual(s, empty)
1484 s = WithSet(full)
1485 s &= s
1486 self.assertEqual(s, full)
1487 s |= s
1488 self.assertEqual(s, full)
1489
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001490 def test_issue16373(self):
1491 # Recursion error comparing comparable and noncomparable
1492 # Set instances
1493 class MyComparableSet(Set):
1494 def __contains__(self, x):
1495 return False
1496 def __len__(self):
1497 return 0
1498 def __iter__(self):
1499 return iter([])
1500 class MyNonComparableSet(Set):
1501 def __contains__(self, x):
1502 return False
1503 def __len__(self):
1504 return 0
1505 def __iter__(self):
1506 return iter([])
1507 def __le__(self, x):
1508 return NotImplemented
1509 def __lt__(self, x):
1510 return NotImplemented
1511
1512 cs = MyComparableSet()
1513 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001514 self.assertFalse(ncs < cs)
1515 self.assertTrue(ncs <= cs)
1516 self.assertFalse(ncs > cs)
1517 self.assertTrue(ncs >= cs)
1518
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001519 def test_issue26915(self):
1520 # Container membership test should check identity first
Xiang Zhangd5d32492017-03-08 11:04:24 +08001521 class CustomSequence(Sequence):
1522 def __init__(self, seq):
1523 self._seq = seq
1524 def __getitem__(self, index):
1525 return self._seq[index]
1526 def __len__(self):
1527 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001528
1529 nan = float('nan')
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03001530 obj = support.NEVER_EQ
Xiang Zhangd5d32492017-03-08 11:04:24 +08001531 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001532 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001533 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001534 ItemsView({1: nan, 2: obj}),
1535 ValuesView({1: nan, 2: obj})
1536 ]
1537 for container in containers:
1538 for elem in container:
1539 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001540 self.assertEqual(seq.index(nan), 0)
1541 self.assertEqual(seq.index(obj), 1)
1542 self.assertEqual(seq.count(nan), 2)
1543 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001544
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001545 def assertSameSet(self, s1, s2):
1546 # coerce both to a real set then check equality
1547 self.assertSetEqual(set(s1), set(s2))
1548
1549 def test_Set_interoperability_with_real_sets(self):
1550 # Issue: 8743
1551 class ListSet(Set):
1552 def __init__(self, elements=()):
1553 self.data = []
1554 for elem in elements:
1555 if elem not in self.data:
1556 self.data.append(elem)
1557 def __contains__(self, elem):
1558 return elem in self.data
1559 def __iter__(self):
1560 return iter(self.data)
1561 def __len__(self):
1562 return len(self.data)
1563 def __repr__(self):
1564 return 'Set({!r})'.format(self.data)
1565
1566 r1 = set('abc')
1567 r2 = set('bcd')
1568 r3 = set('abcde')
1569 f1 = ListSet('abc')
1570 f2 = ListSet('bcd')
1571 f3 = ListSet('abcde')
1572 l1 = list('abccba')
1573 l2 = list('bcddcb')
1574 l3 = list('abcdeedcba')
1575
1576 target = r1 & r2
1577 self.assertSameSet(f1 & f2, target)
1578 self.assertSameSet(f1 & r2, target)
1579 self.assertSameSet(r2 & f1, target)
1580 self.assertSameSet(f1 & l2, target)
1581
1582 target = r1 | r2
1583 self.assertSameSet(f1 | f2, target)
1584 self.assertSameSet(f1 | r2, target)
1585 self.assertSameSet(r2 | f1, target)
1586 self.assertSameSet(f1 | l2, target)
1587
1588 fwd_target = r1 - r2
1589 rev_target = r2 - r1
1590 self.assertSameSet(f1 - f2, fwd_target)
1591 self.assertSameSet(f2 - f1, rev_target)
1592 self.assertSameSet(f1 - r2, fwd_target)
1593 self.assertSameSet(f2 - r1, rev_target)
1594 self.assertSameSet(r1 - f2, fwd_target)
1595 self.assertSameSet(r2 - f1, rev_target)
1596 self.assertSameSet(f1 - l2, fwd_target)
1597 self.assertSameSet(f2 - l1, rev_target)
1598
1599 target = r1 ^ r2
1600 self.assertSameSet(f1 ^ f2, target)
1601 self.assertSameSet(f1 ^ r2, target)
1602 self.assertSameSet(r2 ^ f1, target)
1603 self.assertSameSet(f1 ^ l2, target)
1604
1605 # Don't change the following to use assertLess or other
1606 # "more specific" unittest assertions. The current
1607 # assertTrue/assertFalse style makes the pattern of test
1608 # case combinations clear and allows us to know for sure
1609 # the exact operator being invoked.
1610
1611 # proper subset
1612 self.assertTrue(f1 < f3)
1613 self.assertFalse(f1 < f1)
1614 self.assertFalse(f1 < f2)
1615 self.assertTrue(r1 < f3)
1616 self.assertFalse(r1 < f1)
1617 self.assertFalse(r1 < f2)
1618 self.assertTrue(r1 < r3)
1619 self.assertFalse(r1 < r1)
1620 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001621 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001622 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001623 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001624 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001625 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001626 f1 < l2
1627
1628 # any subset
1629 self.assertTrue(f1 <= f3)
1630 self.assertTrue(f1 <= f1)
1631 self.assertFalse(f1 <= f2)
1632 self.assertTrue(r1 <= f3)
1633 self.assertTrue(r1 <= f1)
1634 self.assertFalse(r1 <= f2)
1635 self.assertTrue(r1 <= r3)
1636 self.assertTrue(r1 <= r1)
1637 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001638 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001639 f1 <= l3
1640 with self.assertRaises(TypeError):
1641 f1 <= l1
1642 with self.assertRaises(TypeError):
1643 f1 <= l2
1644
1645 # proper superset
1646 self.assertTrue(f3 > f1)
1647 self.assertFalse(f1 > f1)
1648 self.assertFalse(f2 > f1)
1649 self.assertTrue(r3 > r1)
1650 self.assertFalse(f1 > r1)
1651 self.assertFalse(f2 > r1)
1652 self.assertTrue(r3 > r1)
1653 self.assertFalse(r1 > r1)
1654 self.assertFalse(r2 > r1)
1655 with self.assertRaises(TypeError):
1656 f1 > l3
1657 with self.assertRaises(TypeError):
1658 f1 > l1
1659 with self.assertRaises(TypeError):
1660 f1 > l2
1661
1662 # any superset
1663 self.assertTrue(f3 >= f1)
1664 self.assertTrue(f1 >= f1)
1665 self.assertFalse(f2 >= f1)
1666 self.assertTrue(r3 >= r1)
1667 self.assertTrue(f1 >= r1)
1668 self.assertFalse(f2 >= r1)
1669 self.assertTrue(r3 >= r1)
1670 self.assertTrue(r1 >= r1)
1671 self.assertFalse(r2 >= r1)
1672 with self.assertRaises(TypeError):
1673 f1 >= l3
1674 with self.assertRaises(TypeError):
1675 f1 >=l1
1676 with self.assertRaises(TypeError):
1677 f1 >= l2
1678
1679 # equality
1680 self.assertTrue(f1 == f1)
1681 self.assertTrue(r1 == f1)
1682 self.assertTrue(f1 == r1)
1683 self.assertFalse(f1 == f3)
1684 self.assertFalse(r1 == f3)
1685 self.assertFalse(f1 == r3)
1686 self.assertFalse(f1 == l3)
1687 self.assertFalse(f1 == l1)
1688 self.assertFalse(f1 == l2)
1689
1690 # inequality
1691 self.assertFalse(f1 != f1)
1692 self.assertFalse(r1 != f1)
1693 self.assertFalse(f1 != r1)
1694 self.assertTrue(f1 != f3)
1695 self.assertTrue(r1 != f3)
1696 self.assertTrue(f1 != r3)
1697 self.assertTrue(f1 != l3)
1698 self.assertTrue(f1 != l1)
1699 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001700
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001701 def test_Mapping(self):
1702 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001703 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001704 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001705 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1706 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001707 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001708 def __len__(self):
1709 return 0
1710 def __getitem__(self, i):
1711 raise IndexError
1712 def __iter__(self):
1713 return iter(())
1714 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001715 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001716
1717 def test_MutableMapping(self):
1718 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001719 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001720 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001721 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1722 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001723
Raymond Hettinger9117c752010-08-22 07:44:24 +00001724 def test_MutableMapping_subclass(self):
1725 # Test issue 9214
1726 mymap = UserDict()
1727 mymap['red'] = 5
1728 self.assertIsInstance(mymap.keys(), Set)
1729 self.assertIsInstance(mymap.keys(), KeysView)
1730 self.assertIsInstance(mymap.items(), Set)
1731 self.assertIsInstance(mymap.items(), ItemsView)
1732
1733 mymap = UserDict()
1734 mymap['red'] = 5
1735 z = mymap.keys() | {'orange'}
1736 self.assertIsInstance(z, set)
1737 list(z)
1738 mymap['blue'] = 7 # Shouldn't affect 'z'
1739 self.assertEqual(sorted(z), ['orange', 'red'])
1740
1741 mymap = UserDict()
1742 mymap['red'] = 5
1743 z = mymap.items() | {('orange', 3)}
1744 self.assertIsInstance(z, set)
1745 list(z)
1746 mymap['blue'] = 7 # Shouldn't affect 'z'
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001747 self.assertEqual(z, {('orange', 3), ('red', 5)})
Raymond Hettinger9117c752010-08-22 07:44:24 +00001748
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001749 def test_Sequence(self):
1750 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001751 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001752 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001753 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001754 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001755 self.assertIsInstance(memoryview(b""), Sequence)
1756 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001757 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001758 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1759 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001760
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001761 def test_Sequence_mixins(self):
1762 class SequenceSubclass(Sequence):
1763 def __init__(self, seq=()):
1764 self.seq = seq
1765
1766 def __getitem__(self, index):
1767 return self.seq[index]
1768
1769 def __len__(self):
1770 return len(self.seq)
1771
1772 # Compare Sequence.index() behavior to (list|str).index() behavior
1773 def assert_index_same(seq1, seq2, index_args):
1774 try:
1775 expected = seq1.index(*index_args)
1776 except ValueError:
1777 with self.assertRaises(ValueError):
1778 seq2.index(*index_args)
1779 else:
1780 actual = seq2.index(*index_args)
1781 self.assertEqual(
1782 actual, expected, '%r.index%s' % (seq1, index_args))
1783
1784 for ty in list, str:
1785 nativeseq = ty('abracadabra')
1786 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1787 seqseq = SequenceSubclass(nativeseq)
1788 for letter in set(nativeseq) | {'z'}:
1789 assert_index_same(nativeseq, seqseq, (letter,))
1790 for start in range(-3, len(nativeseq) + 3):
1791 assert_index_same(nativeseq, seqseq, (letter, start))
1792 for stop in range(-3, len(nativeseq) + 3):
1793 assert_index_same(
1794 nativeseq, seqseq, (letter, start, stop))
1795
Guido van Rossumd05eb002007-11-21 22:26:24 +00001796 def test_ByteString(self):
1797 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001798 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001799 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001800 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001801 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001802 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001803 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001804 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001805
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001806 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001807 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001808 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001809 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001810 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001811 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001812 self.assertTrue(issubclass(sample, MutableSequence))
1813 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001814 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1815 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001816
Eli Bendersky0716a572011-03-04 10:38:14 +00001817 def test_MutableSequence_mixins(self):
Mike53f7a7c2017-12-14 14:04:53 +03001818 # Test the mixins of MutableSequence by creating a minimal concrete
Eli Bendersky0716a572011-03-04 10:38:14 +00001819 # class inherited from it.
1820 class MutableSequenceSubclass(MutableSequence):
1821 def __init__(self):
1822 self.lst = []
1823
1824 def __setitem__(self, index, value):
1825 self.lst[index] = value
1826
1827 def __getitem__(self, index):
1828 return self.lst[index]
1829
1830 def __len__(self):
1831 return len(self.lst)
1832
1833 def __delitem__(self, index):
1834 del self.lst[index]
1835
1836 def insert(self, index, value):
1837 self.lst.insert(index, value)
1838
1839 mss = MutableSequenceSubclass()
1840 mss.append(0)
1841 mss.extend((1, 2, 3, 4))
1842 self.assertEqual(len(mss), 5)
1843 self.assertEqual(mss[3], 3)
1844 mss.reverse()
1845 self.assertEqual(mss[3], 1)
1846 mss.pop()
1847 self.assertEqual(len(mss), 4)
1848 mss.remove(3)
1849 self.assertEqual(len(mss), 3)
1850 mss += (10, 20, 30)
1851 self.assertEqual(len(mss), 6)
1852 self.assertEqual(mss[-1], 30)
1853 mss.clear()
1854 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001855
Naris R1b5f9c92018-08-31 02:56:14 +10001856 # issue 34427
1857 # extending self should not cause infinite loop
1858 items = 'ABCD'
1859 mss2 = MutableSequenceSubclass()
1860 mss2.extend(items + items)
1861 mss.clear()
1862 mss.extend(items)
1863 mss.extend(mss)
1864 self.assertEqual(len(mss), len(mss2))
1865 self.assertEqual(list(mss), list(mss2))
1866
1867
Raymond Hettinger499e1932011-02-23 07:56:53 +00001868################################################################################
1869### Counter
1870################################################################################
1871
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001872class CounterSubclassWithSetItem(Counter):
1873 # Test a counter subclass that overrides __setitem__
1874 def __init__(self, *args, **kwds):
1875 self.called = False
1876 Counter.__init__(self, *args, **kwds)
1877 def __setitem__(self, key, value):
1878 self.called = True
1879 Counter.__setitem__(self, key, value)
1880
1881class CounterSubclassWithGet(Counter):
1882 # Test a counter subclass that overrides get()
1883 def __init__(self, *args, **kwds):
1884 self.called = False
1885 Counter.__init__(self, *args, **kwds)
1886 def get(self, key, default):
1887 self.called = True
1888 return Counter.get(self, key, default)
1889
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001890class TestCounter(unittest.TestCase):
1891
1892 def test_basics(self):
1893 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001894 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1895 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001896 self.assertIsInstance(c, dict)
1897 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001898 self.assertTrue(issubclass(Counter, dict))
1899 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001900 self.assertEqual(len(c), 3)
1901 self.assertEqual(sum(c.values()), 6)
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001902 self.assertEqual(list(c.values()), [3, 2, 1])
1903 self.assertEqual(list(c.keys()), ['a', 'b', 'c'])
1904 self.assertEqual(list(c), ['a', 'b', 'c'])
1905 self.assertEqual(list(c.items()),
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001906 [('a', 3), ('b', 2), ('c', 1)])
1907 self.assertEqual(c['b'], 2)
1908 self.assertEqual(c['z'], 0)
1909 self.assertEqual(c.__contains__('c'), True)
1910 self.assertEqual(c.__contains__('z'), False)
1911 self.assertEqual(c.get('b', 10), 2)
1912 self.assertEqual(c.get('z', 10), 10)
1913 self.assertEqual(c, dict(a=3, b=2, c=1))
1914 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1915 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1916 for i in range(5):
1917 self.assertEqual(c.most_common(i),
1918 [('a', 3), ('b', 2), ('c', 1)][:i])
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001919 self.assertEqual(''.join(c.elements()), 'aaabbc')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001920 c['a'] += 1 # increment an existing value
1921 c['b'] -= 2 # sub existing value to zero
1922 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001923 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001924 c['d'] -= 2 # sub from a missing value
1925 c['e'] = -5 # directly assign a missing value
1926 c['f'] += 4 # add to a missing value
1927 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001928 self.assertEqual(''.join(c.elements()), 'aaaaffff')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001929 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001930 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001931 for i in range(3):
1932 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001933 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001934 c.clear()
1935 self.assertEqual(c, {})
1936 self.assertEqual(repr(c), 'Counter()')
1937 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1938 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001939 c.update(dict(a=5, b=3))
1940 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001941 c.update(Counter('a' * 50 + 'b' * 30))
1942 c.update() # test case with no args
1943 c.__init__('a' * 500 + 'b' * 300)
1944 c.__init__('cdc')
1945 c.__init__()
1946 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1947 self.assertEqual(c.setdefault('d', 5), 1)
1948 self.assertEqual(c['d'], 1)
1949 self.assertEqual(c.setdefault('e', 5), 5)
1950 self.assertEqual(c['e'], 5)
1951
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001952 def test_init(self):
1953 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1954 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1955 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1956 self.assertRaises(TypeError, Counter, 42)
1957 self.assertRaises(TypeError, Counter, (), ())
1958 self.assertRaises(TypeError, Counter.__init__)
1959
Raymond Hettinger407c7342019-02-21 09:19:00 -08001960 def test_order_preservation(self):
1961 # Input order dictates items() order
1962 self.assertEqual(list(Counter('abracadabra').items()),
1963 [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])
1964 # letters with same count: ^----------^ ^---------^
1965
1966 # Verify retention of order even when all counts are equal
1967 self.assertEqual(list(Counter('xyzpdqqdpzyx').items()),
1968 [('x', 2), ('y', 2), ('z', 2), ('p', 2), ('d', 2), ('q', 2)])
1969
1970 # Input order dictates elements() order
1971 self.assertEqual(list(Counter('abracadabra simsalabim').elements()),
1972 ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b','r',
1973 'r', 'c', 'd', ' ', 's', 's', 'i', 'i', 'm', 'm', 'l'])
1974
1975 # Math operations order first by the order encountered in the left
Min ho Kim39d87b52019-08-31 06:21:19 +10001976 # operand and then by the order encountered in the right operand.
Raymond Hettinger407c7342019-02-21 09:19:00 -08001977 ps = 'aaabbcdddeefggghhijjjkkl'
1978 qs = 'abbcccdeefffhkkllllmmnno'
1979 order = {letter: i for i, letter in enumerate(dict.fromkeys(ps + qs))}
1980 def correctly_ordered(seq):
1981 'Return true if the letters occur in the expected order'
1982 positions = [order[letter] for letter in seq]
1983 return positions == sorted(positions)
1984
1985 p, q = Counter(ps), Counter(qs)
1986 self.assertTrue(correctly_ordered(+p))
1987 self.assertTrue(correctly_ordered(-p))
1988 self.assertTrue(correctly_ordered(p + q))
1989 self.assertTrue(correctly_ordered(p - q))
1990 self.assertTrue(correctly_ordered(p | q))
1991 self.assertTrue(correctly_ordered(p & q))
1992
1993 p, q = Counter(ps), Counter(qs)
1994 p += q
1995 self.assertTrue(correctly_ordered(p))
1996
1997 p, q = Counter(ps), Counter(qs)
1998 p -= q
1999 self.assertTrue(correctly_ordered(p))
2000
2001 p, q = Counter(ps), Counter(qs)
2002 p |= q
2003 self.assertTrue(correctly_ordered(p))
2004
2005 p, q = Counter(ps), Counter(qs)
2006 p &= q
2007 self.assertTrue(correctly_ordered(p))
2008
2009 p, q = Counter(ps), Counter(qs)
2010 p.update(q)
2011 self.assertTrue(correctly_ordered(p))
2012
2013 p, q = Counter(ps), Counter(qs)
2014 p.subtract(q)
2015 self.assertTrue(correctly_ordered(p))
2016
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02002017 def test_update(self):
2018 c = Counter()
2019 c.update(self=42)
2020 self.assertEqual(list(c.items()), [('self', 42)])
2021 c = Counter()
2022 c.update(iterable=42)
2023 self.assertEqual(list(c.items()), [('iterable', 42)])
2024 c = Counter()
2025 c.update(iterable=None)
2026 self.assertEqual(list(c.items()), [('iterable', None)])
2027 self.assertRaises(TypeError, Counter().update, 42)
2028 self.assertRaises(TypeError, Counter().update, {}, {})
2029 self.assertRaises(TypeError, Counter.update)
2030
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002031 def test_copying(self):
2032 # Check that counters are copyable, deepcopyable, picklable, and
2033 #have a repr/eval round-trip
2034 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02002035 def check(dup):
2036 msg = "\ncopy: %s\nwords: %s" % (dup, words)
2037 self.assertIsNot(dup, words, msg)
2038 self.assertEqual(dup, words)
2039 check(words.copy())
2040 check(copy.copy(words))
2041 check(copy.deepcopy(words))
2042 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2043 with self.subTest(proto=proto):
2044 check(pickle.loads(pickle.dumps(words, proto)))
2045 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002046 update_test = Counter()
2047 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02002048 check(update_test)
2049 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002050
Raymond Hettinger1c746c22011-04-15 13:16:46 -07002051 def test_copy_subclass(self):
2052 class MyCounter(Counter):
2053 pass
2054 c = MyCounter('slartibartfast')
2055 d = c.copy()
2056 self.assertEqual(d, c)
2057 self.assertEqual(len(d), len(c))
2058 self.assertEqual(type(d), type(c))
2059
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002060 def test_conversions(self):
2061 # Convert to: set, list, dict
2062 s = 'she sells sea shells by the sea shore'
2063 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
2064 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
2065 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
2066 self.assertEqual(set(Counter(s)), set(s))
2067
Raymond Hettinger670eaec2009-01-21 23:14:07 +00002068 def test_invariant_for_the_in_operator(self):
2069 c = Counter(a=10, b=-2, c=0)
2070 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002071 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00002072 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00002073
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002074 def test_multiset_operations(self):
2075 # Verify that adding a zero counter will strip zeros and negatives
2076 c = Counter(a=10, b=-2, c=0) + Counter()
2077 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002078
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002079 elements = 'abcd'
2080 for i in range(1000):
2081 # test random pairs of multisets
2082 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00002083 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002084 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00002085 q.update(h=1, i=-1, j=0)
2086 for counterop, numberop in [
2087 (Counter.__add__, lambda x, y: max(0, x+y)),
2088 (Counter.__sub__, lambda x, y: max(0, x-y)),
2089 (Counter.__or__, lambda x, y: max(0,x,y)),
2090 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002091 ]:
2092 result = counterop(p, q)
2093 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00002094 self.assertEqual(numberop(p[x], q[x]), result[x],
2095 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002096 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002097 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002098
2099 elements = 'abcdef'
2100 for i in range(100):
2101 # verify that random multisets with no repeats are exactly like sets
2102 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
2103 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
2104 for counterop, setop in [
2105 (Counter.__sub__, set.__sub__),
2106 (Counter.__or__, set.__or__),
2107 (Counter.__and__, set.__and__),
2108 ]:
2109 counter_result = counterop(p, q)
2110 set_result = setop(set(p.elements()), set(q.elements()))
2111 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002112
Raymond Hettinger1ca8fb12019-12-16 01:54:14 -08002113 def test_subset_superset_not_implemented(self):
2114 # Verify that multiset comparison operations are not implemented.
2115
2116 # These operations were intentionally omitted because multiset
2117 # comparison semantics conflict with existing dict equality semantics.
2118
2119 # For multisets, we would expect that if p<=q and p>=q are both true,
2120 # then p==q. However, dict equality semantics require that p!=q when
2121 # one of sets contains an element with a zero count and the other
2122 # doesn't.
2123
2124 p = Counter(a=1, b=0)
2125 q = Counter(a=1, c=0)
2126 self.assertNotEqual(p, q)
2127 with self.assertRaises(TypeError):
2128 p < q
2129 with self.assertRaises(TypeError):
2130 p <= q
2131 with self.assertRaises(TypeError):
2132 p > q
2133 with self.assertRaises(TypeError):
2134 p >= q
2135
Raymond Hettingerbecd5682011-10-19 13:40:37 -07002136 def test_inplace_operations(self):
2137 elements = 'abcd'
2138 for i in range(1000):
2139 # test random pairs of multisets
2140 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2141 p.update(e=1, f=-1, g=0)
2142 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2143 q.update(h=1, i=-1, j=0)
2144 for inplace_op, regular_op in [
2145 (Counter.__iadd__, Counter.__add__),
2146 (Counter.__isub__, Counter.__sub__),
2147 (Counter.__ior__, Counter.__or__),
2148 (Counter.__iand__, Counter.__and__),
2149 ]:
2150 c = p.copy()
2151 c_id = id(c)
2152 regular_result = regular_op(c, q)
2153 inplace_result = inplace_op(c, q)
2154 self.assertEqual(inplace_result, regular_result)
2155 self.assertEqual(id(inplace_result), c_id)
2156
Raymond Hettinger9c01e442010-04-03 10:32:58 +00002157 def test_subtract(self):
2158 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2159 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
2160 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
2161 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2162 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
2163 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
2164 c = Counter('aaabbcd')
2165 c.subtract('aaaabbcce')
2166 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002167
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02002168 c = Counter()
2169 c.subtract(self=42)
2170 self.assertEqual(list(c.items()), [('self', -42)])
2171 c = Counter()
2172 c.subtract(iterable=42)
2173 self.assertEqual(list(c.items()), [('iterable', -42)])
2174 self.assertRaises(TypeError, Counter().subtract, 42)
2175 self.assertRaises(TypeError, Counter().subtract, {}, {})
2176 self.assertRaises(TypeError, Counter.subtract)
2177
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07002178 def test_unary(self):
2179 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2180 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
2181 self.assertEqual(dict(-c), dict(a=5))
2182
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07002183 def test_repr_nonsortable(self):
2184 c = Counter(a=2, b=None)
2185 r = repr(c)
2186 self.assertIn("'a': 2", r)
2187 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07002188
Raymond Hettinger426e0522011-01-03 02:12:02 +00002189 def test_helper_function(self):
2190 # two paths, one for real dicts and one for other mappings
2191 elems = list('abracadabra')
2192
2193 d = dict()
2194 _count_elements(d, elems)
2195 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
2196
2197 m = OrderedDict()
2198 _count_elements(m, elems)
2199 self.assertEqual(m,
2200 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
2201
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002202 # test fidelity to the pure python version
2203 c = CounterSubclassWithSetItem('abracadabra')
2204 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07002205 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002206 c = CounterSubclassWithGet('abracadabra')
2207 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07002208 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002209
Raymond Hettinger499e1932011-02-23 07:56:53 +00002210
2211################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00002212### Run tests
2213################################################################################
2214
Guido van Rossumd8faa362007-04-27 19:54:29 +00002215def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00002216 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002217 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00002218 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06002219 TestUserObjects,
2220 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002221 support.run_unittest(*test_classes)
2222 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002223
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002224
Guido van Rossumd8faa362007-04-27 19:54:29 +00002225if __name__ == "__main__":
2226 test_main(verbose=True)