blob: 6aa897927228cc532b08e233f11c9a0cdce3a03e [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
Miss Islington (bot)89d74d02020-11-21 12:20:26 -08001561 def test_Set_from_iterable(self):
1562 """Verify _from_iterable overriden to an instance method works."""
1563 class SetUsingInstanceFromIterable(MutableSet):
1564 def __init__(self, values, created_by):
1565 if not created_by:
1566 raise ValueError(f'created_by must be specified')
1567 self.created_by = created_by
1568 self._values = set(values)
1569
1570 def _from_iterable(self, values):
1571 return type(self)(values, 'from_iterable')
1572
1573 def __contains__(self, value):
1574 return value in self._values
1575
1576 def __iter__(self):
1577 yield from self._values
1578
1579 def __len__(self):
1580 return len(self._values)
1581
1582 def add(self, value):
1583 self._values.add(value)
1584
1585 def discard(self, value):
1586 self._values.discard(value)
1587
1588 impl = SetUsingInstanceFromIterable([1, 2, 3], 'test')
1589
1590 actual = impl - {1}
1591 self.assertIsInstance(actual, SetUsingInstanceFromIterable)
1592 self.assertEqual('from_iterable', actual.created_by)
1593 self.assertEqual({2, 3}, actual)
1594
1595 actual = impl | {4}
1596 self.assertIsInstance(actual, SetUsingInstanceFromIterable)
1597 self.assertEqual('from_iterable', actual.created_by)
1598 self.assertEqual({1, 2, 3, 4}, actual)
1599
1600 actual = impl & {2}
1601 self.assertIsInstance(actual, SetUsingInstanceFromIterable)
1602 self.assertEqual('from_iterable', actual.created_by)
1603 self.assertEqual({2}, actual)
1604
1605 actual = impl ^ {3, 4}
1606 self.assertIsInstance(actual, SetUsingInstanceFromIterable)
1607 self.assertEqual('from_iterable', actual.created_by)
1608 self.assertEqual({1, 2, 4}, actual)
1609
1610 # NOTE: ixor'ing with a list is important here: internally, __ixor__
1611 # only calls _from_iterable if the other value isn't already a Set.
1612 impl ^= [3, 4]
1613 self.assertIsInstance(impl, SetUsingInstanceFromIterable)
1614 self.assertEqual('test', impl.created_by)
1615 self.assertEqual({1, 2, 4}, impl)
1616
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001617 def test_Set_interoperability_with_real_sets(self):
1618 # Issue: 8743
1619 class ListSet(Set):
1620 def __init__(self, elements=()):
1621 self.data = []
1622 for elem in elements:
1623 if elem not in self.data:
1624 self.data.append(elem)
1625 def __contains__(self, elem):
1626 return elem in self.data
1627 def __iter__(self):
1628 return iter(self.data)
1629 def __len__(self):
1630 return len(self.data)
1631 def __repr__(self):
1632 return 'Set({!r})'.format(self.data)
1633
1634 r1 = set('abc')
1635 r2 = set('bcd')
1636 r3 = set('abcde')
1637 f1 = ListSet('abc')
1638 f2 = ListSet('bcd')
1639 f3 = ListSet('abcde')
1640 l1 = list('abccba')
1641 l2 = list('bcddcb')
1642 l3 = list('abcdeedcba')
1643
1644 target = r1 & r2
1645 self.assertSameSet(f1 & f2, target)
1646 self.assertSameSet(f1 & r2, target)
1647 self.assertSameSet(r2 & f1, target)
1648 self.assertSameSet(f1 & l2, target)
1649
1650 target = r1 | r2
1651 self.assertSameSet(f1 | f2, target)
1652 self.assertSameSet(f1 | r2, target)
1653 self.assertSameSet(r2 | f1, target)
1654 self.assertSameSet(f1 | l2, target)
1655
1656 fwd_target = r1 - r2
1657 rev_target = r2 - r1
1658 self.assertSameSet(f1 - f2, fwd_target)
1659 self.assertSameSet(f2 - f1, rev_target)
1660 self.assertSameSet(f1 - r2, fwd_target)
1661 self.assertSameSet(f2 - r1, rev_target)
1662 self.assertSameSet(r1 - f2, fwd_target)
1663 self.assertSameSet(r2 - f1, rev_target)
1664 self.assertSameSet(f1 - l2, fwd_target)
1665 self.assertSameSet(f2 - l1, rev_target)
1666
1667 target = r1 ^ r2
1668 self.assertSameSet(f1 ^ f2, target)
1669 self.assertSameSet(f1 ^ r2, target)
1670 self.assertSameSet(r2 ^ f1, target)
1671 self.assertSameSet(f1 ^ l2, target)
1672
1673 # Don't change the following to use assertLess or other
1674 # "more specific" unittest assertions. The current
1675 # assertTrue/assertFalse style makes the pattern of test
1676 # case combinations clear and allows us to know for sure
1677 # the exact operator being invoked.
1678
1679 # proper subset
1680 self.assertTrue(f1 < f3)
1681 self.assertFalse(f1 < f1)
1682 self.assertFalse(f1 < f2)
1683 self.assertTrue(r1 < f3)
1684 self.assertFalse(r1 < f1)
1685 self.assertFalse(r1 < f2)
1686 self.assertTrue(r1 < r3)
1687 self.assertFalse(r1 < r1)
1688 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001689 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001690 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001691 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001692 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001693 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001694 f1 < l2
1695
1696 # any subset
1697 self.assertTrue(f1 <= f3)
1698 self.assertTrue(f1 <= f1)
1699 self.assertFalse(f1 <= f2)
1700 self.assertTrue(r1 <= f3)
1701 self.assertTrue(r1 <= f1)
1702 self.assertFalse(r1 <= f2)
1703 self.assertTrue(r1 <= r3)
1704 self.assertTrue(r1 <= r1)
1705 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001706 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001707 f1 <= l3
1708 with self.assertRaises(TypeError):
1709 f1 <= l1
1710 with self.assertRaises(TypeError):
1711 f1 <= l2
1712
1713 # proper superset
1714 self.assertTrue(f3 > f1)
1715 self.assertFalse(f1 > f1)
1716 self.assertFalse(f2 > f1)
1717 self.assertTrue(r3 > r1)
1718 self.assertFalse(f1 > r1)
1719 self.assertFalse(f2 > r1)
1720 self.assertTrue(r3 > r1)
1721 self.assertFalse(r1 > r1)
1722 self.assertFalse(r2 > r1)
1723 with self.assertRaises(TypeError):
1724 f1 > l3
1725 with self.assertRaises(TypeError):
1726 f1 > l1
1727 with self.assertRaises(TypeError):
1728 f1 > l2
1729
1730 # any superset
1731 self.assertTrue(f3 >= f1)
1732 self.assertTrue(f1 >= f1)
1733 self.assertFalse(f2 >= f1)
1734 self.assertTrue(r3 >= r1)
1735 self.assertTrue(f1 >= r1)
1736 self.assertFalse(f2 >= r1)
1737 self.assertTrue(r3 >= r1)
1738 self.assertTrue(r1 >= r1)
1739 self.assertFalse(r2 >= r1)
1740 with self.assertRaises(TypeError):
1741 f1 >= l3
1742 with self.assertRaises(TypeError):
1743 f1 >=l1
1744 with self.assertRaises(TypeError):
1745 f1 >= l2
1746
1747 # equality
1748 self.assertTrue(f1 == f1)
1749 self.assertTrue(r1 == f1)
1750 self.assertTrue(f1 == r1)
1751 self.assertFalse(f1 == f3)
1752 self.assertFalse(r1 == f3)
1753 self.assertFalse(f1 == r3)
1754 self.assertFalse(f1 == l3)
1755 self.assertFalse(f1 == l1)
1756 self.assertFalse(f1 == l2)
1757
1758 # inequality
1759 self.assertFalse(f1 != f1)
1760 self.assertFalse(r1 != f1)
1761 self.assertFalse(f1 != r1)
1762 self.assertTrue(f1 != f3)
1763 self.assertTrue(r1 != f3)
1764 self.assertTrue(f1 != r3)
1765 self.assertTrue(f1 != l3)
1766 self.assertTrue(f1 != l1)
1767 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001768
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001769 def test_Mapping(self):
1770 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001771 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001772 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001773 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1774 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001775 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001776 def __len__(self):
1777 return 0
1778 def __getitem__(self, i):
1779 raise IndexError
1780 def __iter__(self):
1781 return iter(())
1782 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001783 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001784
1785 def test_MutableMapping(self):
1786 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001787 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001788 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001789 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1790 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001791
Raymond Hettinger9117c752010-08-22 07:44:24 +00001792 def test_MutableMapping_subclass(self):
1793 # Test issue 9214
1794 mymap = UserDict()
1795 mymap['red'] = 5
1796 self.assertIsInstance(mymap.keys(), Set)
1797 self.assertIsInstance(mymap.keys(), KeysView)
1798 self.assertIsInstance(mymap.items(), Set)
1799 self.assertIsInstance(mymap.items(), ItemsView)
1800
1801 mymap = UserDict()
1802 mymap['red'] = 5
1803 z = mymap.keys() | {'orange'}
1804 self.assertIsInstance(z, set)
1805 list(z)
1806 mymap['blue'] = 7 # Shouldn't affect 'z'
1807 self.assertEqual(sorted(z), ['orange', 'red'])
1808
1809 mymap = UserDict()
1810 mymap['red'] = 5
1811 z = mymap.items() | {('orange', 3)}
1812 self.assertIsInstance(z, set)
1813 list(z)
1814 mymap['blue'] = 7 # Shouldn't affect 'z'
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001815 self.assertEqual(z, {('orange', 3), ('red', 5)})
Raymond Hettinger9117c752010-08-22 07:44:24 +00001816
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001817 def test_Sequence(self):
1818 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001819 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001820 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001821 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001822 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001823 self.assertIsInstance(memoryview(b""), Sequence)
1824 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001825 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001826 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1827 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001828
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001829 def test_Sequence_mixins(self):
1830 class SequenceSubclass(Sequence):
1831 def __init__(self, seq=()):
1832 self.seq = seq
1833
1834 def __getitem__(self, index):
1835 return self.seq[index]
1836
1837 def __len__(self):
1838 return len(self.seq)
1839
1840 # Compare Sequence.index() behavior to (list|str).index() behavior
1841 def assert_index_same(seq1, seq2, index_args):
1842 try:
1843 expected = seq1.index(*index_args)
1844 except ValueError:
1845 with self.assertRaises(ValueError):
1846 seq2.index(*index_args)
1847 else:
1848 actual = seq2.index(*index_args)
1849 self.assertEqual(
1850 actual, expected, '%r.index%s' % (seq1, index_args))
1851
1852 for ty in list, str:
1853 nativeseq = ty('abracadabra')
1854 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1855 seqseq = SequenceSubclass(nativeseq)
1856 for letter in set(nativeseq) | {'z'}:
1857 assert_index_same(nativeseq, seqseq, (letter,))
1858 for start in range(-3, len(nativeseq) + 3):
1859 assert_index_same(nativeseq, seqseq, (letter, start))
1860 for stop in range(-3, len(nativeseq) + 3):
1861 assert_index_same(
1862 nativeseq, seqseq, (letter, start, stop))
1863
Guido van Rossumd05eb002007-11-21 22:26:24 +00001864 def test_ByteString(self):
1865 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001866 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001867 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001868 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001869 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001870 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001871 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001872 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001873
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001874 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001875 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001876 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001877 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001878 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001879 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001880 self.assertTrue(issubclass(sample, MutableSequence))
1881 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001882 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1883 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001884
Eli Bendersky0716a572011-03-04 10:38:14 +00001885 def test_MutableSequence_mixins(self):
Mike53f7a7c2017-12-14 14:04:53 +03001886 # Test the mixins of MutableSequence by creating a minimal concrete
Eli Bendersky0716a572011-03-04 10:38:14 +00001887 # class inherited from it.
1888 class MutableSequenceSubclass(MutableSequence):
1889 def __init__(self):
1890 self.lst = []
1891
1892 def __setitem__(self, index, value):
1893 self.lst[index] = value
1894
1895 def __getitem__(self, index):
1896 return self.lst[index]
1897
1898 def __len__(self):
1899 return len(self.lst)
1900
1901 def __delitem__(self, index):
1902 del self.lst[index]
1903
1904 def insert(self, index, value):
1905 self.lst.insert(index, value)
1906
1907 mss = MutableSequenceSubclass()
1908 mss.append(0)
1909 mss.extend((1, 2, 3, 4))
1910 self.assertEqual(len(mss), 5)
1911 self.assertEqual(mss[3], 3)
1912 mss.reverse()
1913 self.assertEqual(mss[3], 1)
1914 mss.pop()
1915 self.assertEqual(len(mss), 4)
1916 mss.remove(3)
1917 self.assertEqual(len(mss), 3)
1918 mss += (10, 20, 30)
1919 self.assertEqual(len(mss), 6)
1920 self.assertEqual(mss[-1], 30)
1921 mss.clear()
1922 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001923
Naris R1b5f9c92018-08-31 02:56:14 +10001924 # issue 34427
1925 # extending self should not cause infinite loop
1926 items = 'ABCD'
1927 mss2 = MutableSequenceSubclass()
1928 mss2.extend(items + items)
1929 mss.clear()
1930 mss.extend(items)
1931 mss.extend(mss)
1932 self.assertEqual(len(mss), len(mss2))
1933 self.assertEqual(list(mss), list(mss2))
1934
1935
Raymond Hettinger499e1932011-02-23 07:56:53 +00001936################################################################################
1937### Counter
1938################################################################################
1939
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001940class CounterSubclassWithSetItem(Counter):
1941 # Test a counter subclass that overrides __setitem__
1942 def __init__(self, *args, **kwds):
1943 self.called = False
1944 Counter.__init__(self, *args, **kwds)
1945 def __setitem__(self, key, value):
1946 self.called = True
1947 Counter.__setitem__(self, key, value)
1948
1949class CounterSubclassWithGet(Counter):
1950 # Test a counter subclass that overrides get()
1951 def __init__(self, *args, **kwds):
1952 self.called = False
1953 Counter.__init__(self, *args, **kwds)
1954 def get(self, key, default):
1955 self.called = True
1956 return Counter.get(self, key, default)
1957
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001958class TestCounter(unittest.TestCase):
1959
1960 def test_basics(self):
1961 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001962 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1963 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001964 self.assertIsInstance(c, dict)
1965 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001966 self.assertTrue(issubclass(Counter, dict))
1967 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001968 self.assertEqual(len(c), 3)
1969 self.assertEqual(sum(c.values()), 6)
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001970 self.assertEqual(list(c.values()), [3, 2, 1])
1971 self.assertEqual(list(c.keys()), ['a', 'b', 'c'])
1972 self.assertEqual(list(c), ['a', 'b', 'c'])
1973 self.assertEqual(list(c.items()),
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001974 [('a', 3), ('b', 2), ('c', 1)])
1975 self.assertEqual(c['b'], 2)
1976 self.assertEqual(c['z'], 0)
1977 self.assertEqual(c.__contains__('c'), True)
1978 self.assertEqual(c.__contains__('z'), False)
1979 self.assertEqual(c.get('b', 10), 2)
1980 self.assertEqual(c.get('z', 10), 10)
1981 self.assertEqual(c, dict(a=3, b=2, c=1))
1982 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1983 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1984 for i in range(5):
1985 self.assertEqual(c.most_common(i),
1986 [('a', 3), ('b', 2), ('c', 1)][:i])
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001987 self.assertEqual(''.join(c.elements()), 'aaabbc')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001988 c['a'] += 1 # increment an existing value
1989 c['b'] -= 2 # sub existing value to zero
1990 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001991 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001992 c['d'] -= 2 # sub from a missing value
1993 c['e'] = -5 # directly assign a missing value
1994 c['f'] += 4 # add to a missing value
1995 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001996 self.assertEqual(''.join(c.elements()), 'aaaaffff')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001997 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001998 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001999 for i in range(3):
2000 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00002001 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002002 c.clear()
2003 self.assertEqual(c, {})
2004 self.assertEqual(repr(c), 'Counter()')
2005 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
2006 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002007 c.update(dict(a=5, b=3))
2008 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002009 c.update(Counter('a' * 50 + 'b' * 30))
2010 c.update() # test case with no args
2011 c.__init__('a' * 500 + 'b' * 300)
2012 c.__init__('cdc')
2013 c.__init__()
2014 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
2015 self.assertEqual(c.setdefault('d', 5), 1)
2016 self.assertEqual(c['d'], 1)
2017 self.assertEqual(c.setdefault('e', 5), 5)
2018 self.assertEqual(c['e'], 5)
2019
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02002020 def test_init(self):
2021 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
2022 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
2023 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
2024 self.assertRaises(TypeError, Counter, 42)
2025 self.assertRaises(TypeError, Counter, (), ())
2026 self.assertRaises(TypeError, Counter.__init__)
2027
Raymond Hettinger407c7342019-02-21 09:19:00 -08002028 def test_order_preservation(self):
2029 # Input order dictates items() order
2030 self.assertEqual(list(Counter('abracadabra').items()),
2031 [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])
2032 # letters with same count: ^----------^ ^---------^
2033
2034 # Verify retention of order even when all counts are equal
2035 self.assertEqual(list(Counter('xyzpdqqdpzyx').items()),
2036 [('x', 2), ('y', 2), ('z', 2), ('p', 2), ('d', 2), ('q', 2)])
2037
2038 # Input order dictates elements() order
2039 self.assertEqual(list(Counter('abracadabra simsalabim').elements()),
2040 ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b','r',
2041 'r', 'c', 'd', ' ', 's', 's', 'i', 'i', 'm', 'm', 'l'])
2042
2043 # Math operations order first by the order encountered in the left
Min ho Kim39d87b52019-08-31 06:21:19 +10002044 # operand and then by the order encountered in the right operand.
Raymond Hettinger407c7342019-02-21 09:19:00 -08002045 ps = 'aaabbcdddeefggghhijjjkkl'
2046 qs = 'abbcccdeefffhkkllllmmnno'
2047 order = {letter: i for i, letter in enumerate(dict.fromkeys(ps + qs))}
2048 def correctly_ordered(seq):
2049 'Return true if the letters occur in the expected order'
2050 positions = [order[letter] for letter in seq]
2051 return positions == sorted(positions)
2052
2053 p, q = Counter(ps), Counter(qs)
2054 self.assertTrue(correctly_ordered(+p))
2055 self.assertTrue(correctly_ordered(-p))
2056 self.assertTrue(correctly_ordered(p + q))
2057 self.assertTrue(correctly_ordered(p - q))
2058 self.assertTrue(correctly_ordered(p | q))
2059 self.assertTrue(correctly_ordered(p & q))
2060
2061 p, q = Counter(ps), Counter(qs)
2062 p += q
2063 self.assertTrue(correctly_ordered(p))
2064
2065 p, q = Counter(ps), Counter(qs)
2066 p -= q
2067 self.assertTrue(correctly_ordered(p))
2068
2069 p, q = Counter(ps), Counter(qs)
2070 p |= q
2071 self.assertTrue(correctly_ordered(p))
2072
2073 p, q = Counter(ps), Counter(qs)
2074 p &= q
2075 self.assertTrue(correctly_ordered(p))
2076
2077 p, q = Counter(ps), Counter(qs)
2078 p.update(q)
2079 self.assertTrue(correctly_ordered(p))
2080
2081 p, q = Counter(ps), Counter(qs)
2082 p.subtract(q)
2083 self.assertTrue(correctly_ordered(p))
2084
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02002085 def test_update(self):
2086 c = Counter()
2087 c.update(self=42)
2088 self.assertEqual(list(c.items()), [('self', 42)])
2089 c = Counter()
2090 c.update(iterable=42)
2091 self.assertEqual(list(c.items()), [('iterable', 42)])
2092 c = Counter()
2093 c.update(iterable=None)
2094 self.assertEqual(list(c.items()), [('iterable', None)])
2095 self.assertRaises(TypeError, Counter().update, 42)
2096 self.assertRaises(TypeError, Counter().update, {}, {})
2097 self.assertRaises(TypeError, Counter.update)
2098
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002099 def test_copying(self):
2100 # Check that counters are copyable, deepcopyable, picklable, and
2101 #have a repr/eval round-trip
2102 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02002103 def check(dup):
2104 msg = "\ncopy: %s\nwords: %s" % (dup, words)
2105 self.assertIsNot(dup, words, msg)
2106 self.assertEqual(dup, words)
2107 check(words.copy())
2108 check(copy.copy(words))
2109 check(copy.deepcopy(words))
2110 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2111 with self.subTest(proto=proto):
2112 check(pickle.loads(pickle.dumps(words, proto)))
2113 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002114 update_test = Counter()
2115 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02002116 check(update_test)
2117 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002118
Raymond Hettinger1c746c22011-04-15 13:16:46 -07002119 def test_copy_subclass(self):
2120 class MyCounter(Counter):
2121 pass
2122 c = MyCounter('slartibartfast')
2123 d = c.copy()
2124 self.assertEqual(d, c)
2125 self.assertEqual(len(d), len(c))
2126 self.assertEqual(type(d), type(c))
2127
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002128 def test_conversions(self):
2129 # Convert to: set, list, dict
2130 s = 'she sells sea shells by the sea shore'
2131 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
2132 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
2133 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
2134 self.assertEqual(set(Counter(s)), set(s))
2135
Raymond Hettinger670eaec2009-01-21 23:14:07 +00002136 def test_invariant_for_the_in_operator(self):
2137 c = Counter(a=10, b=-2, c=0)
2138 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002139 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00002140 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00002141
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002142 def test_multiset_operations(self):
2143 # Verify that adding a zero counter will strip zeros and negatives
2144 c = Counter(a=10, b=-2, c=0) + Counter()
2145 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002146
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002147 elements = 'abcd'
2148 for i in range(1000):
2149 # test random pairs of multisets
2150 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00002151 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002152 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00002153 q.update(h=1, i=-1, j=0)
2154 for counterop, numberop in [
2155 (Counter.__add__, lambda x, y: max(0, x+y)),
2156 (Counter.__sub__, lambda x, y: max(0, x-y)),
2157 (Counter.__or__, lambda x, y: max(0,x,y)),
2158 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002159 ]:
2160 result = counterop(p, q)
2161 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00002162 self.assertEqual(numberop(p[x], q[x]), result[x],
2163 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002164 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002165 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00002166
2167 elements = 'abcdef'
2168 for i in range(100):
2169 # verify that random multisets with no repeats are exactly like sets
2170 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
2171 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
2172 for counterop, setop in [
2173 (Counter.__sub__, set.__sub__),
2174 (Counter.__or__, set.__or__),
2175 (Counter.__and__, set.__and__),
2176 ]:
2177 counter_result = counterop(p, q)
2178 set_result = setop(set(p.elements()), set(q.elements()))
2179 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002180
Raymond Hettinger1ca8fb12019-12-16 01:54:14 -08002181 def test_subset_superset_not_implemented(self):
2182 # Verify that multiset comparison operations are not implemented.
2183
2184 # These operations were intentionally omitted because multiset
2185 # comparison semantics conflict with existing dict equality semantics.
2186
2187 # For multisets, we would expect that if p<=q and p>=q are both true,
2188 # then p==q. However, dict equality semantics require that p!=q when
2189 # one of sets contains an element with a zero count and the other
2190 # doesn't.
2191
2192 p = Counter(a=1, b=0)
2193 q = Counter(a=1, c=0)
2194 self.assertNotEqual(p, q)
2195 with self.assertRaises(TypeError):
2196 p < q
2197 with self.assertRaises(TypeError):
2198 p <= q
2199 with self.assertRaises(TypeError):
2200 p > q
2201 with self.assertRaises(TypeError):
2202 p >= q
2203
Raymond Hettingerbecd5682011-10-19 13:40:37 -07002204 def test_inplace_operations(self):
2205 elements = 'abcd'
2206 for i in range(1000):
2207 # test random pairs of multisets
2208 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2209 p.update(e=1, f=-1, g=0)
2210 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2211 q.update(h=1, i=-1, j=0)
2212 for inplace_op, regular_op in [
2213 (Counter.__iadd__, Counter.__add__),
2214 (Counter.__isub__, Counter.__sub__),
2215 (Counter.__ior__, Counter.__or__),
2216 (Counter.__iand__, Counter.__and__),
2217 ]:
2218 c = p.copy()
2219 c_id = id(c)
2220 regular_result = regular_op(c, q)
2221 inplace_result = inplace_op(c, q)
2222 self.assertEqual(inplace_result, regular_result)
2223 self.assertEqual(id(inplace_result), c_id)
2224
Raymond Hettinger9c01e442010-04-03 10:32:58 +00002225 def test_subtract(self):
2226 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2227 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
2228 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
2229 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2230 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
2231 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
2232 c = Counter('aaabbcd')
2233 c.subtract('aaaabbcce')
2234 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002235
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02002236 c = Counter()
2237 c.subtract(self=42)
2238 self.assertEqual(list(c.items()), [('self', -42)])
2239 c = Counter()
2240 c.subtract(iterable=42)
2241 self.assertEqual(list(c.items()), [('iterable', -42)])
2242 self.assertRaises(TypeError, Counter().subtract, 42)
2243 self.assertRaises(TypeError, Counter().subtract, {}, {})
2244 self.assertRaises(TypeError, Counter.subtract)
2245
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07002246 def test_unary(self):
2247 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2248 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
2249 self.assertEqual(dict(-c), dict(a=5))
2250
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07002251 def test_repr_nonsortable(self):
2252 c = Counter(a=2, b=None)
2253 r = repr(c)
2254 self.assertIn("'a': 2", r)
2255 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07002256
Raymond Hettinger426e0522011-01-03 02:12:02 +00002257 def test_helper_function(self):
2258 # two paths, one for real dicts and one for other mappings
2259 elems = list('abracadabra')
2260
2261 d = dict()
2262 _count_elements(d, elems)
2263 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
2264
2265 m = OrderedDict()
2266 _count_elements(m, elems)
2267 self.assertEqual(m,
2268 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
2269
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002270 # test fidelity to the pure python version
2271 c = CounterSubclassWithSetItem('abracadabra')
2272 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07002273 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002274 c = CounterSubclassWithGet('abracadabra')
2275 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07002276 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002277
Raymond Hettinger499e1932011-02-23 07:56:53 +00002278
2279################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00002280### Run tests
2281################################################################################
2282
Guido van Rossumd8faa362007-04-27 19:54:29 +00002283def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00002284 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002285 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00002286 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06002287 TestUserObjects,
2288 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002289 support.run_unittest(*test_classes)
2290 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002291
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002292
Guido van Rossumd8faa362007-04-27 19:54:29 +00002293if __name__ == "__main__":
2294 test_main(verbose=True)