blob: e2ffaaafd454242ef0c875f53888dc2bbd195332 [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 Storchaka33e7ea52015-11-25 17:09:01 +02006import operator
7import pickle
8from random import choice, randrange
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02009import string
R. David Murray378c0cf2010-02-24 01:46:21 +000010import sys
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020011from test import support
Yury Selivanov75445082015-05-11 22:57:16 -040012import types
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020013import unittest
14
15from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger573b44c2015-05-22 16:56:32 -070016from collections import UserDict, UserString, UserList
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000017from collections import ChainMap
Raymond Hettinger32ea1652015-03-21 01:37:37 -070018from collections import deque
Yury Selivanov22214ab2016-11-16 18:25:04 -050019from collections.abc import Awaitable, Coroutine
20from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator
Guido van Rossum16ca06b2016-04-04 10:59:29 -070021from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
Guido van Rossumf0666942016-08-23 10:47:07 -070022from collections.abc import Sized, Container, Callable, Collection
Raymond Hettinger57d1a882011-02-23 00:46:28 +000023from collections.abc import Set, MutableSet
Raymond Hettinger584e8ae2016-05-05 11:14:06 +030024from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
Raymond Hettinger57d1a882011-02-23 00:46:28 +000025from collections.abc import Sequence, MutableSequence
26from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000027
Raymond Hettinger499e1932011-02-23 07:56:53 +000028
Raymond Hettinger573b44c2015-05-22 16:56:32 -070029class TestUserObjects(unittest.TestCase):
30 def _superset_test(self, a, b):
31 self.assertGreaterEqual(
32 set(dir(a)),
33 set(dir(b)),
34 '{a} should have all the methods of {b}'.format(
35 a=a.__name__,
36 b=b.__name__,
37 ),
38 )
39 def test_str_protocol(self):
40 self._superset_test(UserString, str)
41
42 def test_list_protocol(self):
43 self._superset_test(UserList, list)
44
45 def test_dict_protocol(self):
46 self._superset_test(UserDict, dict)
47
48
Raymond Hettinger499e1932011-02-23 07:56:53 +000049################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000050### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000051################################################################################
52
53class TestChainMap(unittest.TestCase):
54
55 def test_basics(self):
56 c = ChainMap()
57 c['a'] = 1
58 c['b'] = 2
59 d = c.new_child()
60 d['b'] = 20
61 d['c'] = 30
62 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
63 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
64 self.assertEqual(len(d), 3) # check len
65 for key in 'abc': # check contains
66 self.assertIn(key, d)
67 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
68 self.assertEqual(d.get(k, 100), v)
69
70 del d['b'] # unmask a value
71 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
72 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
73 self.assertEqual(len(d), 3) # check len
74 for key in 'abc': # check contains
75 self.assertIn(key, d)
76 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
77 self.assertEqual(d.get(k, 100), v)
78 self.assertIn(repr(d), [ # check repr
79 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
80 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
81 ])
82
83 for e in d.copy(), copy.copy(d): # check shallow copies
84 self.assertEqual(d, e)
85 self.assertEqual(d.maps, e.maps)
86 self.assertIsNot(d, e)
87 self.assertIsNot(d.maps[0], e.maps[0])
88 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
89 self.assertIs(m1, m2)
90
Serhiy Storchakabad12572014-12-15 14:03:42 +020091 # check deep copies
92 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
93 e = pickle.loads(pickle.dumps(d, proto))
94 self.assertEqual(d, e)
95 self.assertEqual(d.maps, e.maps)
96 self.assertIsNot(d, e)
97 for m1, m2 in zip(d.maps, e.maps):
98 self.assertIsNot(m1, m2, e)
99 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +0000100 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200101 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000102 self.assertEqual(d, e)
103 self.assertEqual(d.maps, e.maps)
104 self.assertIsNot(d, e)
105 for m1, m2 in zip(d.maps, e.maps):
106 self.assertIsNot(m1, m2, e)
107
Raymond Hettingerd0321312011-02-26 06:53:58 +0000108 f = d.new_child()
109 f['b'] = 5
110 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
111 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
112 self.assertEqual(f['b'], 5) # find first in chain
113 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000114
Martin Pantereb995702016-07-28 01:11:04 +0000115 def test_constructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000116 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000117 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
118
Raymond Hettingerd0321312011-02-26 06:53:58 +0000119 def test_bool(self):
120 self.assertFalse(ChainMap())
121 self.assertFalse(ChainMap({}, {}))
122 self.assertTrue(ChainMap({1:2}, {}))
123 self.assertTrue(ChainMap({}, {1:2}))
124
Raymond Hettinger499e1932011-02-23 07:56:53 +0000125 def test_missing(self):
126 class DefaultChainMap(ChainMap):
127 def __missing__(self, key):
128 return 999
129 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
130 for k, v in dict(a=1, b=2, c=30, d=999).items():
131 self.assertEqual(d[k], v) # check __getitem__ w/missing
132 for k, v in dict(a=1, b=2, c=30, d=77).items():
133 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
134 for k, v in dict(a=True, b=True, c=True, d=False).items():
135 self.assertEqual(k in d, v) # check __contains__ w/missing
136 self.assertEqual(d.pop('a', 1001), 1, d)
137 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
138 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
139 with self.assertRaises(KeyError):
140 d.popitem()
141
Raymond Hettinger3793f952018-02-11 00:30:31 -0800142 def test_order_preservation(self):
143 d = ChainMap(
144 OrderedDict(j=0, h=88888),
145 OrderedDict(),
146 OrderedDict(i=9999, d=4444, c=3333),
147 OrderedDict(f=666, b=222, g=777, c=333, h=888),
148 OrderedDict(),
149 OrderedDict(e=55, b=22),
150 OrderedDict(a=1, b=2, c=3, d=4, e=5),
151 OrderedDict(),
152 )
153 self.assertEqual(''.join(d), 'abcdefghij')
154 self.assertEqual(list(d.items()),
155 [('a', 1), ('b', 222), ('c', 3333), ('d', 4444),
156 ('e', 55), ('f', 666), ('g', 777), ('h', 88888),
157 ('i', 9999), ('j', 0)])
158
Raymond Hettinger499e1932011-02-23 07:56:53 +0000159 def test_dict_coercion(self):
160 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
161 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
162 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
163
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000164 def test_new_child(self):
165 'Tests for changes for issue #16613.'
166 c = ChainMap()
167 c['a'] = 1
168 c['b'] = 2
169 m = {'b':20, 'c': 30}
170 d = c.new_child(m)
171 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
172 self.assertIs(m, d.maps[0])
173
174 # Use a different map than a dict
175 class lowerdict(dict):
176 def __getitem__(self, key):
177 if isinstance(key, str):
178 key = key.lower()
179 return dict.__getitem__(self, key)
180 def __contains__(self, key):
181 if isinstance(key, str):
182 key = key.lower()
183 return dict.__contains__(self, key)
184
185 c = ChainMap()
186 c['a'] = 1
187 c['b'] = 2
188 m = lowerdict(b=20, c=30)
189 d = c.new_child(m)
190 self.assertIs(m, d.maps[0])
191 for key in 'abc': # check contains
192 self.assertIn(key, d)
193 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
194 self.assertEqual(d.get(k, 100), v)
195
Raymond Hettinger499e1932011-02-23 07:56:53 +0000196
197################################################################################
198### Named Tuples
199################################################################################
200
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000201TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000202
203class TestNamedTuple(unittest.TestCase):
204
205 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000206 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000207 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000208 self.assertEqual(Point.__slots__, ())
209 self.assertEqual(Point.__module__, __name__)
210 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000211 self.assertEqual(Point._fields, ('x', 'y'))
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000212
213 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
214 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
215 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
216
217 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
218 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
219 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000220 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000221 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
222
223 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000224 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000225
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000226 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000227 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000228 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000229 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000230
Christian Heimesfaf2f632008-01-06 16:59:19 +0000231 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
232 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
233
Raymond Hettinger39482072018-01-10 21:45:19 -0800234 def test_defaults(self):
235 Point = namedtuple('Point', 'x y', defaults=(10, 20)) # 2 defaults
236 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
237 self.assertEqual(Point(1, 2), (1, 2))
238 self.assertEqual(Point(1), (1, 20))
239 self.assertEqual(Point(), (10, 20))
240
241 Point = namedtuple('Point', 'x y', defaults=(20,)) # 1 default
242 self.assertEqual(Point._fields_defaults, {'y': 20})
243 self.assertEqual(Point(1, 2), (1, 2))
244 self.assertEqual(Point(1), (1, 20))
245
246 Point = namedtuple('Point', 'x y', defaults=()) # 0 defaults
247 self.assertEqual(Point._fields_defaults, {})
248 self.assertEqual(Point(1, 2), (1, 2))
249 with self.assertRaises(TypeError):
250 Point(1)
251
252 with self.assertRaises(TypeError): # catch too few args
253 Point()
254 with self.assertRaises(TypeError): # catch too many args
255 Point(1, 2, 3)
256 with self.assertRaises(TypeError): # too many defaults
257 Point = namedtuple('Point', 'x y', defaults=(10, 20, 30))
258 with self.assertRaises(TypeError): # non-iterable defaults
259 Point = namedtuple('Point', 'x y', defaults=10)
260 with self.assertRaises(TypeError): # another non-iterable default
261 Point = namedtuple('Point', 'x y', defaults=False)
262
263 Point = namedtuple('Point', 'x y', defaults=None) # default is None
264 self.assertEqual(Point._fields_defaults, {})
265 self.assertIsNone(Point.__new__.__defaults__, None)
266 self.assertEqual(Point(10, 20), (10, 20))
267 with self.assertRaises(TypeError): # catch too few args
268 Point(10)
269
270 Point = namedtuple('Point', 'x y', defaults=[10, 20]) # allow non-tuple iterable
271 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
272 self.assertEqual(Point.__new__.__defaults__, (10, 20))
273 self.assertEqual(Point(1, 2), (1, 2))
274 self.assertEqual(Point(1), (1, 20))
275 self.assertEqual(Point(), (10, 20))
276
277 Point = namedtuple('Point', 'x y', defaults=iter([10, 20])) # allow plain iterator
278 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
279 self.assertEqual(Point.__new__.__defaults__, (10, 20))
280 self.assertEqual(Point(1, 2), (1, 2))
281 self.assertEqual(Point(1), (1, 20))
282 self.assertEqual(Point(), (10, 20))
283
284
R. David Murray378c0cf2010-02-24 01:46:21 +0000285 @unittest.skipIf(sys.flags.optimize >= 2,
286 "Docstrings are omitted with -O2 and above")
287 def test_factory_doc_attr(self):
288 Point = namedtuple('Point', 'x y')
289 self.assertEqual(Point.__doc__, 'Point(x, y)')
290
Raymond Hettingereac503a2015-05-13 01:09:59 -0700291 @unittest.skipIf(sys.flags.optimize >= 2,
292 "Docstrings are omitted with -O2 and above")
293 def test_doc_writable(self):
294 Point = namedtuple('Point', 'x y')
295 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
296 Point.x.__doc__ = 'docstring for Point.x'
297 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
298
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000299 def test_name_fixer(self):
300 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000301 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
302 [('abc', 'class'), ('abc', '_1')], # field has keyword
303 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
304 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
305 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
306 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000307 ]:
308 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
309
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700310 def test_module_parameter(self):
311 NT = namedtuple('NT', ['x', 'y'], module=collections)
312 self.assertEqual(NT.__module__, collections)
313
Guido van Rossumd8faa362007-04-27 19:54:29 +0000314 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000315 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000316 p = Point(11, 22)
317 self.assertEqual(p, Point(x=11, y=22))
318 self.assertEqual(p, Point(11, y=22))
319 self.assertEqual(p, Point(y=22, x=11))
320 self.assertEqual(p, Point(*(11, 22)))
321 self.assertEqual(p, Point(**dict(x=11, y=22)))
322 self.assertRaises(TypeError, Point, 1) # too few args
323 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
324 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
325 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
326 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000327 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000328 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000329 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
330 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700331 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000332
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000333 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000334 p._replace(x=1, error=2)
335 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000336 pass
337 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000338 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000339
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000340 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000341 Point = namedtuple('Point', 'x, y')
342 p = Point(x=11, y=22)
343 self.assertEqual(repr(p), 'Point(x=11, y=22)')
344
345 # verify that fieldspec can be a non-string sequence
346 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000347 p = Point(x=11, y=22)
348 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000349
350 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000351 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000352 p = Point(11, 22)
353
Ezio Melottie9615932010-01-24 19:26:24 +0000354 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000355 self.assertEqual(p, (11, 22)) # matches a real tuple
356 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
357 self.assertEqual(list(p), [11, 22]) # coercable to a list
358 self.assertEqual(max(p), 22) # iterable
359 self.assertEqual(max(*p), 22) # star-able
360 x, y = p
361 self.assertEqual(p, (x, y)) # unpacks like a tuple
362 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
363 self.assertRaises(IndexError, p.__getitem__, 3)
364
365 self.assertEqual(p.x, x)
366 self.assertEqual(p.y, y)
367 self.assertRaises(AttributeError, eval, 'p.z', locals())
368
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000369 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000370 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000371 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000372 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000373 self.assertEqual(repr(Zero()), 'Zero()')
374 self.assertEqual(Zero()._asdict(), {})
375 self.assertEqual(Zero()._fields, ())
376
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000377 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000378 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000379 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000380 self.assertEqual(Dot(1).d, 1)
381 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
382 self.assertEqual(Dot(1)._asdict(), {'d':1})
383 self.assertEqual(Dot(1)._replace(d=999), (999,))
384 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000385
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200386 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200387 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000388 for j in range(10)]) for i in range(n)))
389 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000390 Big = namedtuple('Big', names)
391 b = Big(*range(n))
392 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000393 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000394 for pos, name in enumerate(names):
395 self.assertEqual(getattr(b, name), pos)
396 repr(b) # make sure repr() doesn't blow-up
397 d = b._asdict()
398 d_expected = dict(zip(names, range(n)))
399 self.assertEqual(d, d_expected)
400 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
401 b2_expected = list(range(n))
402 b2_expected[1] = 999
403 b2_expected[-5] = 42
404 self.assertEqual(b2, tuple(b2_expected))
405 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000406
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000407 def test_pickle(self):
408 p = TestNT(x=10, y=20, z=30)
409 for module in (pickle,):
410 loads = getattr(module, 'loads')
411 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500412 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000413 q = loads(dumps(p, protocol))
414 self.assertEqual(p, q)
415 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700416 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000417
418 def test_copy(self):
419 p = TestNT(x=10, y=20, z=30)
420 for copier in copy.copy, copy.deepcopy:
421 q = copier(p)
422 self.assertEqual(p, q)
423 self.assertEqual(p._fields, q._fields)
424
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000425 def test_name_conflicts(self):
426 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
427 # failed when used as field names. Test to make sure these now work.
428 T = namedtuple('T', 'itemgetter property self cls tuple')
429 t = T(1, 2, 3, 4, 5)
430 self.assertEqual(t, (1,2,3,4,5))
431 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
432 self.assertEqual(newt, (10,20,30,40,50))
433
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700434 # Broader test of all interesting names taken from the code, old
435 # template, and an example
436 words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create',
437 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper',
438 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note',
439 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError',
440 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add',
441 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments',
442 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot',
443 'class_namespace', 'classmethod', 'cls', 'collections', 'convert',
444 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict',
445 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect',
446 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f',
447 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame',
448 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater',
449 'has', 'help', 'identifiers', 'index', 'indexable', 'instance',
450 'instantiate', 'interning', 'introspection', 'isidentifier',
451 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords',
452 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata',
453 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named',
454 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new',
455 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option',
456 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional',
457 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr',
458 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen',
459 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start',
460 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys',
461 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new',
462 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use',
463 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where',
464 'which', 'work', 'x', 'y', 'z', 'zip'}
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000465 T = namedtuple('T', words)
466 # test __new__
467 values = tuple(range(len(words)))
468 t = T(*values)
469 self.assertEqual(t, values)
470 t = T(**dict(zip(T._fields, values)))
471 self.assertEqual(t, values)
472 # test _make
473 t = T._make(values)
474 self.assertEqual(t, values)
475 # exercise __repr__
476 repr(t)
477 # test _asdict
478 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
479 # test _replace
480 t = T._make(values)
481 newvalues = tuple(v*10 for v in values)
482 newt = t._replace(**dict(zip(T._fields, newvalues)))
483 self.assertEqual(newt, newvalues)
484 # test _fields
485 self.assertEqual(T._fields, tuple(words))
486 # test __getnewargs__
487 self.assertEqual(t.__getnewargs__(), values)
488
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000489 def test_repr(self):
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700490 A = namedtuple('A', 'x')
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000491 self.assertEqual(repr(A(1)), 'A(x=1)')
492 # repr should show the name of the subclass
493 class B(A):
494 pass
495 self.assertEqual(repr(B(1)), 'B(x=1)')
496
Raymond Hettinger6538b432016-08-16 10:55:43 -0700497 def test_keyword_only_arguments(self):
498 # See issue 25628
Raymond Hettinger6538b432016-08-16 10:55:43 -0700499 with self.assertRaises(TypeError):
500 NT = namedtuple('NT', ['x', 'y'], True)
501
502 NT = namedtuple('NT', ['abc', 'def'], rename=True)
503 self.assertEqual(NT._fields, ('abc', '_1'))
504 with self.assertRaises(TypeError):
505 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000506
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700507 def test_namedtuple_subclass_issue_24931(self):
508 class Point(namedtuple('_Point', ['x', 'y'])):
509 pass
510
511 a = Point(3, 4)
512 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
513
514 a.w = 5
515 self.assertEqual(a.__dict__, {'w': 5})
516
517
Raymond Hettinger499e1932011-02-23 07:56:53 +0000518################################################################################
519### Abstract Base Classes
520################################################################################
521
Raymond Hettingerae650182009-01-28 23:33:59 +0000522class ABCTestCase(unittest.TestCase):
523
524 def validate_abstract_methods(self, abc, *names):
525 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
526
527 # everything should work will all required methods are present
528 C = type('C', (abc,), methodstubs)
529 C()
530
531 # instantiation should fail if a required method is missing
532 for name in names:
533 stubs = methodstubs.copy()
534 del stubs[name]
535 C = type('C', (abc,), stubs)
536 self.assertRaises(TypeError, C, name)
537
Florent Xiclunace153f62010-03-08 15:34:35 +0000538 def validate_isinstance(self, abc, name):
539 stub = lambda s, *args: 0
540
541 C = type('C', (object,), {'__hash__': None})
542 setattr(C, name, stub)
543 self.assertIsInstance(C(), abc)
544 self.assertTrue(issubclass(C, abc))
545
546 C = type('C', (object,), {'__hash__': None})
547 self.assertNotIsInstance(C(), abc)
548 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000549
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000550 def validate_comparison(self, instance):
551 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
552 operators = {}
553 for op in ops:
554 name = '__' + op + '__'
555 operators[name] = getattr(operator, name)
556
557 class Other:
558 def __init__(self):
559 self.right_side = False
560 def __eq__(self, other):
561 self.right_side = True
562 return True
563 __lt__ = __eq__
564 __gt__ = __eq__
565 __le__ = __eq__
566 __ge__ = __eq__
567 __ne__ = __eq__
568 __ror__ = __eq__
569 __rand__ = __eq__
570 __rxor__ = __eq__
571 __rsub__ = __eq__
572
573 for name, op in operators.items():
574 if not hasattr(instance, name):
575 continue
576 other = Other()
577 op(instance, other)
578 self.assertTrue(other.right_side,'Right side not called for %s.%s'
579 % (type(instance), name))
580
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700581def _test_gen():
582 yield
583
Raymond Hettingerae650182009-01-28 23:33:59 +0000584class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000585
Yury Selivanov75445082015-05-11 22:57:16 -0400586 def test_Awaitable(self):
587 def gen():
588 yield
589
590 @types.coroutine
591 def coro():
592 yield
593
594 async def new_coro():
595 pass
596
597 class Bar:
598 def __await__(self):
599 yield
600
601 class MinimalCoro(Coroutine):
602 def send(self, value):
603 return value
604 def throw(self, typ, val=None, tb=None):
605 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400606 def __await__(self):
607 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400608
609 non_samples = [None, int(), gen(), object()]
610 for x in non_samples:
611 self.assertNotIsInstance(x, Awaitable)
612 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
613
614 samples = [Bar(), MinimalCoro()]
615 for x in samples:
616 self.assertIsInstance(x, Awaitable)
617 self.assertTrue(issubclass(type(x), Awaitable))
618
619 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400620 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
621 # flag don't have '__await__' method, hence can't be instances
622 # of Awaitable. Use inspect.isawaitable to detect them.
623 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400624
625 c = new_coro()
626 self.assertIsInstance(c, Awaitable)
Mike53f7a7c2017-12-14 14:04:53 +0300627 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400628
Yury Selivanov56fc6142015-05-29 09:01:29 -0400629 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400630 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400631 self.assertTrue(isinstance(CoroLike(), Awaitable))
632 self.assertTrue(issubclass(CoroLike, Awaitable))
633 CoroLike = None
634 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400635
Yury Selivanov75445082015-05-11 22:57:16 -0400636 def test_Coroutine(self):
637 def gen():
638 yield
639
640 @types.coroutine
641 def coro():
642 yield
643
644 async def new_coro():
645 pass
646
647 class Bar:
648 def __await__(self):
649 yield
650
651 class MinimalCoro(Coroutine):
652 def send(self, value):
653 return value
654 def throw(self, typ, val=None, tb=None):
655 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400656 def __await__(self):
657 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400658
659 non_samples = [None, int(), gen(), object(), Bar()]
660 for x in non_samples:
661 self.assertNotIsInstance(x, Coroutine)
662 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
663
664 samples = [MinimalCoro()]
665 for x in samples:
666 self.assertIsInstance(x, Awaitable)
667 self.assertTrue(issubclass(type(x), Awaitable))
668
669 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400670 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
671 # flag don't have '__await__' method, hence can't be instances
672 # of Coroutine. Use inspect.isawaitable to detect them.
673 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400674
675 c = new_coro()
676 self.assertIsInstance(c, Coroutine)
Mike53f7a7c2017-12-14 14:04:53 +0300677 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400678
Yury Selivanov56fc6142015-05-29 09:01:29 -0400679 class CoroLike:
680 def send(self, value):
681 pass
682 def throw(self, typ, val=None, tb=None):
683 pass
684 def close(self):
685 pass
686 def __await__(self):
687 pass
688 self.assertTrue(isinstance(CoroLike(), Coroutine))
689 self.assertTrue(issubclass(CoroLike, Coroutine))
690
691 class CoroLike:
692 def send(self, value):
693 pass
694 def close(self):
695 pass
696 def __await__(self):
697 pass
698 self.assertFalse(isinstance(CoroLike(), Coroutine))
699 self.assertFalse(issubclass(CoroLike, Coroutine))
700
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000701 def test_Hashable(self):
702 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000703 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000704 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000705 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000706 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000707 # Check some hashables
708 samples = [None,
709 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000710 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000711 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000712 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000713 ]
714 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000715 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000716 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000717 self.assertRaises(TypeError, Hashable)
718 # Check direct subclassing
719 class H(Hashable):
720 def __hash__(self):
721 return super().__hash__()
722 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000723 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000724 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000725 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000726
Yury Selivanove0104ae2015-05-14 12:19:16 -0400727 def test_AsyncIterable(self):
728 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400729 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400730 return self
731 self.assertTrue(isinstance(AI(), AsyncIterable))
732 self.assertTrue(issubclass(AI, AsyncIterable))
733 # Check some non-iterables
734 non_samples = [None, object, []]
735 for x in non_samples:
736 self.assertNotIsInstance(x, AsyncIterable)
737 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
738 self.validate_abstract_methods(AsyncIterable, '__aiter__')
739 self.validate_isinstance(AsyncIterable, '__aiter__')
740
741 def test_AsyncIterator(self):
742 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400743 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400744 return self
745 async def __anext__(self):
746 raise StopAsyncIteration
747 self.assertTrue(isinstance(AI(), AsyncIterator))
748 self.assertTrue(issubclass(AI, AsyncIterator))
749 non_samples = [None, object, []]
750 # Check some non-iterables
751 for x in non_samples:
752 self.assertNotIsInstance(x, AsyncIterator)
753 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
754 # Similarly to regular iterators (see issue 10565)
755 class AnextOnly:
756 async def __anext__(self):
757 raise StopAsyncIteration
758 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
759 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
760
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000761 def test_Iterable(self):
762 # Check some non-iterables
763 non_samples = [None, 42, 3.14, 1j]
764 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000765 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000766 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000767 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000768 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000769 tuple(), list(), set(), frozenset(), dict(),
770 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700771 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000772 (x for x in []),
773 ]
774 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000775 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000776 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000777 # Check direct subclassing
778 class I(Iterable):
779 def __iter__(self):
780 return super().__iter__()
781 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000782 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000783 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000784 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700785 # Check None blocking
786 class It:
787 def __iter__(self): return iter([])
788 class ItBlocked(It):
789 __iter__ = None
790 self.assertTrue(issubclass(It, Iterable))
791 self.assertTrue(isinstance(It(), Iterable))
792 self.assertFalse(issubclass(ItBlocked, Iterable))
793 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000794
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700795 def test_Reversible(self):
796 # Check some non-reversibles
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100797 non_samples = [None, 42, 3.14, 1j, set(), frozenset()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700798 for x in non_samples:
799 self.assertNotIsInstance(x, Reversible)
800 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700801 # Check some non-reversible iterables
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100802 non_reversibles = [_test_gen(), (x for x in []), iter([]), reversed([])]
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700803 for x in non_reversibles:
804 self.assertNotIsInstance(x, Reversible)
805 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
806 # Check some reversible iterables
807 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
808 OrderedDict().keys(), OrderedDict().items(),
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100809 OrderedDict().values(), Counter(), Counter().keys(),
810 Counter().items(), Counter().values(), dict(),
811 dict().keys(), dict().items(), dict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700812 for x in samples:
813 self.assertIsInstance(x, Reversible)
814 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
815 # Check also Mapping, MutableMapping, and Sequence
816 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
817 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
818 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
819 # Check direct subclassing
820 class R(Reversible):
821 def __iter__(self):
822 return iter(list())
823 def __reversed__(self):
824 return iter(list())
825 self.assertEqual(list(reversed(R())), [])
826 self.assertFalse(issubclass(float, R))
827 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700828 # Check reversible non-iterable (which is not Reversible)
829 class RevNoIter:
830 def __reversed__(self): return reversed([])
831 class RevPlusIter(RevNoIter):
832 def __iter__(self): return iter([])
833 self.assertFalse(issubclass(RevNoIter, Reversible))
834 self.assertFalse(isinstance(RevNoIter(), Reversible))
835 self.assertTrue(issubclass(RevPlusIter, Reversible))
836 self.assertTrue(isinstance(RevPlusIter(), Reversible))
837 # Check None blocking
838 class Rev:
839 def __iter__(self): return iter([])
840 def __reversed__(self): return reversed([])
841 class RevItBlocked(Rev):
842 __iter__ = None
843 class RevRevBlocked(Rev):
844 __reversed__ = None
845 self.assertTrue(issubclass(Rev, Reversible))
846 self.assertTrue(isinstance(Rev(), Reversible))
847 self.assertFalse(issubclass(RevItBlocked, Reversible))
848 self.assertFalse(isinstance(RevItBlocked(), Reversible))
849 self.assertFalse(issubclass(RevRevBlocked, Reversible))
850 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700851
Guido van Rossumf0666942016-08-23 10:47:07 -0700852 def test_Collection(self):
853 # Check some non-collections
854 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
855 for x in non_collections:
856 self.assertNotIsInstance(x, Collection)
857 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
858 # Check some non-collection iterables
859 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800860 (x for x in [])]
Guido van Rossumf0666942016-08-23 10:47:07 -0700861 for x in non_col_iterables:
862 self.assertNotIsInstance(x, Collection)
863 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
864 # Check some collections
865 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800866 list(), dict().keys(), dict().items(), dict().values()]
Guido van Rossumf0666942016-08-23 10:47:07 -0700867 for x in samples:
868 self.assertIsInstance(x, Collection)
869 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
870 # Check also Mapping, MutableMapping, etc.
871 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
872 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
873 self.assertTrue(issubclass(MutableMapping, Collection),
874 repr(MutableMapping))
875 self.assertTrue(issubclass(Set, Collection), repr(Set))
876 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
877 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
878 # Check direct subclassing
879 class Col(Collection):
880 def __iter__(self):
881 return iter(list())
882 def __len__(self):
883 return 0
884 def __contains__(self, item):
885 return False
886 class DerCol(Col): pass
887 self.assertEqual(list(iter(Col())), [])
888 self.assertFalse(issubclass(list, Col))
889 self.assertFalse(issubclass(set, Col))
890 self.assertFalse(issubclass(float, Col))
891 self.assertEqual(list(iter(DerCol())), [])
892 self.assertFalse(issubclass(list, DerCol))
893 self.assertFalse(issubclass(set, DerCol))
894 self.assertFalse(issubclass(float, DerCol))
895 self.validate_abstract_methods(Collection, '__len__', '__iter__',
896 '__contains__')
897 # Check sized container non-iterable (which is not Collection) etc.
898 class ColNoIter:
899 def __len__(self): return 0
900 def __contains__(self, item): return False
901 class ColNoSize:
902 def __iter__(self): return iter([])
903 def __contains__(self, item): return False
904 class ColNoCont:
905 def __iter__(self): return iter([])
906 def __len__(self): return 0
907 self.assertFalse(issubclass(ColNoIter, Collection))
908 self.assertFalse(isinstance(ColNoIter(), Collection))
909 self.assertFalse(issubclass(ColNoSize, Collection))
910 self.assertFalse(isinstance(ColNoSize(), Collection))
911 self.assertFalse(issubclass(ColNoCont, Collection))
912 self.assertFalse(isinstance(ColNoCont(), Collection))
913 # Check None blocking
914 class SizeBlock:
915 def __iter__(self): return iter([])
916 def __contains__(self): return False
917 __len__ = None
918 class IterBlock:
919 def __len__(self): return 0
920 def __contains__(self): return True
921 __iter__ = None
922 self.assertFalse(issubclass(SizeBlock, Collection))
923 self.assertFalse(isinstance(SizeBlock(), Collection))
924 self.assertFalse(issubclass(IterBlock, Collection))
925 self.assertFalse(isinstance(IterBlock(), Collection))
926 # Check None blocking in subclass
927 class ColImpl:
928 def __iter__(self):
929 return iter(list())
930 def __len__(self):
931 return 0
932 def __contains__(self, item):
933 return False
934 class NonCol(ColImpl):
935 __contains__ = None
936 self.assertFalse(issubclass(NonCol, Collection))
937 self.assertFalse(isinstance(NonCol(), Collection))
938
939
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000940 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000941 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000942 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000943 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000944 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000945 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000946 iter(tuple()), iter(list()), iter(dict()),
947 iter(set()), iter(frozenset()),
948 iter(dict().keys()), iter(dict().items()),
949 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700950 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000951 (x for x in []),
952 ]
953 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000954 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000955 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000956 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
957
958 # Issue 10565
959 class NextOnly:
960 def __next__(self):
961 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800962 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000963 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000964
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400965 def test_Generator(self):
966 class NonGen1:
967 def __iter__(self): return self
968 def __next__(self): return None
969 def close(self): pass
970 def throw(self, typ, val=None, tb=None): pass
971
972 class NonGen2:
973 def __iter__(self): return self
974 def __next__(self): return None
975 def close(self): pass
976 def send(self, value): return value
977
978 class NonGen3:
979 def close(self): pass
980 def send(self, value): return value
981 def throw(self, typ, val=None, tb=None): pass
982
983 non_samples = [
984 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
985 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
986 for x in non_samples:
987 self.assertNotIsInstance(x, Generator)
988 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
989
990 class Gen:
991 def __iter__(self): return self
992 def __next__(self): return None
993 def close(self): pass
994 def send(self, value): return value
995 def throw(self, typ, val=None, tb=None): pass
996
997 class MinimalGen(Generator):
998 def send(self, value):
999 return value
1000 def throw(self, typ, val=None, tb=None):
1001 super().throw(typ, val, tb)
1002
1003 def gen():
1004 yield 1
1005
1006 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
1007 for x in samples:
1008 self.assertIsInstance(x, Iterator)
1009 self.assertIsInstance(x, Generator)
1010 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
1011 self.validate_abstract_methods(Generator, 'send', 'throw')
1012
1013 # mixin tests
1014 mgen = MinimalGen()
1015 self.assertIs(mgen, iter(mgen))
1016 self.assertIs(mgen.send(None), next(mgen))
1017 self.assertEqual(2, mgen.send(2))
1018 self.assertIsNone(mgen.close())
1019 self.assertRaises(ValueError, mgen.throw, ValueError)
1020 self.assertRaisesRegex(ValueError, "^huhu$",
1021 mgen.throw, ValueError, ValueError("huhu"))
1022 self.assertRaises(StopIteration, mgen.throw, StopIteration())
1023
1024 class FailOnClose(Generator):
1025 def send(self, value): return value
1026 def throw(self, *args): raise ValueError
1027
1028 self.assertRaises(ValueError, FailOnClose().close)
1029
1030 class IgnoreGeneratorExit(Generator):
1031 def send(self, value): return value
1032 def throw(self, *args): pass
1033
1034 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
1035
Yury Selivanov22214ab2016-11-16 18:25:04 -05001036 def test_AsyncGenerator(self):
1037 class NonAGen1:
1038 def __aiter__(self): return self
1039 def __anext__(self): return None
1040 def aclose(self): pass
1041 def athrow(self, typ, val=None, tb=None): pass
1042
1043 class NonAGen2:
1044 def __aiter__(self): return self
1045 def __anext__(self): return None
1046 def aclose(self): pass
1047 def asend(self, value): return value
1048
1049 class NonAGen3:
1050 def aclose(self): pass
1051 def asend(self, value): return value
1052 def athrow(self, typ, val=None, tb=None): pass
1053
1054 non_samples = [
1055 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1056 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
1057 for x in non_samples:
1058 self.assertNotIsInstance(x, AsyncGenerator)
1059 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
1060
1061 class Gen:
1062 def __aiter__(self): return self
1063 async def __anext__(self): return None
1064 async def aclose(self): pass
1065 async def asend(self, value): return value
1066 async def athrow(self, typ, val=None, tb=None): pass
1067
1068 class MinimalAGen(AsyncGenerator):
1069 async def asend(self, value):
1070 return value
1071 async def athrow(self, typ, val=None, tb=None):
1072 await super().athrow(typ, val, tb)
1073
1074 async def gen():
1075 yield 1
1076
1077 samples = [gen(), Gen(), MinimalAGen()]
1078 for x in samples:
1079 self.assertIsInstance(x, AsyncIterator)
1080 self.assertIsInstance(x, AsyncGenerator)
1081 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1082 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1083
1084 def run_async(coro):
1085 result = None
1086 while True:
1087 try:
1088 coro.send(None)
1089 except StopIteration as ex:
1090 result = ex.args[0] if ex.args else None
1091 break
1092 return result
1093
1094 # mixin tests
1095 mgen = MinimalAGen()
1096 self.assertIs(mgen, mgen.__aiter__())
1097 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1098 self.assertEqual(2, run_async(mgen.asend(2)))
1099 self.assertIsNone(run_async(mgen.aclose()))
1100 with self.assertRaises(ValueError):
1101 run_async(mgen.athrow(ValueError))
1102
1103 class FailOnClose(AsyncGenerator):
1104 async def asend(self, value): return value
1105 async def athrow(self, *args): raise ValueError
1106
1107 with self.assertRaises(ValueError):
1108 run_async(FailOnClose().aclose())
1109
1110 class IgnoreGeneratorExit(AsyncGenerator):
1111 async def asend(self, value): return value
1112 async def athrow(self, *args): pass
1113
1114 with self.assertRaises(RuntimeError):
1115 run_async(IgnoreGeneratorExit().aclose())
1116
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001117 def test_Sized(self):
1118 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001119 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001120 (x for x in []),
1121 ]
1122 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001123 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001124 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001125 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001126 tuple(), list(), set(), frozenset(), dict(),
1127 dict().keys(), dict().items(), dict().values(),
1128 ]
1129 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001130 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001131 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001132 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001133 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001134
1135 def test_Container(self):
1136 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001137 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001138 (x for x in []),
1139 ]
1140 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001141 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001142 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001143 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001144 tuple(), list(), set(), frozenset(), dict(),
1145 dict().keys(), dict().items(),
1146 ]
1147 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001148 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001149 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001150 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001151 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001152
1153 def test_Callable(self):
1154 non_samples = [None, 42, 3.14, 1j,
1155 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001156 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001157 (x for x in []),
1158 ]
1159 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001160 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001161 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001162 samples = [lambda: None,
1163 type, int, object,
1164 len,
1165 list.append, [].append,
1166 ]
1167 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001168 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001169 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001170 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001171 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001172
1173 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001174 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001175 class C(B):
1176 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001177 self.assertTrue(issubclass(C, B))
1178 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001179
1180 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001181 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001182 class C:
1183 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001184 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001185 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001186 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001187
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001188class WithSet(MutableSet):
1189
1190 def __init__(self, it=()):
1191 self.data = set(it)
1192
1193 def __len__(self):
1194 return len(self.data)
1195
1196 def __iter__(self):
1197 return iter(self.data)
1198
1199 def __contains__(self, item):
1200 return item in self.data
1201
1202 def add(self, item):
1203 self.data.add(item)
1204
1205 def discard(self, item):
1206 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001207
Raymond Hettingerae650182009-01-28 23:33:59 +00001208class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001209
1210 # XXX For now, we only test some virtual inheritance properties.
1211 # We should also test the proper behavior of the collection ABCs
1212 # as real base classes or mix-in classes.
1213
1214 def test_Set(self):
1215 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001216 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001217 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001218 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001219 class MySet(Set):
1220 def __contains__(self, x):
1221 return False
1222 def __len__(self):
1223 return 0
1224 def __iter__(self):
1225 return iter([])
1226 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001227
Benjamin Peterson41181742008-07-02 20:22:54 +00001228 def test_hash_Set(self):
1229 class OneTwoThreeSet(Set):
1230 def __init__(self):
1231 self.contents = [1, 2, 3]
1232 def __contains__(self, x):
1233 return x in self.contents
1234 def __len__(self):
1235 return len(self.contents)
1236 def __iter__(self):
1237 return iter(self.contents)
1238 def __hash__(self):
1239 return self._hash()
1240 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001241 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001242
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001243 def test_isdisjoint_Set(self):
1244 class MySet(Set):
1245 def __init__(self, itr):
1246 self.contents = itr
1247 def __contains__(self, x):
1248 return x in self.contents
1249 def __iter__(self):
1250 return iter(self.contents)
1251 def __len__(self):
1252 return len([x for x in self.contents])
1253 s1 = MySet((1, 2, 3))
1254 s2 = MySet((4, 5, 6))
1255 s3 = MySet((1, 5, 6))
1256 self.assertTrue(s1.isdisjoint(s2))
1257 self.assertFalse(s1.isdisjoint(s3))
1258
1259 def test_equality_Set(self):
1260 class MySet(Set):
1261 def __init__(self, itr):
1262 self.contents = itr
1263 def __contains__(self, x):
1264 return x in self.contents
1265 def __iter__(self):
1266 return iter(self.contents)
1267 def __len__(self):
1268 return len([x for x in self.contents])
1269 s1 = MySet((1,))
1270 s2 = MySet((1, 2))
1271 s3 = MySet((3, 4))
1272 s4 = MySet((3, 4))
1273 self.assertTrue(s2 > s1)
1274 self.assertTrue(s1 < s2)
1275 self.assertFalse(s2 <= s1)
1276 self.assertFalse(s2 <= s3)
1277 self.assertFalse(s1 >= s2)
1278 self.assertEqual(s3, s4)
1279 self.assertNotEqual(s2, s3)
1280
1281 def test_arithmetic_Set(self):
1282 class MySet(Set):
1283 def __init__(self, itr):
1284 self.contents = itr
1285 def __contains__(self, x):
1286 return x in self.contents
1287 def __iter__(self):
1288 return iter(self.contents)
1289 def __len__(self):
1290 return len([x for x in self.contents])
1291 s1 = MySet((1, 2, 3))
1292 s2 = MySet((3, 4, 5))
1293 s3 = s1 & s2
1294 self.assertEqual(s3, MySet((3,)))
1295
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001296 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001297 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001298 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001299 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001300 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001301 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1302 'add', 'discard')
1303
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001304 def test_issue_5647(self):
1305 # MutableSet.__iand__ mutated the set during iteration
1306 s = WithSet('abcd')
1307 s &= WithSet('cdef') # This used to fail
1308 self.assertEqual(set(s), set('cd'))
1309
Raymond Hettingerae650182009-01-28 23:33:59 +00001310 def test_issue_4920(self):
1311 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001312 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001313 __slots__=['__s']
1314 def __init__(self,items=None):
1315 if items is None:
1316 items=[]
1317 self.__s=set(items)
1318 def __contains__(self,v):
1319 return v in self.__s
1320 def __iter__(self):
1321 return iter(self.__s)
1322 def __len__(self):
1323 return len(self.__s)
1324 def add(self,v):
1325 result=v not in self.__s
1326 self.__s.add(v)
1327 return result
1328 def discard(self,v):
1329 result=v in self.__s
1330 self.__s.discard(v)
1331 return result
1332 def __repr__(self):
1333 return "MySet(%s)" % repr(list(self))
1334 s = MySet([5,43,2,1])
1335 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001336
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001337 def test_issue8750(self):
1338 empty = WithSet()
1339 full = WithSet(range(10))
1340 s = WithSet(full)
1341 s -= s
1342 self.assertEqual(s, empty)
1343 s = WithSet(full)
1344 s ^= s
1345 self.assertEqual(s, empty)
1346 s = WithSet(full)
1347 s &= s
1348 self.assertEqual(s, full)
1349 s |= s
1350 self.assertEqual(s, full)
1351
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001352 def test_issue16373(self):
1353 # Recursion error comparing comparable and noncomparable
1354 # Set instances
1355 class MyComparableSet(Set):
1356 def __contains__(self, x):
1357 return False
1358 def __len__(self):
1359 return 0
1360 def __iter__(self):
1361 return iter([])
1362 class MyNonComparableSet(Set):
1363 def __contains__(self, x):
1364 return False
1365 def __len__(self):
1366 return 0
1367 def __iter__(self):
1368 return iter([])
1369 def __le__(self, x):
1370 return NotImplemented
1371 def __lt__(self, x):
1372 return NotImplemented
1373
1374 cs = MyComparableSet()
1375 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001376 self.assertFalse(ncs < cs)
1377 self.assertTrue(ncs <= cs)
1378 self.assertFalse(ncs > cs)
1379 self.assertTrue(ncs >= cs)
1380
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001381 def test_issue26915(self):
1382 # Container membership test should check identity first
1383 class CustomEqualObject:
1384 def __eq__(self, other):
1385 return False
Xiang Zhangd5d32492017-03-08 11:04:24 +08001386 class CustomSequence(Sequence):
1387 def __init__(self, seq):
1388 self._seq = seq
1389 def __getitem__(self, index):
1390 return self._seq[index]
1391 def __len__(self):
1392 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001393
1394 nan = float('nan')
1395 obj = CustomEqualObject()
Xiang Zhangd5d32492017-03-08 11:04:24 +08001396 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001397 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001398 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001399 ItemsView({1: nan, 2: obj}),
1400 ValuesView({1: nan, 2: obj})
1401 ]
1402 for container in containers:
1403 for elem in container:
1404 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001405 self.assertEqual(seq.index(nan), 0)
1406 self.assertEqual(seq.index(obj), 1)
1407 self.assertEqual(seq.count(nan), 2)
1408 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001409
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001410 def assertSameSet(self, s1, s2):
1411 # coerce both to a real set then check equality
1412 self.assertSetEqual(set(s1), set(s2))
1413
1414 def test_Set_interoperability_with_real_sets(self):
1415 # Issue: 8743
1416 class ListSet(Set):
1417 def __init__(self, elements=()):
1418 self.data = []
1419 for elem in elements:
1420 if elem not in self.data:
1421 self.data.append(elem)
1422 def __contains__(self, elem):
1423 return elem in self.data
1424 def __iter__(self):
1425 return iter(self.data)
1426 def __len__(self):
1427 return len(self.data)
1428 def __repr__(self):
1429 return 'Set({!r})'.format(self.data)
1430
1431 r1 = set('abc')
1432 r2 = set('bcd')
1433 r3 = set('abcde')
1434 f1 = ListSet('abc')
1435 f2 = ListSet('bcd')
1436 f3 = ListSet('abcde')
1437 l1 = list('abccba')
1438 l2 = list('bcddcb')
1439 l3 = list('abcdeedcba')
1440
1441 target = r1 & r2
1442 self.assertSameSet(f1 & f2, target)
1443 self.assertSameSet(f1 & r2, target)
1444 self.assertSameSet(r2 & f1, target)
1445 self.assertSameSet(f1 & l2, target)
1446
1447 target = r1 | r2
1448 self.assertSameSet(f1 | f2, target)
1449 self.assertSameSet(f1 | r2, target)
1450 self.assertSameSet(r2 | f1, target)
1451 self.assertSameSet(f1 | l2, target)
1452
1453 fwd_target = r1 - r2
1454 rev_target = r2 - r1
1455 self.assertSameSet(f1 - f2, fwd_target)
1456 self.assertSameSet(f2 - f1, rev_target)
1457 self.assertSameSet(f1 - r2, fwd_target)
1458 self.assertSameSet(f2 - r1, rev_target)
1459 self.assertSameSet(r1 - f2, fwd_target)
1460 self.assertSameSet(r2 - f1, rev_target)
1461 self.assertSameSet(f1 - l2, fwd_target)
1462 self.assertSameSet(f2 - l1, rev_target)
1463
1464 target = r1 ^ r2
1465 self.assertSameSet(f1 ^ f2, target)
1466 self.assertSameSet(f1 ^ r2, target)
1467 self.assertSameSet(r2 ^ f1, target)
1468 self.assertSameSet(f1 ^ l2, target)
1469
1470 # Don't change the following to use assertLess or other
1471 # "more specific" unittest assertions. The current
1472 # assertTrue/assertFalse style makes the pattern of test
1473 # case combinations clear and allows us to know for sure
1474 # the exact operator being invoked.
1475
1476 # proper subset
1477 self.assertTrue(f1 < f3)
1478 self.assertFalse(f1 < f1)
1479 self.assertFalse(f1 < f2)
1480 self.assertTrue(r1 < f3)
1481 self.assertFalse(r1 < f1)
1482 self.assertFalse(r1 < f2)
1483 self.assertTrue(r1 < r3)
1484 self.assertFalse(r1 < r1)
1485 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001486 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001487 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001488 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001489 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001490 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001491 f1 < l2
1492
1493 # any subset
1494 self.assertTrue(f1 <= f3)
1495 self.assertTrue(f1 <= f1)
1496 self.assertFalse(f1 <= f2)
1497 self.assertTrue(r1 <= f3)
1498 self.assertTrue(r1 <= f1)
1499 self.assertFalse(r1 <= f2)
1500 self.assertTrue(r1 <= r3)
1501 self.assertTrue(r1 <= r1)
1502 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001503 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001504 f1 <= l3
1505 with self.assertRaises(TypeError):
1506 f1 <= l1
1507 with self.assertRaises(TypeError):
1508 f1 <= l2
1509
1510 # proper superset
1511 self.assertTrue(f3 > f1)
1512 self.assertFalse(f1 > f1)
1513 self.assertFalse(f2 > f1)
1514 self.assertTrue(r3 > r1)
1515 self.assertFalse(f1 > r1)
1516 self.assertFalse(f2 > r1)
1517 self.assertTrue(r3 > r1)
1518 self.assertFalse(r1 > r1)
1519 self.assertFalse(r2 > r1)
1520 with self.assertRaises(TypeError):
1521 f1 > l3
1522 with self.assertRaises(TypeError):
1523 f1 > l1
1524 with self.assertRaises(TypeError):
1525 f1 > l2
1526
1527 # any superset
1528 self.assertTrue(f3 >= f1)
1529 self.assertTrue(f1 >= f1)
1530 self.assertFalse(f2 >= f1)
1531 self.assertTrue(r3 >= r1)
1532 self.assertTrue(f1 >= r1)
1533 self.assertFalse(f2 >= r1)
1534 self.assertTrue(r3 >= r1)
1535 self.assertTrue(r1 >= r1)
1536 self.assertFalse(r2 >= r1)
1537 with self.assertRaises(TypeError):
1538 f1 >= l3
1539 with self.assertRaises(TypeError):
1540 f1 >=l1
1541 with self.assertRaises(TypeError):
1542 f1 >= l2
1543
1544 # equality
1545 self.assertTrue(f1 == f1)
1546 self.assertTrue(r1 == f1)
1547 self.assertTrue(f1 == r1)
1548 self.assertFalse(f1 == f3)
1549 self.assertFalse(r1 == f3)
1550 self.assertFalse(f1 == r3)
1551 self.assertFalse(f1 == l3)
1552 self.assertFalse(f1 == l1)
1553 self.assertFalse(f1 == l2)
1554
1555 # inequality
1556 self.assertFalse(f1 != f1)
1557 self.assertFalse(r1 != f1)
1558 self.assertFalse(f1 != r1)
1559 self.assertTrue(f1 != f3)
1560 self.assertTrue(r1 != f3)
1561 self.assertTrue(f1 != r3)
1562 self.assertTrue(f1 != l3)
1563 self.assertTrue(f1 != l1)
1564 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001565
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001566 def test_Mapping(self):
1567 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001568 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001569 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001570 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1571 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001572 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001573 def __len__(self):
1574 return 0
1575 def __getitem__(self, i):
1576 raise IndexError
1577 def __iter__(self):
1578 return iter(())
1579 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001580 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001581
1582 def test_MutableMapping(self):
1583 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001584 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001585 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001586 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1587 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001588
Raymond Hettinger9117c752010-08-22 07:44:24 +00001589 def test_MutableMapping_subclass(self):
1590 # Test issue 9214
1591 mymap = UserDict()
1592 mymap['red'] = 5
1593 self.assertIsInstance(mymap.keys(), Set)
1594 self.assertIsInstance(mymap.keys(), KeysView)
1595 self.assertIsInstance(mymap.items(), Set)
1596 self.assertIsInstance(mymap.items(), ItemsView)
1597
1598 mymap = UserDict()
1599 mymap['red'] = 5
1600 z = mymap.keys() | {'orange'}
1601 self.assertIsInstance(z, set)
1602 list(z)
1603 mymap['blue'] = 7 # Shouldn't affect 'z'
1604 self.assertEqual(sorted(z), ['orange', 'red'])
1605
1606 mymap = UserDict()
1607 mymap['red'] = 5
1608 z = mymap.items() | {('orange', 3)}
1609 self.assertIsInstance(z, set)
1610 list(z)
1611 mymap['blue'] = 7 # Shouldn't affect 'z'
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001612 self.assertEqual(z, {('orange', 3), ('red', 5)})
Raymond Hettinger9117c752010-08-22 07:44:24 +00001613
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001614 def test_Sequence(self):
1615 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001616 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001617 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001618 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001619 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001620 self.assertIsInstance(memoryview(b""), Sequence)
1621 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001622 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001623 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1624 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001625
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001626 def test_Sequence_mixins(self):
1627 class SequenceSubclass(Sequence):
1628 def __init__(self, seq=()):
1629 self.seq = seq
1630
1631 def __getitem__(self, index):
1632 return self.seq[index]
1633
1634 def __len__(self):
1635 return len(self.seq)
1636
1637 # Compare Sequence.index() behavior to (list|str).index() behavior
1638 def assert_index_same(seq1, seq2, index_args):
1639 try:
1640 expected = seq1.index(*index_args)
1641 except ValueError:
1642 with self.assertRaises(ValueError):
1643 seq2.index(*index_args)
1644 else:
1645 actual = seq2.index(*index_args)
1646 self.assertEqual(
1647 actual, expected, '%r.index%s' % (seq1, index_args))
1648
1649 for ty in list, str:
1650 nativeseq = ty('abracadabra')
1651 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1652 seqseq = SequenceSubclass(nativeseq)
1653 for letter in set(nativeseq) | {'z'}:
1654 assert_index_same(nativeseq, seqseq, (letter,))
1655 for start in range(-3, len(nativeseq) + 3):
1656 assert_index_same(nativeseq, seqseq, (letter, start))
1657 for stop in range(-3, len(nativeseq) + 3):
1658 assert_index_same(
1659 nativeseq, seqseq, (letter, start, stop))
1660
Guido van Rossumd05eb002007-11-21 22:26:24 +00001661 def test_ByteString(self):
1662 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001663 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001664 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001665 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001666 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001667 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001668 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001669 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001670
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001671 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001672 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001673 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001674 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001675 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001676 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001677 self.assertTrue(issubclass(sample, MutableSequence))
1678 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001679 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1680 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001681
Eli Bendersky0716a572011-03-04 10:38:14 +00001682 def test_MutableSequence_mixins(self):
Mike53f7a7c2017-12-14 14:04:53 +03001683 # Test the mixins of MutableSequence by creating a minimal concrete
Eli Bendersky0716a572011-03-04 10:38:14 +00001684 # class inherited from it.
1685 class MutableSequenceSubclass(MutableSequence):
1686 def __init__(self):
1687 self.lst = []
1688
1689 def __setitem__(self, index, value):
1690 self.lst[index] = value
1691
1692 def __getitem__(self, index):
1693 return self.lst[index]
1694
1695 def __len__(self):
1696 return len(self.lst)
1697
1698 def __delitem__(self, index):
1699 del self.lst[index]
1700
1701 def insert(self, index, value):
1702 self.lst.insert(index, value)
1703
1704 mss = MutableSequenceSubclass()
1705 mss.append(0)
1706 mss.extend((1, 2, 3, 4))
1707 self.assertEqual(len(mss), 5)
1708 self.assertEqual(mss[3], 3)
1709 mss.reverse()
1710 self.assertEqual(mss[3], 1)
1711 mss.pop()
1712 self.assertEqual(len(mss), 4)
1713 mss.remove(3)
1714 self.assertEqual(len(mss), 3)
1715 mss += (10, 20, 30)
1716 self.assertEqual(len(mss), 6)
1717 self.assertEqual(mss[-1], 30)
1718 mss.clear()
1719 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001720
Naris R1b5f9c92018-08-31 02:56:14 +10001721 # issue 34427
1722 # extending self should not cause infinite loop
1723 items = 'ABCD'
1724 mss2 = MutableSequenceSubclass()
1725 mss2.extend(items + items)
1726 mss.clear()
1727 mss.extend(items)
1728 mss.extend(mss)
1729 self.assertEqual(len(mss), len(mss2))
1730 self.assertEqual(list(mss), list(mss2))
1731
1732
Raymond Hettinger499e1932011-02-23 07:56:53 +00001733################################################################################
1734### Counter
1735################################################################################
1736
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001737class CounterSubclassWithSetItem(Counter):
1738 # Test a counter subclass that overrides __setitem__
1739 def __init__(self, *args, **kwds):
1740 self.called = False
1741 Counter.__init__(self, *args, **kwds)
1742 def __setitem__(self, key, value):
1743 self.called = True
1744 Counter.__setitem__(self, key, value)
1745
1746class CounterSubclassWithGet(Counter):
1747 # Test a counter subclass that overrides get()
1748 def __init__(self, *args, **kwds):
1749 self.called = False
1750 Counter.__init__(self, *args, **kwds)
1751 def get(self, key, default):
1752 self.called = True
1753 return Counter.get(self, key, default)
1754
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001755class TestCounter(unittest.TestCase):
1756
1757 def test_basics(self):
1758 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001759 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1760 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001761 self.assertIsInstance(c, dict)
1762 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001763 self.assertTrue(issubclass(Counter, dict))
1764 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001765 self.assertEqual(len(c), 3)
1766 self.assertEqual(sum(c.values()), 6)
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001767 self.assertEqual(list(c.values()), [3, 2, 1])
1768 self.assertEqual(list(c.keys()), ['a', 'b', 'c'])
1769 self.assertEqual(list(c), ['a', 'b', 'c'])
1770 self.assertEqual(list(c.items()),
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001771 [('a', 3), ('b', 2), ('c', 1)])
1772 self.assertEqual(c['b'], 2)
1773 self.assertEqual(c['z'], 0)
1774 self.assertEqual(c.__contains__('c'), True)
1775 self.assertEqual(c.__contains__('z'), False)
1776 self.assertEqual(c.get('b', 10), 2)
1777 self.assertEqual(c.get('z', 10), 10)
1778 self.assertEqual(c, dict(a=3, b=2, c=1))
1779 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1780 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1781 for i in range(5):
1782 self.assertEqual(c.most_common(i),
1783 [('a', 3), ('b', 2), ('c', 1)][:i])
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001784 self.assertEqual(''.join(c.elements()), 'aaabbc')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001785 c['a'] += 1 # increment an existing value
1786 c['b'] -= 2 # sub existing value to zero
1787 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001788 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001789 c['d'] -= 2 # sub from a missing value
1790 c['e'] = -5 # directly assign a missing value
1791 c['f'] += 4 # add to a missing value
1792 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001793 self.assertEqual(''.join(c.elements()), 'aaaaffff')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001794 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001795 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001796 for i in range(3):
1797 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001798 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001799 c.clear()
1800 self.assertEqual(c, {})
1801 self.assertEqual(repr(c), 'Counter()')
1802 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1803 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001804 c.update(dict(a=5, b=3))
1805 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001806 c.update(Counter('a' * 50 + 'b' * 30))
1807 c.update() # test case with no args
1808 c.__init__('a' * 500 + 'b' * 300)
1809 c.__init__('cdc')
1810 c.__init__()
1811 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1812 self.assertEqual(c.setdefault('d', 5), 1)
1813 self.assertEqual(c['d'], 1)
1814 self.assertEqual(c.setdefault('e', 5), 5)
1815 self.assertEqual(c['e'], 5)
1816
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001817 def test_init(self):
1818 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1819 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1820 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1821 self.assertRaises(TypeError, Counter, 42)
1822 self.assertRaises(TypeError, Counter, (), ())
1823 self.assertRaises(TypeError, Counter.__init__)
1824
1825 def test_update(self):
1826 c = Counter()
1827 c.update(self=42)
1828 self.assertEqual(list(c.items()), [('self', 42)])
1829 c = Counter()
1830 c.update(iterable=42)
1831 self.assertEqual(list(c.items()), [('iterable', 42)])
1832 c = Counter()
1833 c.update(iterable=None)
1834 self.assertEqual(list(c.items()), [('iterable', None)])
1835 self.assertRaises(TypeError, Counter().update, 42)
1836 self.assertRaises(TypeError, Counter().update, {}, {})
1837 self.assertRaises(TypeError, Counter.update)
1838
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001839 def test_copying(self):
1840 # Check that counters are copyable, deepcopyable, picklable, and
1841 #have a repr/eval round-trip
1842 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001843 def check(dup):
1844 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1845 self.assertIsNot(dup, words, msg)
1846 self.assertEqual(dup, words)
1847 check(words.copy())
1848 check(copy.copy(words))
1849 check(copy.deepcopy(words))
1850 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1851 with self.subTest(proto=proto):
1852 check(pickle.loads(pickle.dumps(words, proto)))
1853 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001854 update_test = Counter()
1855 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001856 check(update_test)
1857 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001858
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001859 def test_copy_subclass(self):
1860 class MyCounter(Counter):
1861 pass
1862 c = MyCounter('slartibartfast')
1863 d = c.copy()
1864 self.assertEqual(d, c)
1865 self.assertEqual(len(d), len(c))
1866 self.assertEqual(type(d), type(c))
1867
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001868 def test_conversions(self):
1869 # Convert to: set, list, dict
1870 s = 'she sells sea shells by the sea shore'
1871 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1872 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1873 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1874 self.assertEqual(set(Counter(s)), set(s))
1875
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001876 def test_invariant_for_the_in_operator(self):
1877 c = Counter(a=10, b=-2, c=0)
1878 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001879 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001880 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001881
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001882 def test_multiset_operations(self):
1883 # Verify that adding a zero counter will strip zeros and negatives
1884 c = Counter(a=10, b=-2, c=0) + Counter()
1885 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001886
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001887 elements = 'abcd'
1888 for i in range(1000):
1889 # test random pairs of multisets
1890 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001891 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001892 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001893 q.update(h=1, i=-1, j=0)
1894 for counterop, numberop in [
1895 (Counter.__add__, lambda x, y: max(0, x+y)),
1896 (Counter.__sub__, lambda x, y: max(0, x-y)),
1897 (Counter.__or__, lambda x, y: max(0,x,y)),
1898 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001899 ]:
1900 result = counterop(p, q)
1901 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001902 self.assertEqual(numberop(p[x], q[x]), result[x],
1903 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001904 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001905 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001906
1907 elements = 'abcdef'
1908 for i in range(100):
1909 # verify that random multisets with no repeats are exactly like sets
1910 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1911 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1912 for counterop, setop in [
1913 (Counter.__sub__, set.__sub__),
1914 (Counter.__or__, set.__or__),
1915 (Counter.__and__, set.__and__),
1916 ]:
1917 counter_result = counterop(p, q)
1918 set_result = setop(set(p.elements()), set(q.elements()))
1919 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001920
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001921 def test_inplace_operations(self):
1922 elements = 'abcd'
1923 for i in range(1000):
1924 # test random pairs of multisets
1925 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1926 p.update(e=1, f=-1, g=0)
1927 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1928 q.update(h=1, i=-1, j=0)
1929 for inplace_op, regular_op in [
1930 (Counter.__iadd__, Counter.__add__),
1931 (Counter.__isub__, Counter.__sub__),
1932 (Counter.__ior__, Counter.__or__),
1933 (Counter.__iand__, Counter.__and__),
1934 ]:
1935 c = p.copy()
1936 c_id = id(c)
1937 regular_result = regular_op(c, q)
1938 inplace_result = inplace_op(c, q)
1939 self.assertEqual(inplace_result, regular_result)
1940 self.assertEqual(id(inplace_result), c_id)
1941
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001942 def test_subtract(self):
1943 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1944 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1945 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1946 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1947 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1948 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1949 c = Counter('aaabbcd')
1950 c.subtract('aaaabbcce')
1951 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001952
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001953 c = Counter()
1954 c.subtract(self=42)
1955 self.assertEqual(list(c.items()), [('self', -42)])
1956 c = Counter()
1957 c.subtract(iterable=42)
1958 self.assertEqual(list(c.items()), [('iterable', -42)])
1959 self.assertRaises(TypeError, Counter().subtract, 42)
1960 self.assertRaises(TypeError, Counter().subtract, {}, {})
1961 self.assertRaises(TypeError, Counter.subtract)
1962
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001963 def test_unary(self):
1964 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1965 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1966 self.assertEqual(dict(-c), dict(a=5))
1967
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001968 def test_repr_nonsortable(self):
1969 c = Counter(a=2, b=None)
1970 r = repr(c)
1971 self.assertIn("'a': 2", r)
1972 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001973
Raymond Hettinger426e0522011-01-03 02:12:02 +00001974 def test_helper_function(self):
1975 # two paths, one for real dicts and one for other mappings
1976 elems = list('abracadabra')
1977
1978 d = dict()
1979 _count_elements(d, elems)
1980 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1981
1982 m = OrderedDict()
1983 _count_elements(m, elems)
1984 self.assertEqual(m,
1985 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1986
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001987 # test fidelity to the pure python version
1988 c = CounterSubclassWithSetItem('abracadabra')
1989 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001990 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001991 c = CounterSubclassWithGet('abracadabra')
1992 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001993 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001994
Raymond Hettinger499e1932011-02-23 07:56:53 +00001995
1996################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001997### Run tests
1998################################################################################
1999
Guido van Rossumd8faa362007-04-27 19:54:29 +00002000def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00002001 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002002 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00002003 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06002004 TestUserObjects,
2005 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002006 support.run_unittest(*test_classes)
2007 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002008
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002009
Guido van Rossumd8faa362007-04-27 19:54:29 +00002010if __name__ == "__main__":
2011 test_main(verbose=True)