blob: a8d3337ef5288d18f8756ced408555e0861759ce [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
Ammar Askara86b5222020-04-14 23:36:08 -0700414 @support.cpython_only
415 def test_field_repr(self):
416 Point = namedtuple('Point', 'x y')
417 self.assertEqual(repr(Point.x), "_tuplegetter(0, 'Alias for field number 0')")
418 self.assertEqual(repr(Point.y), "_tuplegetter(1, 'Alias for field number 1')")
419
420 Point.x.__doc__ = 'The x-coordinate'
421 Point.y.__doc__ = 'The y-coordinate'
422
423 self.assertEqual(repr(Point.x), "_tuplegetter(0, 'The x-coordinate')")
424 self.assertEqual(repr(Point.y), "_tuplegetter(1, 'The y-coordinate')")
425
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000426 def test_name_fixer(self):
427 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000428 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
429 [('abc', 'class'), ('abc', '_1')], # field has keyword
430 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
431 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
432 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
433 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000434 ]:
435 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
436
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700437 def test_module_parameter(self):
438 NT = namedtuple('NT', ['x', 'y'], module=collections)
439 self.assertEqual(NT.__module__, collections)
440
Guido van Rossumd8faa362007-04-27 19:54:29 +0000441 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000442 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000443 p = Point(11, 22)
444 self.assertEqual(p, Point(x=11, y=22))
445 self.assertEqual(p, Point(11, y=22))
446 self.assertEqual(p, Point(y=22, x=11))
447 self.assertEqual(p, Point(*(11, 22)))
448 self.assertEqual(p, Point(**dict(x=11, y=22)))
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200449 self.assertRaises(TypeError, Point, 1) # too few args
450 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
451 with self.assertRaises(TypeError): # wrong keyword argument
452 Point(XXX=1, y=2)
453 with self.assertRaises(TypeError): # missing keyword argument
454 Point(x=1)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000455 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000456 self.assertNotIn('__weakref__', dir(p))
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200457 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
458 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
459 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
460 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000461
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000462 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000463 p._replace(x=1, error=2)
464 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000465 pass
466 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000467 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000468
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000469 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000470 Point = namedtuple('Point', 'x, y')
471 p = Point(x=11, y=22)
472 self.assertEqual(repr(p), 'Point(x=11, y=22)')
473
474 # verify that fieldspec can be a non-string sequence
475 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000476 p = Point(x=11, y=22)
477 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000478
479 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000480 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000481 p = Point(11, 22)
482
Ezio Melottie9615932010-01-24 19:26:24 +0000483 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000484 self.assertEqual(p, (11, 22)) # matches a real tuple
Min ho Kimc4cacc82019-07-31 08:16:13 +1000485 self.assertEqual(tuple(p), (11, 22)) # coercible to a real tuple
486 self.assertEqual(list(p), [11, 22]) # coercible to a list
Guido van Rossumd8faa362007-04-27 19:54:29 +0000487 self.assertEqual(max(p), 22) # iterable
488 self.assertEqual(max(*p), 22) # star-able
489 x, y = p
490 self.assertEqual(p, (x, y)) # unpacks like a tuple
491 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200492 with self.assertRaises(IndexError):
493 p[3]
494 self.assertEqual(p[-1], 22)
495 self.assertEqual(hash(p), hash((11, 22)))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000496
497 self.assertEqual(p.x, x)
498 self.assertEqual(p.y, y)
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200499 with self.assertRaises(AttributeError):
500 p.z
Guido van Rossumd8faa362007-04-27 19:54:29 +0000501
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000502 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000503 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000504 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000505 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000506 self.assertEqual(repr(Zero()), 'Zero()')
507 self.assertEqual(Zero()._asdict(), {})
508 self.assertEqual(Zero()._fields, ())
509
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000510 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000511 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000512 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000513 self.assertEqual(Dot(1).d, 1)
514 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
515 self.assertEqual(Dot(1)._asdict(), {'d':1})
516 self.assertEqual(Dot(1)._replace(d=999), (999,))
517 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000518
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200519 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200520 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000521 for j in range(10)]) for i in range(n)))
522 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000523 Big = namedtuple('Big', names)
524 b = Big(*range(n))
525 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000526 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000527 for pos, name in enumerate(names):
528 self.assertEqual(getattr(b, name), pos)
529 repr(b) # make sure repr() doesn't blow-up
530 d = b._asdict()
531 d_expected = dict(zip(names, range(n)))
532 self.assertEqual(d, d_expected)
533 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
534 b2_expected = list(range(n))
535 b2_expected[1] = 999
536 b2_expected[-5] = 42
537 self.assertEqual(b2, tuple(b2_expected))
538 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000539
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000540 def test_pickle(self):
541 p = TestNT(x=10, y=20, z=30)
542 for module in (pickle,):
543 loads = getattr(module, 'loads')
544 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500545 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000546 q = loads(dumps(p, protocol))
547 self.assertEqual(p, q)
548 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700549 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000550
551 def test_copy(self):
552 p = TestNT(x=10, y=20, z=30)
553 for copier in copy.copy, copy.deepcopy:
554 q = copier(p)
555 self.assertEqual(p, q)
556 self.assertEqual(p._fields, q._fields)
557
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000558 def test_name_conflicts(self):
559 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
560 # failed when used as field names. Test to make sure these now work.
561 T = namedtuple('T', 'itemgetter property self cls tuple')
562 t = T(1, 2, 3, 4, 5)
563 self.assertEqual(t, (1,2,3,4,5))
564 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
565 self.assertEqual(newt, (10,20,30,40,50))
566
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700567 # Broader test of all interesting names taken from the code, old
568 # template, and an example
569 words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create',
570 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper',
571 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note',
572 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError',
573 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add',
574 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments',
575 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot',
576 'class_namespace', 'classmethod', 'cls', 'collections', 'convert',
577 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict',
578 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect',
579 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f',
580 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame',
581 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater',
582 'has', 'help', 'identifiers', 'index', 'indexable', 'instance',
583 'instantiate', 'interning', 'introspection', 'isidentifier',
584 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords',
585 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata',
586 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named',
587 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new',
588 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option',
589 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional',
590 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr',
591 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen',
592 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start',
593 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys',
594 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new',
595 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use',
596 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where',
597 'which', 'work', 'x', 'y', 'z', 'zip'}
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000598 T = namedtuple('T', words)
599 # test __new__
600 values = tuple(range(len(words)))
601 t = T(*values)
602 self.assertEqual(t, values)
603 t = T(**dict(zip(T._fields, values)))
604 self.assertEqual(t, values)
605 # test _make
606 t = T._make(values)
607 self.assertEqual(t, values)
608 # exercise __repr__
609 repr(t)
610 # test _asdict
611 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
612 # test _replace
613 t = T._make(values)
614 newvalues = tuple(v*10 for v in values)
615 newt = t._replace(**dict(zip(T._fields, newvalues)))
616 self.assertEqual(newt, newvalues)
617 # test _fields
618 self.assertEqual(T._fields, tuple(words))
619 # test __getnewargs__
620 self.assertEqual(t.__getnewargs__(), values)
621
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000622 def test_repr(self):
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700623 A = namedtuple('A', 'x')
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000624 self.assertEqual(repr(A(1)), 'A(x=1)')
625 # repr should show the name of the subclass
626 class B(A):
627 pass
628 self.assertEqual(repr(B(1)), 'B(x=1)')
629
Raymond Hettinger6538b432016-08-16 10:55:43 -0700630 def test_keyword_only_arguments(self):
631 # See issue 25628
Raymond Hettinger6538b432016-08-16 10:55:43 -0700632 with self.assertRaises(TypeError):
633 NT = namedtuple('NT', ['x', 'y'], True)
634
635 NT = namedtuple('NT', ['abc', 'def'], rename=True)
636 self.assertEqual(NT._fields, ('abc', '_1'))
637 with self.assertRaises(TypeError):
638 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000639
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700640 def test_namedtuple_subclass_issue_24931(self):
641 class Point(namedtuple('_Point', ['x', 'y'])):
642 pass
643
644 a = Point(3, 4)
645 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
646
647 a.w = 5
648 self.assertEqual(a.__dict__, {'w': 5})
649
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200650 def test_field_descriptor(self):
651 Point = namedtuple('Point', 'x y')
652 p = Point(11, 22)
653 self.assertTrue(inspect.isdatadescriptor(Point.x))
654 self.assertEqual(Point.x.__get__(p), 11)
655 self.assertRaises(AttributeError, Point.x.__set__, p, 33)
656 self.assertRaises(AttributeError, Point.x.__delete__, p)
Pablo Galindo3f5fc702018-12-30 09:24:03 +0000657
Joe Jevnikf36f8922019-02-21 16:00:40 -0500658 class NewPoint(tuple):
659 x = pickle.loads(pickle.dumps(Point.x))
660 y = pickle.loads(pickle.dumps(Point.y))
661
662 np = NewPoint([1, 2])
663
664 self.assertEqual(np.x, 1)
665 self.assertEqual(np.y, 2)
666
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700667
Raymond Hettinger499e1932011-02-23 07:56:53 +0000668################################################################################
669### Abstract Base Classes
670################################################################################
671
Raymond Hettingerae650182009-01-28 23:33:59 +0000672class ABCTestCase(unittest.TestCase):
673
674 def validate_abstract_methods(self, abc, *names):
675 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
676
677 # everything should work will all required methods are present
678 C = type('C', (abc,), methodstubs)
679 C()
680
681 # instantiation should fail if a required method is missing
682 for name in names:
683 stubs = methodstubs.copy()
684 del stubs[name]
685 C = type('C', (abc,), stubs)
686 self.assertRaises(TypeError, C, name)
687
Florent Xiclunace153f62010-03-08 15:34:35 +0000688 def validate_isinstance(self, abc, name):
689 stub = lambda s, *args: 0
690
691 C = type('C', (object,), {'__hash__': None})
692 setattr(C, name, stub)
693 self.assertIsInstance(C(), abc)
694 self.assertTrue(issubclass(C, abc))
695
696 C = type('C', (object,), {'__hash__': None})
697 self.assertNotIsInstance(C(), abc)
698 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000699
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000700 def validate_comparison(self, instance):
701 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
702 operators = {}
703 for op in ops:
704 name = '__' + op + '__'
705 operators[name] = getattr(operator, name)
706
707 class Other:
708 def __init__(self):
709 self.right_side = False
710 def __eq__(self, other):
711 self.right_side = True
712 return True
713 __lt__ = __eq__
714 __gt__ = __eq__
715 __le__ = __eq__
716 __ge__ = __eq__
717 __ne__ = __eq__
718 __ror__ = __eq__
719 __rand__ = __eq__
720 __rxor__ = __eq__
721 __rsub__ = __eq__
722
723 for name, op in operators.items():
724 if not hasattr(instance, name):
725 continue
726 other = Other()
727 op(instance, other)
728 self.assertTrue(other.right_side,'Right side not called for %s.%s'
729 % (type(instance), name))
730
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700731def _test_gen():
732 yield
733
Raymond Hettingerae650182009-01-28 23:33:59 +0000734class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000735
Yury Selivanov75445082015-05-11 22:57:16 -0400736 def test_Awaitable(self):
737 def gen():
738 yield
739
740 @types.coroutine
741 def coro():
742 yield
743
744 async def new_coro():
745 pass
746
747 class Bar:
748 def __await__(self):
749 yield
750
751 class MinimalCoro(Coroutine):
752 def send(self, value):
753 return value
754 def throw(self, typ, val=None, tb=None):
755 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400756 def __await__(self):
757 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400758
759 non_samples = [None, int(), gen(), object()]
760 for x in non_samples:
761 self.assertNotIsInstance(x, Awaitable)
762 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
763
764 samples = [Bar(), MinimalCoro()]
765 for x in samples:
766 self.assertIsInstance(x, Awaitable)
767 self.assertTrue(issubclass(type(x), Awaitable))
768
769 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400770 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
771 # flag don't have '__await__' method, hence can't be instances
772 # of Awaitable. Use inspect.isawaitable to detect them.
773 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400774
775 c = new_coro()
776 self.assertIsInstance(c, Awaitable)
Mike53f7a7c2017-12-14 14:04:53 +0300777 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400778
Yury Selivanov56fc6142015-05-29 09:01:29 -0400779 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400780 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400781 self.assertTrue(isinstance(CoroLike(), Awaitable))
782 self.assertTrue(issubclass(CoroLike, Awaitable))
783 CoroLike = None
784 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400785
Yury Selivanov75445082015-05-11 22:57:16 -0400786 def test_Coroutine(self):
787 def gen():
788 yield
789
790 @types.coroutine
791 def coro():
792 yield
793
794 async def new_coro():
795 pass
796
797 class Bar:
798 def __await__(self):
799 yield
800
801 class MinimalCoro(Coroutine):
802 def send(self, value):
803 return value
804 def throw(self, typ, val=None, tb=None):
805 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400806 def __await__(self):
807 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400808
809 non_samples = [None, int(), gen(), object(), Bar()]
810 for x in non_samples:
811 self.assertNotIsInstance(x, Coroutine)
812 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
813
814 samples = [MinimalCoro()]
815 for x in samples:
816 self.assertIsInstance(x, Awaitable)
817 self.assertTrue(issubclass(type(x), Awaitable))
818
819 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400820 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
821 # flag don't have '__await__' method, hence can't be instances
822 # of Coroutine. Use inspect.isawaitable to detect them.
823 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400824
825 c = new_coro()
826 self.assertIsInstance(c, Coroutine)
Mike53f7a7c2017-12-14 14:04:53 +0300827 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400828
Yury Selivanov56fc6142015-05-29 09:01:29 -0400829 class CoroLike:
830 def send(self, value):
831 pass
832 def throw(self, typ, val=None, tb=None):
833 pass
834 def close(self):
835 pass
836 def __await__(self):
837 pass
838 self.assertTrue(isinstance(CoroLike(), Coroutine))
839 self.assertTrue(issubclass(CoroLike, Coroutine))
840
841 class CoroLike:
842 def send(self, value):
843 pass
844 def close(self):
845 pass
846 def __await__(self):
847 pass
848 self.assertFalse(isinstance(CoroLike(), Coroutine))
849 self.assertFalse(issubclass(CoroLike, Coroutine))
850
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000851 def test_Hashable(self):
852 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000853 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000854 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000855 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000856 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000857 # Check some hashables
858 samples = [None,
859 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000860 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000861 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000862 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000863 ]
864 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000865 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000866 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000867 self.assertRaises(TypeError, Hashable)
868 # Check direct subclassing
869 class H(Hashable):
870 def __hash__(self):
871 return super().__hash__()
872 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000873 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000874 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000875 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000876
Yury Selivanove0104ae2015-05-14 12:19:16 -0400877 def test_AsyncIterable(self):
878 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400879 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400880 return self
881 self.assertTrue(isinstance(AI(), AsyncIterable))
882 self.assertTrue(issubclass(AI, AsyncIterable))
883 # Check some non-iterables
884 non_samples = [None, object, []]
885 for x in non_samples:
886 self.assertNotIsInstance(x, AsyncIterable)
887 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
888 self.validate_abstract_methods(AsyncIterable, '__aiter__')
889 self.validate_isinstance(AsyncIterable, '__aiter__')
890
891 def test_AsyncIterator(self):
892 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400893 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400894 return self
895 async def __anext__(self):
896 raise StopAsyncIteration
897 self.assertTrue(isinstance(AI(), AsyncIterator))
898 self.assertTrue(issubclass(AI, AsyncIterator))
899 non_samples = [None, object, []]
900 # Check some non-iterables
901 for x in non_samples:
902 self.assertNotIsInstance(x, AsyncIterator)
903 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
904 # Similarly to regular iterators (see issue 10565)
905 class AnextOnly:
906 async def __anext__(self):
907 raise StopAsyncIteration
908 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
909 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
910
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000911 def test_Iterable(self):
912 # Check some non-iterables
913 non_samples = [None, 42, 3.14, 1j]
914 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000915 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000916 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000917 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000918 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000919 tuple(), list(), set(), frozenset(), dict(),
920 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700921 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000922 (x for x in []),
923 ]
924 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000925 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000926 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000927 # Check direct subclassing
928 class I(Iterable):
929 def __iter__(self):
930 return super().__iter__()
931 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000932 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000933 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000934 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700935 # Check None blocking
936 class It:
937 def __iter__(self): return iter([])
938 class ItBlocked(It):
939 __iter__ = None
940 self.assertTrue(issubclass(It, Iterable))
941 self.assertTrue(isinstance(It(), Iterable))
942 self.assertFalse(issubclass(ItBlocked, Iterable))
943 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000944
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700945 def test_Reversible(self):
946 # Check some non-reversibles
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100947 non_samples = [None, 42, 3.14, 1j, set(), frozenset()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700948 for x in non_samples:
949 self.assertNotIsInstance(x, Reversible)
950 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700951 # Check some non-reversible iterables
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100952 non_reversibles = [_test_gen(), (x for x in []), iter([]), reversed([])]
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700953 for x in non_reversibles:
954 self.assertNotIsInstance(x, Reversible)
955 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
956 # Check some reversible iterables
957 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
958 OrderedDict().keys(), OrderedDict().items(),
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100959 OrderedDict().values(), Counter(), Counter().keys(),
960 Counter().items(), Counter().values(), dict(),
961 dict().keys(), dict().items(), dict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700962 for x in samples:
963 self.assertIsInstance(x, Reversible)
964 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
965 # Check also Mapping, MutableMapping, and Sequence
966 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
967 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
968 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
969 # Check direct subclassing
970 class R(Reversible):
971 def __iter__(self):
972 return iter(list())
973 def __reversed__(self):
974 return iter(list())
975 self.assertEqual(list(reversed(R())), [])
976 self.assertFalse(issubclass(float, R))
977 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700978 # Check reversible non-iterable (which is not Reversible)
979 class RevNoIter:
980 def __reversed__(self): return reversed([])
981 class RevPlusIter(RevNoIter):
982 def __iter__(self): return iter([])
983 self.assertFalse(issubclass(RevNoIter, Reversible))
984 self.assertFalse(isinstance(RevNoIter(), Reversible))
985 self.assertTrue(issubclass(RevPlusIter, Reversible))
986 self.assertTrue(isinstance(RevPlusIter(), Reversible))
987 # Check None blocking
988 class Rev:
989 def __iter__(self): return iter([])
990 def __reversed__(self): return reversed([])
991 class RevItBlocked(Rev):
992 __iter__ = None
993 class RevRevBlocked(Rev):
994 __reversed__ = None
995 self.assertTrue(issubclass(Rev, Reversible))
996 self.assertTrue(isinstance(Rev(), Reversible))
997 self.assertFalse(issubclass(RevItBlocked, Reversible))
998 self.assertFalse(isinstance(RevItBlocked(), Reversible))
999 self.assertFalse(issubclass(RevRevBlocked, Reversible))
1000 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001001
Guido van Rossumf0666942016-08-23 10:47:07 -07001002 def test_Collection(self):
1003 # Check some non-collections
1004 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
1005 for x in non_collections:
1006 self.assertNotIsInstance(x, Collection)
1007 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
1008 # Check some non-collection iterables
1009 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
Raymond Hettinger02556fb2018-01-11 21:53:49 -08001010 (x for x in [])]
Guido van Rossumf0666942016-08-23 10:47:07 -07001011 for x in non_col_iterables:
1012 self.assertNotIsInstance(x, Collection)
1013 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
1014 # Check some collections
1015 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
Raymond Hettinger02556fb2018-01-11 21:53:49 -08001016 list(), dict().keys(), dict().items(), dict().values()]
Guido van Rossumf0666942016-08-23 10:47:07 -07001017 for x in samples:
1018 self.assertIsInstance(x, Collection)
1019 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
1020 # Check also Mapping, MutableMapping, etc.
1021 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
1022 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
1023 self.assertTrue(issubclass(MutableMapping, Collection),
1024 repr(MutableMapping))
1025 self.assertTrue(issubclass(Set, Collection), repr(Set))
1026 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
1027 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
1028 # Check direct subclassing
1029 class Col(Collection):
1030 def __iter__(self):
1031 return iter(list())
1032 def __len__(self):
1033 return 0
1034 def __contains__(self, item):
1035 return False
1036 class DerCol(Col): pass
1037 self.assertEqual(list(iter(Col())), [])
1038 self.assertFalse(issubclass(list, Col))
1039 self.assertFalse(issubclass(set, Col))
1040 self.assertFalse(issubclass(float, Col))
1041 self.assertEqual(list(iter(DerCol())), [])
1042 self.assertFalse(issubclass(list, DerCol))
1043 self.assertFalse(issubclass(set, DerCol))
1044 self.assertFalse(issubclass(float, DerCol))
1045 self.validate_abstract_methods(Collection, '__len__', '__iter__',
1046 '__contains__')
1047 # Check sized container non-iterable (which is not Collection) etc.
1048 class ColNoIter:
1049 def __len__(self): return 0
1050 def __contains__(self, item): return False
1051 class ColNoSize:
1052 def __iter__(self): return iter([])
1053 def __contains__(self, item): return False
1054 class ColNoCont:
1055 def __iter__(self): return iter([])
1056 def __len__(self): return 0
1057 self.assertFalse(issubclass(ColNoIter, Collection))
1058 self.assertFalse(isinstance(ColNoIter(), Collection))
1059 self.assertFalse(issubclass(ColNoSize, Collection))
1060 self.assertFalse(isinstance(ColNoSize(), Collection))
1061 self.assertFalse(issubclass(ColNoCont, Collection))
1062 self.assertFalse(isinstance(ColNoCont(), Collection))
1063 # Check None blocking
1064 class SizeBlock:
1065 def __iter__(self): return iter([])
1066 def __contains__(self): return False
1067 __len__ = None
1068 class IterBlock:
1069 def __len__(self): return 0
1070 def __contains__(self): return True
1071 __iter__ = None
1072 self.assertFalse(issubclass(SizeBlock, Collection))
1073 self.assertFalse(isinstance(SizeBlock(), Collection))
1074 self.assertFalse(issubclass(IterBlock, Collection))
1075 self.assertFalse(isinstance(IterBlock(), Collection))
1076 # Check None blocking in subclass
1077 class ColImpl:
1078 def __iter__(self):
1079 return iter(list())
1080 def __len__(self):
1081 return 0
1082 def __contains__(self, item):
1083 return False
1084 class NonCol(ColImpl):
1085 __contains__ = None
1086 self.assertFalse(issubclass(NonCol, Collection))
1087 self.assertFalse(isinstance(NonCol(), Collection))
1088
1089
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001090 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +00001091 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001092 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001093 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001094 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001095 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001096 iter(tuple()), iter(list()), iter(dict()),
1097 iter(set()), iter(frozenset()),
1098 iter(dict().keys()), iter(dict().items()),
1099 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001100 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001101 (x for x in []),
1102 ]
1103 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001104 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001105 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +00001106 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
1107
1108 # Issue 10565
1109 class NextOnly:
1110 def __next__(self):
1111 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -08001112 return
Raymond Hettingeread22222010-11-29 03:56:12 +00001113 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001114
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -04001115 def test_Generator(self):
1116 class NonGen1:
1117 def __iter__(self): return self
1118 def __next__(self): return None
1119 def close(self): pass
1120 def throw(self, typ, val=None, tb=None): pass
1121
1122 class NonGen2:
1123 def __iter__(self): return self
1124 def __next__(self): return None
1125 def close(self): pass
1126 def send(self, value): return value
1127
1128 class NonGen3:
1129 def close(self): pass
1130 def send(self, value): return value
1131 def throw(self, typ, val=None, tb=None): pass
1132
1133 non_samples = [
1134 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1135 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
1136 for x in non_samples:
1137 self.assertNotIsInstance(x, Generator)
1138 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
1139
1140 class Gen:
1141 def __iter__(self): return self
1142 def __next__(self): return None
1143 def close(self): pass
1144 def send(self, value): return value
1145 def throw(self, typ, val=None, tb=None): pass
1146
1147 class MinimalGen(Generator):
1148 def send(self, value):
1149 return value
1150 def throw(self, typ, val=None, tb=None):
1151 super().throw(typ, val, tb)
1152
1153 def gen():
1154 yield 1
1155
1156 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
1157 for x in samples:
1158 self.assertIsInstance(x, Iterator)
1159 self.assertIsInstance(x, Generator)
1160 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
1161 self.validate_abstract_methods(Generator, 'send', 'throw')
1162
1163 # mixin tests
1164 mgen = MinimalGen()
1165 self.assertIs(mgen, iter(mgen))
1166 self.assertIs(mgen.send(None), next(mgen))
1167 self.assertEqual(2, mgen.send(2))
1168 self.assertIsNone(mgen.close())
1169 self.assertRaises(ValueError, mgen.throw, ValueError)
1170 self.assertRaisesRegex(ValueError, "^huhu$",
1171 mgen.throw, ValueError, ValueError("huhu"))
1172 self.assertRaises(StopIteration, mgen.throw, StopIteration())
1173
1174 class FailOnClose(Generator):
1175 def send(self, value): return value
1176 def throw(self, *args): raise ValueError
1177
1178 self.assertRaises(ValueError, FailOnClose().close)
1179
1180 class IgnoreGeneratorExit(Generator):
1181 def send(self, value): return value
1182 def throw(self, *args): pass
1183
1184 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
1185
Yury Selivanov22214ab2016-11-16 18:25:04 -05001186 def test_AsyncGenerator(self):
1187 class NonAGen1:
1188 def __aiter__(self): return self
1189 def __anext__(self): return None
1190 def aclose(self): pass
1191 def athrow(self, typ, val=None, tb=None): pass
1192
1193 class NonAGen2:
1194 def __aiter__(self): return self
1195 def __anext__(self): return None
1196 def aclose(self): pass
1197 def asend(self, value): return value
1198
1199 class NonAGen3:
1200 def aclose(self): pass
1201 def asend(self, value): return value
1202 def athrow(self, typ, val=None, tb=None): pass
1203
1204 non_samples = [
1205 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1206 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
1207 for x in non_samples:
1208 self.assertNotIsInstance(x, AsyncGenerator)
1209 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
1210
1211 class Gen:
1212 def __aiter__(self): return self
1213 async def __anext__(self): return None
1214 async def aclose(self): pass
1215 async def asend(self, value): return value
1216 async def athrow(self, typ, val=None, tb=None): pass
1217
1218 class MinimalAGen(AsyncGenerator):
1219 async def asend(self, value):
1220 return value
1221 async def athrow(self, typ, val=None, tb=None):
1222 await super().athrow(typ, val, tb)
1223
1224 async def gen():
1225 yield 1
1226
1227 samples = [gen(), Gen(), MinimalAGen()]
1228 for x in samples:
1229 self.assertIsInstance(x, AsyncIterator)
1230 self.assertIsInstance(x, AsyncGenerator)
1231 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1232 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1233
1234 def run_async(coro):
1235 result = None
1236 while True:
1237 try:
1238 coro.send(None)
1239 except StopIteration as ex:
1240 result = ex.args[0] if ex.args else None
1241 break
1242 return result
1243
1244 # mixin tests
1245 mgen = MinimalAGen()
1246 self.assertIs(mgen, mgen.__aiter__())
1247 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1248 self.assertEqual(2, run_async(mgen.asend(2)))
1249 self.assertIsNone(run_async(mgen.aclose()))
1250 with self.assertRaises(ValueError):
1251 run_async(mgen.athrow(ValueError))
1252
1253 class FailOnClose(AsyncGenerator):
1254 async def asend(self, value): return value
1255 async def athrow(self, *args): raise ValueError
1256
1257 with self.assertRaises(ValueError):
1258 run_async(FailOnClose().aclose())
1259
1260 class IgnoreGeneratorExit(AsyncGenerator):
1261 async def asend(self, value): return value
1262 async def athrow(self, *args): pass
1263
1264 with self.assertRaises(RuntimeError):
1265 run_async(IgnoreGeneratorExit().aclose())
1266
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001267 def test_Sized(self):
1268 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001269 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001270 (x for x in []),
1271 ]
1272 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001273 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001274 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001275 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001276 tuple(), list(), set(), frozenset(), dict(),
1277 dict().keys(), dict().items(), dict().values(),
1278 ]
1279 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001280 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001281 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001282 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001283 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001284
1285 def test_Container(self):
1286 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001287 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001288 (x for x in []),
1289 ]
1290 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001291 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001292 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001293 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001294 tuple(), list(), set(), frozenset(), dict(),
1295 dict().keys(), dict().items(),
1296 ]
1297 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001298 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001299 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001300 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001301 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001302
1303 def test_Callable(self):
1304 non_samples = [None, 42, 3.14, 1j,
1305 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001306 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001307 (x for x in []),
1308 ]
1309 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001310 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001311 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001312 samples = [lambda: None,
1313 type, int, object,
1314 len,
1315 list.append, [].append,
1316 ]
1317 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001318 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001319 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001320 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001321 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001322
1323 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001324 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001325 class C(B):
1326 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001327 self.assertTrue(issubclass(C, B))
1328 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001329
1330 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001331 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001332 class C:
1333 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001334 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001335 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001336 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001337
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001338class WithSet(MutableSet):
1339
1340 def __init__(self, it=()):
1341 self.data = set(it)
1342
1343 def __len__(self):
1344 return len(self.data)
1345
1346 def __iter__(self):
1347 return iter(self.data)
1348
1349 def __contains__(self, item):
1350 return item in self.data
1351
1352 def add(self, item):
1353 self.data.add(item)
1354
1355 def discard(self, item):
1356 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001357
Raymond Hettingerae650182009-01-28 23:33:59 +00001358class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001359
1360 # XXX For now, we only test some virtual inheritance properties.
1361 # We should also test the proper behavior of the collection ABCs
1362 # as real base classes or mix-in classes.
1363
1364 def test_Set(self):
1365 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001366 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001367 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001368 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001369 class MySet(Set):
1370 def __contains__(self, x):
1371 return False
1372 def __len__(self):
1373 return 0
1374 def __iter__(self):
1375 return iter([])
1376 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001377
Benjamin Peterson41181742008-07-02 20:22:54 +00001378 def test_hash_Set(self):
1379 class OneTwoThreeSet(Set):
1380 def __init__(self):
1381 self.contents = [1, 2, 3]
1382 def __contains__(self, x):
1383 return x in self.contents
1384 def __len__(self):
1385 return len(self.contents)
1386 def __iter__(self):
1387 return iter(self.contents)
1388 def __hash__(self):
1389 return self._hash()
1390 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001391 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001392
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001393 def test_isdisjoint_Set(self):
1394 class MySet(Set):
1395 def __init__(self, itr):
1396 self.contents = itr
1397 def __contains__(self, x):
1398 return x in self.contents
1399 def __iter__(self):
1400 return iter(self.contents)
1401 def __len__(self):
1402 return len([x for x in self.contents])
1403 s1 = MySet((1, 2, 3))
1404 s2 = MySet((4, 5, 6))
1405 s3 = MySet((1, 5, 6))
1406 self.assertTrue(s1.isdisjoint(s2))
1407 self.assertFalse(s1.isdisjoint(s3))
1408
1409 def test_equality_Set(self):
1410 class MySet(Set):
1411 def __init__(self, itr):
1412 self.contents = itr
1413 def __contains__(self, x):
1414 return x in self.contents
1415 def __iter__(self):
1416 return iter(self.contents)
1417 def __len__(self):
1418 return len([x for x in self.contents])
1419 s1 = MySet((1,))
1420 s2 = MySet((1, 2))
1421 s3 = MySet((3, 4))
1422 s4 = MySet((3, 4))
1423 self.assertTrue(s2 > s1)
1424 self.assertTrue(s1 < s2)
1425 self.assertFalse(s2 <= s1)
1426 self.assertFalse(s2 <= s3)
1427 self.assertFalse(s1 >= s2)
1428 self.assertEqual(s3, s4)
1429 self.assertNotEqual(s2, s3)
1430
1431 def test_arithmetic_Set(self):
1432 class MySet(Set):
1433 def __init__(self, itr):
1434 self.contents = itr
1435 def __contains__(self, x):
1436 return x in self.contents
1437 def __iter__(self):
1438 return iter(self.contents)
1439 def __len__(self):
1440 return len([x for x in self.contents])
1441 s1 = MySet((1, 2, 3))
1442 s2 = MySet((3, 4, 5))
1443 s3 = s1 & s2
1444 self.assertEqual(s3, MySet((3,)))
1445
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001446 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001447 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001448 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001449 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001450 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001451 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1452 'add', 'discard')
1453
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001454 def test_issue_5647(self):
1455 # MutableSet.__iand__ mutated the set during iteration
1456 s = WithSet('abcd')
1457 s &= WithSet('cdef') # This used to fail
1458 self.assertEqual(set(s), set('cd'))
1459
Raymond Hettingerae650182009-01-28 23:33:59 +00001460 def test_issue_4920(self):
1461 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001462 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001463 __slots__=['__s']
1464 def __init__(self,items=None):
1465 if items is None:
1466 items=[]
1467 self.__s=set(items)
1468 def __contains__(self,v):
1469 return v in self.__s
1470 def __iter__(self):
1471 return iter(self.__s)
1472 def __len__(self):
1473 return len(self.__s)
1474 def add(self,v):
1475 result=v not in self.__s
1476 self.__s.add(v)
1477 return result
1478 def discard(self,v):
1479 result=v in self.__s
1480 self.__s.discard(v)
1481 return result
1482 def __repr__(self):
1483 return "MySet(%s)" % repr(list(self))
1484 s = MySet([5,43,2,1])
1485 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001486
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001487 def test_issue8750(self):
1488 empty = WithSet()
1489 full = WithSet(range(10))
1490 s = WithSet(full)
1491 s -= s
1492 self.assertEqual(s, empty)
1493 s = WithSet(full)
1494 s ^= s
1495 self.assertEqual(s, empty)
1496 s = WithSet(full)
1497 s &= s
1498 self.assertEqual(s, full)
1499 s |= s
1500 self.assertEqual(s, full)
1501
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001502 def test_issue16373(self):
1503 # Recursion error comparing comparable and noncomparable
1504 # Set instances
1505 class MyComparableSet(Set):
1506 def __contains__(self, x):
1507 return False
1508 def __len__(self):
1509 return 0
1510 def __iter__(self):
1511 return iter([])
1512 class MyNonComparableSet(Set):
1513 def __contains__(self, x):
1514 return False
1515 def __len__(self):
1516 return 0
1517 def __iter__(self):
1518 return iter([])
1519 def __le__(self, x):
1520 return NotImplemented
1521 def __lt__(self, x):
1522 return NotImplemented
1523
1524 cs = MyComparableSet()
1525 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001526 self.assertFalse(ncs < cs)
1527 self.assertTrue(ncs <= cs)
1528 self.assertFalse(ncs > cs)
1529 self.assertTrue(ncs >= cs)
1530
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001531 def test_issue26915(self):
1532 # Container membership test should check identity first
Xiang Zhangd5d32492017-03-08 11:04:24 +08001533 class CustomSequence(Sequence):
1534 def __init__(self, seq):
1535 self._seq = seq
1536 def __getitem__(self, index):
1537 return self._seq[index]
1538 def __len__(self):
1539 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001540
1541 nan = float('nan')
Serhiy Storchaka7d44e7a2019-08-08 08:43:18 +03001542 obj = support.NEVER_EQ
Xiang Zhangd5d32492017-03-08 11:04:24 +08001543 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001544 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001545 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001546 ItemsView({1: nan, 2: obj}),
1547 ValuesView({1: nan, 2: obj})
1548 ]
1549 for container in containers:
1550 for elem in container:
1551 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001552 self.assertEqual(seq.index(nan), 0)
1553 self.assertEqual(seq.index(obj), 1)
1554 self.assertEqual(seq.count(nan), 2)
1555 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001556
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001557 def assertSameSet(self, s1, s2):
1558 # coerce both to a real set then check equality
1559 self.assertSetEqual(set(s1), set(s2))
1560
1561 def test_Set_interoperability_with_real_sets(self):
1562 # Issue: 8743
1563 class ListSet(Set):
1564 def __init__(self, elements=()):
1565 self.data = []
1566 for elem in elements:
1567 if elem not in self.data:
1568 self.data.append(elem)
1569 def __contains__(self, elem):
1570 return elem in self.data
1571 def __iter__(self):
1572 return iter(self.data)
1573 def __len__(self):
1574 return len(self.data)
1575 def __repr__(self):
1576 return 'Set({!r})'.format(self.data)
1577
1578 r1 = set('abc')
1579 r2 = set('bcd')
1580 r3 = set('abcde')
1581 f1 = ListSet('abc')
1582 f2 = ListSet('bcd')
1583 f3 = ListSet('abcde')
1584 l1 = list('abccba')
1585 l2 = list('bcddcb')
1586 l3 = list('abcdeedcba')
1587
1588 target = r1 & r2
1589 self.assertSameSet(f1 & f2, target)
1590 self.assertSameSet(f1 & r2, target)
1591 self.assertSameSet(r2 & f1, target)
1592 self.assertSameSet(f1 & l2, target)
1593
1594 target = r1 | r2
1595 self.assertSameSet(f1 | f2, target)
1596 self.assertSameSet(f1 | r2, target)
1597 self.assertSameSet(r2 | f1, target)
1598 self.assertSameSet(f1 | l2, target)
1599
1600 fwd_target = r1 - r2
1601 rev_target = r2 - r1
1602 self.assertSameSet(f1 - f2, fwd_target)
1603 self.assertSameSet(f2 - f1, rev_target)
1604 self.assertSameSet(f1 - r2, fwd_target)
1605 self.assertSameSet(f2 - r1, rev_target)
1606 self.assertSameSet(r1 - f2, fwd_target)
1607 self.assertSameSet(r2 - f1, rev_target)
1608 self.assertSameSet(f1 - l2, fwd_target)
1609 self.assertSameSet(f2 - l1, rev_target)
1610
1611 target = r1 ^ r2
1612 self.assertSameSet(f1 ^ f2, target)
1613 self.assertSameSet(f1 ^ r2, target)
1614 self.assertSameSet(r2 ^ f1, target)
1615 self.assertSameSet(f1 ^ l2, target)
1616
1617 # Don't change the following to use assertLess or other
1618 # "more specific" unittest assertions. The current
1619 # assertTrue/assertFalse style makes the pattern of test
1620 # case combinations clear and allows us to know for sure
1621 # the exact operator being invoked.
1622
1623 # proper subset
1624 self.assertTrue(f1 < f3)
1625 self.assertFalse(f1 < f1)
1626 self.assertFalse(f1 < f2)
1627 self.assertTrue(r1 < f3)
1628 self.assertFalse(r1 < f1)
1629 self.assertFalse(r1 < f2)
1630 self.assertTrue(r1 < r3)
1631 self.assertFalse(r1 < r1)
1632 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001633 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001634 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001635 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001636 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001637 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001638 f1 < l2
1639
1640 # any subset
1641 self.assertTrue(f1 <= f3)
1642 self.assertTrue(f1 <= f1)
1643 self.assertFalse(f1 <= f2)
1644 self.assertTrue(r1 <= f3)
1645 self.assertTrue(r1 <= f1)
1646 self.assertFalse(r1 <= f2)
1647 self.assertTrue(r1 <= r3)
1648 self.assertTrue(r1 <= r1)
1649 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001650 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001651 f1 <= l3
1652 with self.assertRaises(TypeError):
1653 f1 <= l1
1654 with self.assertRaises(TypeError):
1655 f1 <= l2
1656
1657 # proper superset
1658 self.assertTrue(f3 > f1)
1659 self.assertFalse(f1 > f1)
1660 self.assertFalse(f2 > f1)
1661 self.assertTrue(r3 > r1)
1662 self.assertFalse(f1 > r1)
1663 self.assertFalse(f2 > r1)
1664 self.assertTrue(r3 > r1)
1665 self.assertFalse(r1 > r1)
1666 self.assertFalse(r2 > r1)
1667 with self.assertRaises(TypeError):
1668 f1 > l3
1669 with self.assertRaises(TypeError):
1670 f1 > l1
1671 with self.assertRaises(TypeError):
1672 f1 > l2
1673
1674 # any superset
1675 self.assertTrue(f3 >= f1)
1676 self.assertTrue(f1 >= f1)
1677 self.assertFalse(f2 >= f1)
1678 self.assertTrue(r3 >= r1)
1679 self.assertTrue(f1 >= r1)
1680 self.assertFalse(f2 >= r1)
1681 self.assertTrue(r3 >= r1)
1682 self.assertTrue(r1 >= r1)
1683 self.assertFalse(r2 >= r1)
1684 with self.assertRaises(TypeError):
1685 f1 >= l3
1686 with self.assertRaises(TypeError):
1687 f1 >=l1
1688 with self.assertRaises(TypeError):
1689 f1 >= l2
1690
1691 # equality
1692 self.assertTrue(f1 == f1)
1693 self.assertTrue(r1 == f1)
1694 self.assertTrue(f1 == r1)
1695 self.assertFalse(f1 == f3)
1696 self.assertFalse(r1 == f3)
1697 self.assertFalse(f1 == r3)
1698 self.assertFalse(f1 == l3)
1699 self.assertFalse(f1 == l1)
1700 self.assertFalse(f1 == l2)
1701
1702 # inequality
1703 self.assertFalse(f1 != f1)
1704 self.assertFalse(r1 != f1)
1705 self.assertFalse(f1 != r1)
1706 self.assertTrue(f1 != f3)
1707 self.assertTrue(r1 != f3)
1708 self.assertTrue(f1 != r3)
1709 self.assertTrue(f1 != l3)
1710 self.assertTrue(f1 != l1)
1711 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001712
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001713 def test_Mapping(self):
1714 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001715 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001716 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001717 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1718 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001719 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001720 def __len__(self):
1721 return 0
1722 def __getitem__(self, i):
1723 raise IndexError
1724 def __iter__(self):
1725 return iter(())
1726 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001727 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001728
1729 def test_MutableMapping(self):
1730 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001731 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001732 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001733 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1734 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001735
Raymond Hettinger9117c752010-08-22 07:44:24 +00001736 def test_MutableMapping_subclass(self):
1737 # Test issue 9214
1738 mymap = UserDict()
1739 mymap['red'] = 5
1740 self.assertIsInstance(mymap.keys(), Set)
1741 self.assertIsInstance(mymap.keys(), KeysView)
1742 self.assertIsInstance(mymap.items(), Set)
1743 self.assertIsInstance(mymap.items(), ItemsView)
1744
1745 mymap = UserDict()
1746 mymap['red'] = 5
1747 z = mymap.keys() | {'orange'}
1748 self.assertIsInstance(z, set)
1749 list(z)
1750 mymap['blue'] = 7 # Shouldn't affect 'z'
1751 self.assertEqual(sorted(z), ['orange', 'red'])
1752
1753 mymap = UserDict()
1754 mymap['red'] = 5
1755 z = mymap.items() | {('orange', 3)}
1756 self.assertIsInstance(z, set)
1757 list(z)
1758 mymap['blue'] = 7 # Shouldn't affect 'z'
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001759 self.assertEqual(z, {('orange', 3), ('red', 5)})
Raymond Hettinger9117c752010-08-22 07:44:24 +00001760
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001761 def test_Sequence(self):
1762 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001763 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001764 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001765 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001766 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001767 self.assertIsInstance(memoryview(b""), Sequence)
1768 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001769 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001770 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1771 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001772
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001773 def test_Sequence_mixins(self):
1774 class SequenceSubclass(Sequence):
1775 def __init__(self, seq=()):
1776 self.seq = seq
1777
1778 def __getitem__(self, index):
1779 return self.seq[index]
1780
1781 def __len__(self):
1782 return len(self.seq)
1783
1784 # Compare Sequence.index() behavior to (list|str).index() behavior
1785 def assert_index_same(seq1, seq2, index_args):
1786 try:
1787 expected = seq1.index(*index_args)
1788 except ValueError:
1789 with self.assertRaises(ValueError):
1790 seq2.index(*index_args)
1791 else:
1792 actual = seq2.index(*index_args)
1793 self.assertEqual(
1794 actual, expected, '%r.index%s' % (seq1, index_args))
1795
1796 for ty in list, str:
1797 nativeseq = ty('abracadabra')
1798 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1799 seqseq = SequenceSubclass(nativeseq)
1800 for letter in set(nativeseq) | {'z'}:
1801 assert_index_same(nativeseq, seqseq, (letter,))
1802 for start in range(-3, len(nativeseq) + 3):
1803 assert_index_same(nativeseq, seqseq, (letter, start))
1804 for stop in range(-3, len(nativeseq) + 3):
1805 assert_index_same(
1806 nativeseq, seqseq, (letter, start, stop))
1807
Guido van Rossumd05eb002007-11-21 22:26:24 +00001808 def test_ByteString(self):
1809 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001810 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001811 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001812 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001813 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001814 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001815 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001816 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001817
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001818 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001819 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001820 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001821 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001822 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001823 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001824 self.assertTrue(issubclass(sample, MutableSequence))
1825 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001826 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1827 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001828
Eli Bendersky0716a572011-03-04 10:38:14 +00001829 def test_MutableSequence_mixins(self):
Mike53f7a7c2017-12-14 14:04:53 +03001830 # Test the mixins of MutableSequence by creating a minimal concrete
Eli Bendersky0716a572011-03-04 10:38:14 +00001831 # class inherited from it.
1832 class MutableSequenceSubclass(MutableSequence):
1833 def __init__(self):
1834 self.lst = []
1835
1836 def __setitem__(self, index, value):
1837 self.lst[index] = value
1838
1839 def __getitem__(self, index):
1840 return self.lst[index]
1841
1842 def __len__(self):
1843 return len(self.lst)
1844
1845 def __delitem__(self, index):
1846 del self.lst[index]
1847
1848 def insert(self, index, value):
1849 self.lst.insert(index, value)
1850
1851 mss = MutableSequenceSubclass()
1852 mss.append(0)
1853 mss.extend((1, 2, 3, 4))
1854 self.assertEqual(len(mss), 5)
1855 self.assertEqual(mss[3], 3)
1856 mss.reverse()
1857 self.assertEqual(mss[3], 1)
1858 mss.pop()
1859 self.assertEqual(len(mss), 4)
1860 mss.remove(3)
1861 self.assertEqual(len(mss), 3)
1862 mss += (10, 20, 30)
1863 self.assertEqual(len(mss), 6)
1864 self.assertEqual(mss[-1], 30)
1865 mss.clear()
1866 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001867
Naris R1b5f9c92018-08-31 02:56:14 +10001868 # issue 34427
1869 # extending self should not cause infinite loop
1870 items = 'ABCD'
1871 mss2 = MutableSequenceSubclass()
1872 mss2.extend(items + items)
1873 mss.clear()
1874 mss.extend(items)
1875 mss.extend(mss)
1876 self.assertEqual(len(mss), len(mss2))
1877 self.assertEqual(list(mss), list(mss2))
1878
1879
Raymond Hettinger499e1932011-02-23 07:56:53 +00001880################################################################################
1881### Counter
1882################################################################################
1883
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001884class CounterSubclassWithSetItem(Counter):
1885 # Test a counter subclass that overrides __setitem__
1886 def __init__(self, *args, **kwds):
1887 self.called = False
1888 Counter.__init__(self, *args, **kwds)
1889 def __setitem__(self, key, value):
1890 self.called = True
1891 Counter.__setitem__(self, key, value)
1892
1893class CounterSubclassWithGet(Counter):
1894 # Test a counter subclass that overrides get()
1895 def __init__(self, *args, **kwds):
1896 self.called = False
1897 Counter.__init__(self, *args, **kwds)
1898 def get(self, key, default):
1899 self.called = True
1900 return Counter.get(self, key, default)
1901
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001902class TestCounter(unittest.TestCase):
1903
1904 def test_basics(self):
1905 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001906 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1907 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001908 self.assertIsInstance(c, dict)
1909 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001910 self.assertTrue(issubclass(Counter, dict))
1911 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001912 self.assertEqual(len(c), 3)
1913 self.assertEqual(sum(c.values()), 6)
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001914 self.assertEqual(list(c.values()), [3, 2, 1])
1915 self.assertEqual(list(c.keys()), ['a', 'b', 'c'])
1916 self.assertEqual(list(c), ['a', 'b', 'c'])
1917 self.assertEqual(list(c.items()),
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001918 [('a', 3), ('b', 2), ('c', 1)])
1919 self.assertEqual(c['b'], 2)
1920 self.assertEqual(c['z'], 0)
1921 self.assertEqual(c.__contains__('c'), True)
1922 self.assertEqual(c.__contains__('z'), False)
1923 self.assertEqual(c.get('b', 10), 2)
1924 self.assertEqual(c.get('z', 10), 10)
1925 self.assertEqual(c, dict(a=3, b=2, c=1))
1926 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1927 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1928 for i in range(5):
1929 self.assertEqual(c.most_common(i),
1930 [('a', 3), ('b', 2), ('c', 1)][:i])
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001931 self.assertEqual(''.join(c.elements()), 'aaabbc')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001932 c['a'] += 1 # increment an existing value
1933 c['b'] -= 2 # sub existing value to zero
1934 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001935 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001936 c['d'] -= 2 # sub from a missing value
1937 c['e'] = -5 # directly assign a missing value
1938 c['f'] += 4 # add to a missing value
1939 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001940 self.assertEqual(''.join(c.elements()), 'aaaaffff')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001941 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001942 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001943 for i in range(3):
1944 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001945 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001946 c.clear()
1947 self.assertEqual(c, {})
1948 self.assertEqual(repr(c), 'Counter()')
1949 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1950 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001951 c.update(dict(a=5, b=3))
1952 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001953 c.update(Counter('a' * 50 + 'b' * 30))
1954 c.update() # test case with no args
1955 c.__init__('a' * 500 + 'b' * 300)
1956 c.__init__('cdc')
1957 c.__init__()
1958 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1959 self.assertEqual(c.setdefault('d', 5), 1)
1960 self.assertEqual(c['d'], 1)
1961 self.assertEqual(c.setdefault('e', 5), 5)
1962 self.assertEqual(c['e'], 5)
1963
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001964 def test_init(self):
1965 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1966 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1967 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1968 self.assertRaises(TypeError, Counter, 42)
1969 self.assertRaises(TypeError, Counter, (), ())
1970 self.assertRaises(TypeError, Counter.__init__)
1971
Raymond Hettinger407c7342019-02-21 09:19:00 -08001972 def test_order_preservation(self):
1973 # Input order dictates items() order
1974 self.assertEqual(list(Counter('abracadabra').items()),
1975 [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])
1976 # letters with same count: ^----------^ ^---------^
1977
1978 # Verify retention of order even when all counts are equal
1979 self.assertEqual(list(Counter('xyzpdqqdpzyx').items()),
1980 [('x', 2), ('y', 2), ('z', 2), ('p', 2), ('d', 2), ('q', 2)])
1981
1982 # Input order dictates elements() order
1983 self.assertEqual(list(Counter('abracadabra simsalabim').elements()),
1984 ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b','r',
1985 'r', 'c', 'd', ' ', 's', 's', 'i', 'i', 'm', 'm', 'l'])
1986
1987 # Math operations order first by the order encountered in the left
Min ho Kim39d87b52019-08-31 06:21:19 +10001988 # operand and then by the order encountered in the right operand.
Raymond Hettinger407c7342019-02-21 09:19:00 -08001989 ps = 'aaabbcdddeefggghhijjjkkl'
1990 qs = 'abbcccdeefffhkkllllmmnno'
1991 order = {letter: i for i, letter in enumerate(dict.fromkeys(ps + qs))}
1992 def correctly_ordered(seq):
1993 'Return true if the letters occur in the expected order'
1994 positions = [order[letter] for letter in seq]
1995 return positions == sorted(positions)
1996
1997 p, q = Counter(ps), Counter(qs)
1998 self.assertTrue(correctly_ordered(+p))
1999 self.assertTrue(correctly_ordered(-p))
2000 self.assertTrue(correctly_ordered(p + q))
2001 self.assertTrue(correctly_ordered(p - q))
2002 self.assertTrue(correctly_ordered(p | q))
2003 self.assertTrue(correctly_ordered(p & q))
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 -= q
2011 self.assertTrue(correctly_ordered(p))
2012
2013 p, q = Counter(ps), Counter(qs)
2014 p |= q
2015 self.assertTrue(correctly_ordered(p))
2016
2017 p, q = Counter(ps), Counter(qs)
2018 p &= q
2019 self.assertTrue(correctly_ordered(p))
2020
2021 p, q = Counter(ps), Counter(qs)
2022 p.update(q)
2023 self.assertTrue(correctly_ordered(p))
2024
2025 p, q = Counter(ps), Counter(qs)
2026 p.subtract(q)
2027 self.assertTrue(correctly_ordered(p))
2028
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02002029 def test_update(self):
2030 c = Counter()
2031 c.update(self=42)
2032 self.assertEqual(list(c.items()), [('self', 42)])
2033 c = Counter()
2034 c.update(iterable=42)
2035 self.assertEqual(list(c.items()), [('iterable', 42)])
2036 c = Counter()
2037 c.update(iterable=None)
2038 self.assertEqual(list(c.items()), [('iterable', None)])
2039 self.assertRaises(TypeError, Counter().update, 42)
2040 self.assertRaises(TypeError, Counter().update, {}, {})
2041 self.assertRaises(TypeError, Counter.update)
2042
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002043 def test_copying(self):
2044 # Check that counters are copyable, deepcopyable, picklable, and
2045 #have a repr/eval round-trip
2046 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02002047 def check(dup):
2048 msg = "\ncopy: %s\nwords: %s" % (dup, words)
2049 self.assertIsNot(dup, words, msg)
2050 self.assertEqual(dup, words)
2051 check(words.copy())
2052 check(copy.copy(words))
2053 check(copy.deepcopy(words))
2054 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2055 with self.subTest(proto=proto):
2056 check(pickle.loads(pickle.dumps(words, proto)))
2057 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002058 update_test = Counter()
2059 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02002060 check(update_test)
2061 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002062
Raymond Hettinger1c746c22011-04-15 13:16:46 -07002063 def test_copy_subclass(self):
2064 class MyCounter(Counter):
2065 pass
2066 c = MyCounter('slartibartfast')
2067 d = c.copy()
2068 self.assertEqual(d, c)
2069 self.assertEqual(len(d), len(c))
2070 self.assertEqual(type(d), type(c))
2071
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002072 def test_conversions(self):
2073 # Convert to: set, list, dict
2074 s = 'she sells sea shells by the sea shore'
2075 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
2076 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
2077 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
2078 self.assertEqual(set(Counter(s)), set(s))
2079
Raymond Hettinger670eaec2009-01-21 23:14:07 +00002080 def test_invariant_for_the_in_operator(self):
2081 c = Counter(a=10, b=-2, c=0)
2082 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002083 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00002084 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00002085
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002086 def test_multiset_operations(self):
2087 # Verify that adding a zero counter will strip zeros and negatives
2088 c = Counter(a=10, b=-2, c=0) + Counter()
2089 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002090
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002091 elements = 'abcd'
2092 for i in range(1000):
2093 # test random pairs of multisets
2094 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00002095 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002096 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00002097 q.update(h=1, i=-1, j=0)
2098 for counterop, numberop in [
2099 (Counter.__add__, lambda x, y: max(0, x+y)),
2100 (Counter.__sub__, lambda x, y: max(0, x-y)),
2101 (Counter.__or__, lambda x, y: max(0,x,y)),
2102 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002103 ]:
2104 result = counterop(p, q)
2105 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00002106 self.assertEqual(numberop(p[x], q[x]), result[x],
2107 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002108 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002109 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002110
2111 elements = 'abcdef'
2112 for i in range(100):
2113 # verify that random multisets with no repeats are exactly like sets
2114 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
2115 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
2116 for counterop, setop in [
2117 (Counter.__sub__, set.__sub__),
2118 (Counter.__or__, set.__or__),
2119 (Counter.__and__, set.__and__),
2120 ]:
2121 counter_result = counterop(p, q)
2122 set_result = setop(set(p.elements()), set(q.elements()))
2123 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002124
Raymond Hettinger1ca8fb12019-12-16 01:54:14 -08002125 def test_subset_superset_not_implemented(self):
2126 # Verify that multiset comparison operations are not implemented.
2127
2128 # These operations were intentionally omitted because multiset
2129 # comparison semantics conflict with existing dict equality semantics.
2130
2131 # For multisets, we would expect that if p<=q and p>=q are both true,
2132 # then p==q. However, dict equality semantics require that p!=q when
2133 # one of sets contains an element with a zero count and the other
2134 # doesn't.
2135
2136 p = Counter(a=1, b=0)
2137 q = Counter(a=1, c=0)
2138 self.assertNotEqual(p, q)
2139 with self.assertRaises(TypeError):
2140 p < q
2141 with self.assertRaises(TypeError):
2142 p <= q
2143 with self.assertRaises(TypeError):
2144 p > q
2145 with self.assertRaises(TypeError):
2146 p >= q
2147
Raymond Hettingerbecd5682011-10-19 13:40:37 -07002148 def test_inplace_operations(self):
2149 elements = 'abcd'
2150 for i in range(1000):
2151 # test random pairs of multisets
2152 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2153 p.update(e=1, f=-1, g=0)
2154 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2155 q.update(h=1, i=-1, j=0)
2156 for inplace_op, regular_op in [
2157 (Counter.__iadd__, Counter.__add__),
2158 (Counter.__isub__, Counter.__sub__),
2159 (Counter.__ior__, Counter.__or__),
2160 (Counter.__iand__, Counter.__and__),
2161 ]:
2162 c = p.copy()
2163 c_id = id(c)
2164 regular_result = regular_op(c, q)
2165 inplace_result = inplace_op(c, q)
2166 self.assertEqual(inplace_result, regular_result)
2167 self.assertEqual(id(inplace_result), c_id)
2168
Raymond Hettinger9c01e442010-04-03 10:32:58 +00002169 def test_subtract(self):
2170 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2171 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
2172 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
2173 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2174 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
2175 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
2176 c = Counter('aaabbcd')
2177 c.subtract('aaaabbcce')
2178 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002179
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02002180 c = Counter()
2181 c.subtract(self=42)
2182 self.assertEqual(list(c.items()), [('self', -42)])
2183 c = Counter()
2184 c.subtract(iterable=42)
2185 self.assertEqual(list(c.items()), [('iterable', -42)])
2186 self.assertRaises(TypeError, Counter().subtract, 42)
2187 self.assertRaises(TypeError, Counter().subtract, {}, {})
2188 self.assertRaises(TypeError, Counter.subtract)
2189
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07002190 def test_unary(self):
2191 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2192 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
2193 self.assertEqual(dict(-c), dict(a=5))
2194
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07002195 def test_repr_nonsortable(self):
2196 c = Counter(a=2, b=None)
2197 r = repr(c)
2198 self.assertIn("'a': 2", r)
2199 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07002200
Raymond Hettinger426e0522011-01-03 02:12:02 +00002201 def test_helper_function(self):
2202 # two paths, one for real dicts and one for other mappings
2203 elems = list('abracadabra')
2204
2205 d = dict()
2206 _count_elements(d, elems)
2207 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
2208
2209 m = OrderedDict()
2210 _count_elements(m, elems)
2211 self.assertEqual(m,
2212 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
2213
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002214 # test fidelity to the pure python version
2215 c = CounterSubclassWithSetItem('abracadabra')
2216 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07002217 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002218 c = CounterSubclassWithGet('abracadabra')
2219 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07002220 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002221
Raymond Hettinger499e1932011-02-23 07:56:53 +00002222
2223################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00002224### Run tests
2225################################################################################
2226
Guido van Rossumd8faa362007-04-27 19:54:29 +00002227def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00002228 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002229 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00002230 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06002231 TestUserObjects,
2232 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002233 support.run_unittest(*test_classes)
2234 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002235
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002236
Guido van Rossumd8faa362007-04-27 19:54:29 +00002237if __name__ == "__main__":
2238 test_main(verbose=True)