blob: 00b33ce27674b5870cd453bb7d6bec9b3095d279 [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
Raymond Hettinger499b2ee2009-05-27 01:53:46 +00006import keyword
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02007import operator
8import pickle
9from random import choice, randrange
Raymond Hettinger499b2ee2009-05-27 01:53:46 +000010import re
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020011import string
R. David Murray378c0cf2010-02-24 01:46:21 +000012import sys
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020013from test import support
Yury Selivanov75445082015-05-11 22:57:16 -040014import types
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020015import unittest
16
17from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger573b44c2015-05-22 16:56:32 -070018from collections import UserDict, UserString, UserList
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000019from collections import ChainMap
Raymond Hettinger32ea1652015-03-21 01:37:37 -070020from collections import deque
Yury Selivanov22214ab2016-11-16 18:25:04 -050021from collections.abc import Awaitable, Coroutine
22from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator
Guido van Rossum16ca06b2016-04-04 10:59:29 -070023from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
Guido van Rossumf0666942016-08-23 10:47:07 -070024from collections.abc import Sized, Container, Callable, Collection
Raymond Hettinger57d1a882011-02-23 00:46:28 +000025from collections.abc import Set, MutableSet
Raymond Hettinger584e8ae2016-05-05 11:14:06 +030026from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
Raymond Hettinger57d1a882011-02-23 00:46:28 +000027from collections.abc import Sequence, MutableSequence
28from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000029
Raymond Hettinger499e1932011-02-23 07:56:53 +000030
Raymond Hettinger573b44c2015-05-22 16:56:32 -070031class TestUserObjects(unittest.TestCase):
32 def _superset_test(self, a, b):
33 self.assertGreaterEqual(
34 set(dir(a)),
35 set(dir(b)),
36 '{a} should have all the methods of {b}'.format(
37 a=a.__name__,
38 b=b.__name__,
39 ),
40 )
41 def test_str_protocol(self):
42 self._superset_test(UserString, str)
43
44 def test_list_protocol(self):
45 self._superset_test(UserList, list)
46
47 def test_dict_protocol(self):
48 self._superset_test(UserDict, dict)
49
50
Raymond Hettinger499e1932011-02-23 07:56:53 +000051################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000052### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000053################################################################################
54
55class TestChainMap(unittest.TestCase):
56
57 def test_basics(self):
58 c = ChainMap()
59 c['a'] = 1
60 c['b'] = 2
61 d = c.new_child()
62 d['b'] = 20
63 d['c'] = 30
64 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
65 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
66 self.assertEqual(len(d), 3) # check len
67 for key in 'abc': # check contains
68 self.assertIn(key, d)
69 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
70 self.assertEqual(d.get(k, 100), v)
71
72 del d['b'] # unmask a value
73 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
74 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
75 self.assertEqual(len(d), 3) # check len
76 for key in 'abc': # check contains
77 self.assertIn(key, d)
78 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
79 self.assertEqual(d.get(k, 100), v)
80 self.assertIn(repr(d), [ # check repr
81 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
82 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
83 ])
84
85 for e in d.copy(), copy.copy(d): # check shallow copies
86 self.assertEqual(d, e)
87 self.assertEqual(d.maps, e.maps)
88 self.assertIsNot(d, e)
89 self.assertIsNot(d.maps[0], e.maps[0])
90 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
91 self.assertIs(m1, m2)
92
Serhiy Storchakabad12572014-12-15 14:03:42 +020093 # check deep copies
94 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
95 e = pickle.loads(pickle.dumps(d, proto))
96 self.assertEqual(d, e)
97 self.assertEqual(d.maps, e.maps)
98 self.assertIsNot(d, e)
99 for m1, m2 in zip(d.maps, e.maps):
100 self.assertIsNot(m1, m2, e)
101 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +0000102 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200103 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000104 self.assertEqual(d, e)
105 self.assertEqual(d.maps, e.maps)
106 self.assertIsNot(d, e)
107 for m1, m2 in zip(d.maps, e.maps):
108 self.assertIsNot(m1, m2, e)
109
Raymond Hettingerd0321312011-02-26 06:53:58 +0000110 f = d.new_child()
111 f['b'] = 5
112 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
113 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
114 self.assertEqual(f['b'], 5) # find first in chain
115 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000116
Miss Islington (bot)7121a6e2019-02-21 09:47:46 -0800117 def test_ordering(self):
118 # Combined order matches a series of dict updates from last to first.
119 # This test relies on the ordering of the underlying dicts.
120
121 baseline = {'music': 'bach', 'art': 'rembrandt'}
122 adjustments = {'art': 'van gogh', 'opera': 'carmen'}
123
124 cm = ChainMap(adjustments, baseline)
125
126 combined = baseline.copy()
127 combined.update(adjustments)
128
129 self.assertEqual(list(combined.items()), list(cm.items()))
130
Martin Pantereb995702016-07-28 01:11:04 +0000131 def test_constructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000132 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000133 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
134
Raymond Hettingerd0321312011-02-26 06:53:58 +0000135 def test_bool(self):
136 self.assertFalse(ChainMap())
137 self.assertFalse(ChainMap({}, {}))
138 self.assertTrue(ChainMap({1:2}, {}))
139 self.assertTrue(ChainMap({}, {1:2}))
140
Raymond Hettinger499e1932011-02-23 07:56:53 +0000141 def test_missing(self):
142 class DefaultChainMap(ChainMap):
143 def __missing__(self, key):
144 return 999
145 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
146 for k, v in dict(a=1, b=2, c=30, d=999).items():
147 self.assertEqual(d[k], v) # check __getitem__ w/missing
148 for k, v in dict(a=1, b=2, c=30, d=77).items():
149 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
150 for k, v in dict(a=True, b=True, c=True, d=False).items():
151 self.assertEqual(k in d, v) # check __contains__ w/missing
152 self.assertEqual(d.pop('a', 1001), 1, d)
153 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
154 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
155 with self.assertRaises(KeyError):
156 d.popitem()
157
Miss Islington (bot)170b3f72018-02-11 01:09:52 -0800158 def test_order_preservation(self):
159 d = ChainMap(
160 OrderedDict(j=0, h=88888),
161 OrderedDict(),
162 OrderedDict(i=9999, d=4444, c=3333),
163 OrderedDict(f=666, b=222, g=777, c=333, h=888),
164 OrderedDict(),
165 OrderedDict(e=55, b=22),
166 OrderedDict(a=1, b=2, c=3, d=4, e=5),
167 OrderedDict(),
168 )
169 self.assertEqual(''.join(d), 'abcdefghij')
170 self.assertEqual(list(d.items()),
171 [('a', 1), ('b', 222), ('c', 3333), ('d', 4444),
172 ('e', 55), ('f', 666), ('g', 777), ('h', 88888),
173 ('i', 9999), ('j', 0)])
174
Raymond Hettinger499e1932011-02-23 07:56:53 +0000175 def test_dict_coercion(self):
176 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
177 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
178 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
179
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000180 def test_new_child(self):
181 'Tests for changes for issue #16613.'
182 c = ChainMap()
183 c['a'] = 1
184 c['b'] = 2
185 m = {'b':20, 'c': 30}
186 d = c.new_child(m)
187 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
188 self.assertIs(m, d.maps[0])
189
190 # Use a different map than a dict
191 class lowerdict(dict):
192 def __getitem__(self, key):
193 if isinstance(key, str):
194 key = key.lower()
195 return dict.__getitem__(self, key)
196 def __contains__(self, key):
197 if isinstance(key, str):
198 key = key.lower()
199 return dict.__contains__(self, key)
200
201 c = ChainMap()
202 c['a'] = 1
203 c['b'] = 2
204 m = lowerdict(b=20, c=30)
205 d = c.new_child(m)
206 self.assertIs(m, d.maps[0])
207 for key in 'abc': # check contains
208 self.assertIn(key, d)
209 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
210 self.assertEqual(d.get(k, 100), v)
211
Raymond Hettinger499e1932011-02-23 07:56:53 +0000212
213################################################################################
214### Named Tuples
215################################################################################
216
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000217TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000218
219class TestNamedTuple(unittest.TestCase):
220
221 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000222 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000223 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000224 self.assertEqual(Point.__slots__, ())
225 self.assertEqual(Point.__module__, __name__)
226 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000227 self.assertEqual(Point._fields, ('x', 'y'))
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000228
229 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
230 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
231 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
232
233 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
234 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
235 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000236 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000237 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
238
239 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000240 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000241
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000242 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000243 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000244 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000245 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000246
Christian Heimesfaf2f632008-01-06 16:59:19 +0000247 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
248 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
249
Raymond Hettinger39482072018-01-10 21:45:19 -0800250 def test_defaults(self):
251 Point = namedtuple('Point', 'x y', defaults=(10, 20)) # 2 defaults
Miss Islington (bot)bedfbc72019-03-18 00:48:02 -0700252 self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
Raymond Hettinger39482072018-01-10 21:45:19 -0800253 self.assertEqual(Point(1, 2), (1, 2))
254 self.assertEqual(Point(1), (1, 20))
255 self.assertEqual(Point(), (10, 20))
256
257 Point = namedtuple('Point', 'x y', defaults=(20,)) # 1 default
Miss Islington (bot)bedfbc72019-03-18 00:48:02 -0700258 self.assertEqual(Point._field_defaults, {'y': 20})
Raymond Hettinger39482072018-01-10 21:45:19 -0800259 self.assertEqual(Point(1, 2), (1, 2))
260 self.assertEqual(Point(1), (1, 20))
261
262 Point = namedtuple('Point', 'x y', defaults=()) # 0 defaults
Miss Islington (bot)bedfbc72019-03-18 00:48:02 -0700263 self.assertEqual(Point._field_defaults, {})
Raymond Hettinger39482072018-01-10 21:45:19 -0800264 self.assertEqual(Point(1, 2), (1, 2))
265 with self.assertRaises(TypeError):
266 Point(1)
267
268 with self.assertRaises(TypeError): # catch too few args
269 Point()
270 with self.assertRaises(TypeError): # catch too many args
271 Point(1, 2, 3)
272 with self.assertRaises(TypeError): # too many defaults
273 Point = namedtuple('Point', 'x y', defaults=(10, 20, 30))
274 with self.assertRaises(TypeError): # non-iterable defaults
275 Point = namedtuple('Point', 'x y', defaults=10)
276 with self.assertRaises(TypeError): # another non-iterable default
277 Point = namedtuple('Point', 'x y', defaults=False)
278
279 Point = namedtuple('Point', 'x y', defaults=None) # default is None
Miss Islington (bot)bedfbc72019-03-18 00:48:02 -0700280 self.assertEqual(Point._field_defaults, {})
Raymond Hettinger39482072018-01-10 21:45:19 -0800281 self.assertIsNone(Point.__new__.__defaults__, None)
282 self.assertEqual(Point(10, 20), (10, 20))
283 with self.assertRaises(TypeError): # catch too few args
284 Point(10)
285
286 Point = namedtuple('Point', 'x y', defaults=[10, 20]) # allow non-tuple iterable
Miss Islington (bot)bedfbc72019-03-18 00:48:02 -0700287 self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
Raymond Hettinger39482072018-01-10 21:45:19 -0800288 self.assertEqual(Point.__new__.__defaults__, (10, 20))
289 self.assertEqual(Point(1, 2), (1, 2))
290 self.assertEqual(Point(1), (1, 20))
291 self.assertEqual(Point(), (10, 20))
292
293 Point = namedtuple('Point', 'x y', defaults=iter([10, 20])) # allow plain iterator
Miss Islington (bot)bedfbc72019-03-18 00:48:02 -0700294 self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
Raymond Hettinger39482072018-01-10 21:45:19 -0800295 self.assertEqual(Point.__new__.__defaults__, (10, 20))
296 self.assertEqual(Point(1, 2), (1, 2))
297 self.assertEqual(Point(1), (1, 20))
298 self.assertEqual(Point(), (10, 20))
299
300
R. David Murray378c0cf2010-02-24 01:46:21 +0000301 @unittest.skipIf(sys.flags.optimize >= 2,
302 "Docstrings are omitted with -O2 and above")
303 def test_factory_doc_attr(self):
304 Point = namedtuple('Point', 'x y')
305 self.assertEqual(Point.__doc__, 'Point(x, y)')
306
Raymond Hettingereac503a2015-05-13 01:09:59 -0700307 @unittest.skipIf(sys.flags.optimize >= 2,
308 "Docstrings are omitted with -O2 and above")
309 def test_doc_writable(self):
310 Point = namedtuple('Point', 'x y')
311 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
312 Point.x.__doc__ = 'docstring for Point.x'
313 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
314
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000315 def test_name_fixer(self):
316 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000317 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
318 [('abc', 'class'), ('abc', '_1')], # field has keyword
319 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
320 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
321 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
322 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000323 ]:
324 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
325
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700326 def test_module_parameter(self):
327 NT = namedtuple('NT', ['x', 'y'], module=collections)
328 self.assertEqual(NT.__module__, collections)
329
Guido van Rossumd8faa362007-04-27 19:54:29 +0000330 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000331 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000332 p = Point(11, 22)
333 self.assertEqual(p, Point(x=11, y=22))
334 self.assertEqual(p, Point(11, y=22))
335 self.assertEqual(p, Point(y=22, x=11))
336 self.assertEqual(p, Point(*(11, 22)))
337 self.assertEqual(p, Point(**dict(x=11, y=22)))
338 self.assertRaises(TypeError, Point, 1) # too few args
339 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
340 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
341 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
342 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000343 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000344 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000345 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
346 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700347 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000348
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000349 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000350 p._replace(x=1, error=2)
351 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000352 pass
353 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000354 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000355
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000356 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000357 Point = namedtuple('Point', 'x, y')
358 p = Point(x=11, y=22)
359 self.assertEqual(repr(p), 'Point(x=11, y=22)')
360
361 # verify that fieldspec can be a non-string sequence
362 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000363 p = Point(x=11, y=22)
364 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000365
366 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000367 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000368 p = Point(11, 22)
369
Ezio Melottie9615932010-01-24 19:26:24 +0000370 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000371 self.assertEqual(p, (11, 22)) # matches a real tuple
372 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
373 self.assertEqual(list(p), [11, 22]) # coercable to a list
374 self.assertEqual(max(p), 22) # iterable
375 self.assertEqual(max(*p), 22) # star-able
376 x, y = p
377 self.assertEqual(p, (x, y)) # unpacks like a tuple
378 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
379 self.assertRaises(IndexError, p.__getitem__, 3)
380
381 self.assertEqual(p.x, x)
382 self.assertEqual(p.y, y)
383 self.assertRaises(AttributeError, eval, 'p.z', locals())
384
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000385 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000386 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000387 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000388 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000389 self.assertEqual(repr(Zero()), 'Zero()')
390 self.assertEqual(Zero()._asdict(), {})
391 self.assertEqual(Zero()._fields, ())
392
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000393 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000394 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000395 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000396 self.assertEqual(Dot(1).d, 1)
397 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
398 self.assertEqual(Dot(1)._asdict(), {'d':1})
399 self.assertEqual(Dot(1)._replace(d=999), (999,))
400 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000401
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200402 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200403 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000404 for j in range(10)]) for i in range(n)))
405 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000406 Big = namedtuple('Big', names)
407 b = Big(*range(n))
408 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000409 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000410 for pos, name in enumerate(names):
411 self.assertEqual(getattr(b, name), pos)
412 repr(b) # make sure repr() doesn't blow-up
413 d = b._asdict()
414 d_expected = dict(zip(names, range(n)))
415 self.assertEqual(d, d_expected)
416 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
417 b2_expected = list(range(n))
418 b2_expected[1] = 999
419 b2_expected[-5] = 42
420 self.assertEqual(b2, tuple(b2_expected))
421 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000422
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000423 def test_pickle(self):
424 p = TestNT(x=10, y=20, z=30)
425 for module in (pickle,):
426 loads = getattr(module, 'loads')
427 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500428 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000429 q = loads(dumps(p, protocol))
430 self.assertEqual(p, q)
431 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700432 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000433
434 def test_copy(self):
435 p = TestNT(x=10, y=20, z=30)
436 for copier in copy.copy, copy.deepcopy:
437 q = copier(p)
438 self.assertEqual(p, q)
439 self.assertEqual(p._fields, q._fields)
440
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000441 def test_name_conflicts(self):
442 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
443 # failed when used as field names. Test to make sure these now work.
444 T = namedtuple('T', 'itemgetter property self cls tuple')
445 t = T(1, 2, 3, 4, 5)
446 self.assertEqual(t, (1,2,3,4,5))
447 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
448 self.assertEqual(newt, (10,20,30,40,50))
449
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700450 # Broader test of all interesting names taken from the code, old
451 # template, and an example
452 words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create',
453 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper',
454 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note',
455 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError',
456 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add',
457 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments',
458 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot',
459 'class_namespace', 'classmethod', 'cls', 'collections', 'convert',
460 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict',
461 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect',
462 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f',
463 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame',
464 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater',
465 'has', 'help', 'identifiers', 'index', 'indexable', 'instance',
466 'instantiate', 'interning', 'introspection', 'isidentifier',
467 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords',
468 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata',
469 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named',
470 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new',
471 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option',
472 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional',
473 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr',
474 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen',
475 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start',
476 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys',
477 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new',
478 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use',
479 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where',
480 'which', 'work', 'x', 'y', 'z', 'zip'}
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000481 T = namedtuple('T', words)
482 # test __new__
483 values = tuple(range(len(words)))
484 t = T(*values)
485 self.assertEqual(t, values)
486 t = T(**dict(zip(T._fields, values)))
487 self.assertEqual(t, values)
488 # test _make
489 t = T._make(values)
490 self.assertEqual(t, values)
491 # exercise __repr__
492 repr(t)
493 # test _asdict
494 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
495 # test _replace
496 t = T._make(values)
497 newvalues = tuple(v*10 for v in values)
498 newt = t._replace(**dict(zip(T._fields, newvalues)))
499 self.assertEqual(newt, newvalues)
500 # test _fields
501 self.assertEqual(T._fields, tuple(words))
502 # test __getnewargs__
503 self.assertEqual(t.__getnewargs__(), values)
504
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000505 def test_repr(self):
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700506 A = namedtuple('A', 'x')
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000507 self.assertEqual(repr(A(1)), 'A(x=1)')
508 # repr should show the name of the subclass
509 class B(A):
510 pass
511 self.assertEqual(repr(B(1)), 'B(x=1)')
512
Raymond Hettinger6538b432016-08-16 10:55:43 -0700513 def test_keyword_only_arguments(self):
514 # See issue 25628
Raymond Hettinger6538b432016-08-16 10:55:43 -0700515 with self.assertRaises(TypeError):
516 NT = namedtuple('NT', ['x', 'y'], True)
517
518 NT = namedtuple('NT', ['abc', 'def'], rename=True)
519 self.assertEqual(NT._fields, ('abc', '_1'))
520 with self.assertRaises(TypeError):
521 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000522
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700523 def test_namedtuple_subclass_issue_24931(self):
524 class Point(namedtuple('_Point', ['x', 'y'])):
525 pass
526
527 a = Point(3, 4)
528 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
529
530 a.w = 5
531 self.assertEqual(a.__dict__, {'w': 5})
532
533
Raymond Hettinger499e1932011-02-23 07:56:53 +0000534################################################################################
535### Abstract Base Classes
536################################################################################
537
Raymond Hettingerae650182009-01-28 23:33:59 +0000538class ABCTestCase(unittest.TestCase):
539
540 def validate_abstract_methods(self, abc, *names):
541 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
542
543 # everything should work will all required methods are present
544 C = type('C', (abc,), methodstubs)
545 C()
546
547 # instantiation should fail if a required method is missing
548 for name in names:
549 stubs = methodstubs.copy()
550 del stubs[name]
551 C = type('C', (abc,), stubs)
552 self.assertRaises(TypeError, C, name)
553
Florent Xiclunace153f62010-03-08 15:34:35 +0000554 def validate_isinstance(self, abc, name):
555 stub = lambda s, *args: 0
556
557 C = type('C', (object,), {'__hash__': None})
558 setattr(C, name, stub)
559 self.assertIsInstance(C(), abc)
560 self.assertTrue(issubclass(C, abc))
561
562 C = type('C', (object,), {'__hash__': None})
563 self.assertNotIsInstance(C(), abc)
564 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000565
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000566 def validate_comparison(self, instance):
567 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
568 operators = {}
569 for op in ops:
570 name = '__' + op + '__'
571 operators[name] = getattr(operator, name)
572
573 class Other:
574 def __init__(self):
575 self.right_side = False
576 def __eq__(self, other):
577 self.right_side = True
578 return True
579 __lt__ = __eq__
580 __gt__ = __eq__
581 __le__ = __eq__
582 __ge__ = __eq__
583 __ne__ = __eq__
584 __ror__ = __eq__
585 __rand__ = __eq__
586 __rxor__ = __eq__
587 __rsub__ = __eq__
588
589 for name, op in operators.items():
590 if not hasattr(instance, name):
591 continue
592 other = Other()
593 op(instance, other)
594 self.assertTrue(other.right_side,'Right side not called for %s.%s'
595 % (type(instance), name))
596
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700597def _test_gen():
598 yield
599
Raymond Hettingerae650182009-01-28 23:33:59 +0000600class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000601
Yury Selivanov75445082015-05-11 22:57:16 -0400602 def test_Awaitable(self):
603 def gen():
604 yield
605
606 @types.coroutine
607 def coro():
608 yield
609
610 async def new_coro():
611 pass
612
613 class Bar:
614 def __await__(self):
615 yield
616
617 class MinimalCoro(Coroutine):
618 def send(self, value):
619 return value
620 def throw(self, typ, val=None, tb=None):
621 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400622 def __await__(self):
623 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400624
625 non_samples = [None, int(), gen(), object()]
626 for x in non_samples:
627 self.assertNotIsInstance(x, Awaitable)
628 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
629
630 samples = [Bar(), MinimalCoro()]
631 for x in samples:
632 self.assertIsInstance(x, Awaitable)
633 self.assertTrue(issubclass(type(x), Awaitable))
634
635 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400636 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
637 # flag don't have '__await__' method, hence can't be instances
638 # of Awaitable. Use inspect.isawaitable to detect them.
639 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400640
641 c = new_coro()
642 self.assertIsInstance(c, Awaitable)
Mike53f7a7c2017-12-14 14:04:53 +0300643 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400644
Yury Selivanov56fc6142015-05-29 09:01:29 -0400645 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400646 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400647 self.assertTrue(isinstance(CoroLike(), Awaitable))
648 self.assertTrue(issubclass(CoroLike, Awaitable))
649 CoroLike = None
650 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400651
Yury Selivanov75445082015-05-11 22:57:16 -0400652 def test_Coroutine(self):
653 def gen():
654 yield
655
656 @types.coroutine
657 def coro():
658 yield
659
660 async def new_coro():
661 pass
662
663 class Bar:
664 def __await__(self):
665 yield
666
667 class MinimalCoro(Coroutine):
668 def send(self, value):
669 return value
670 def throw(self, typ, val=None, tb=None):
671 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400672 def __await__(self):
673 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400674
675 non_samples = [None, int(), gen(), object(), Bar()]
676 for x in non_samples:
677 self.assertNotIsInstance(x, Coroutine)
678 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
679
680 samples = [MinimalCoro()]
681 for x in samples:
682 self.assertIsInstance(x, Awaitable)
683 self.assertTrue(issubclass(type(x), Awaitable))
684
685 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400686 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
687 # flag don't have '__await__' method, hence can't be instances
688 # of Coroutine. Use inspect.isawaitable to detect them.
689 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400690
691 c = new_coro()
692 self.assertIsInstance(c, Coroutine)
Mike53f7a7c2017-12-14 14:04:53 +0300693 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400694
Yury Selivanov56fc6142015-05-29 09:01:29 -0400695 class CoroLike:
696 def send(self, value):
697 pass
698 def throw(self, typ, val=None, tb=None):
699 pass
700 def close(self):
701 pass
702 def __await__(self):
703 pass
704 self.assertTrue(isinstance(CoroLike(), Coroutine))
705 self.assertTrue(issubclass(CoroLike, Coroutine))
706
707 class CoroLike:
708 def send(self, value):
709 pass
710 def close(self):
711 pass
712 def __await__(self):
713 pass
714 self.assertFalse(isinstance(CoroLike(), Coroutine))
715 self.assertFalse(issubclass(CoroLike, Coroutine))
716
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000717 def test_Hashable(self):
718 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000719 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000720 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000721 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000722 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000723 # Check some hashables
724 samples = [None,
725 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000726 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000727 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000728 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000729 ]
730 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000731 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000732 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000733 self.assertRaises(TypeError, Hashable)
734 # Check direct subclassing
735 class H(Hashable):
736 def __hash__(self):
737 return super().__hash__()
738 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000739 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000740 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000741 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000742
Yury Selivanove0104ae2015-05-14 12:19:16 -0400743 def test_AsyncIterable(self):
744 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400745 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400746 return self
747 self.assertTrue(isinstance(AI(), AsyncIterable))
748 self.assertTrue(issubclass(AI, AsyncIterable))
749 # Check some non-iterables
750 non_samples = [None, object, []]
751 for x in non_samples:
752 self.assertNotIsInstance(x, AsyncIterable)
753 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
754 self.validate_abstract_methods(AsyncIterable, '__aiter__')
755 self.validate_isinstance(AsyncIterable, '__aiter__')
756
757 def test_AsyncIterator(self):
758 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400759 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400760 return self
761 async def __anext__(self):
762 raise StopAsyncIteration
763 self.assertTrue(isinstance(AI(), AsyncIterator))
764 self.assertTrue(issubclass(AI, AsyncIterator))
765 non_samples = [None, object, []]
766 # Check some non-iterables
767 for x in non_samples:
768 self.assertNotIsInstance(x, AsyncIterator)
769 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
770 # Similarly to regular iterators (see issue 10565)
771 class AnextOnly:
772 async def __anext__(self):
773 raise StopAsyncIteration
774 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
775 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
776
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000777 def test_Iterable(self):
778 # Check some non-iterables
779 non_samples = [None, 42, 3.14, 1j]
780 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000781 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000782 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000783 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000784 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000785 tuple(), list(), set(), frozenset(), dict(),
786 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700787 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000788 (x for x in []),
789 ]
790 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000791 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000792 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000793 # Check direct subclassing
794 class I(Iterable):
795 def __iter__(self):
796 return super().__iter__()
797 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000798 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000799 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000800 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700801 # Check None blocking
802 class It:
803 def __iter__(self): return iter([])
804 class ItBlocked(It):
805 __iter__ = None
806 self.assertTrue(issubclass(It, Iterable))
807 self.assertTrue(isinstance(It(), Iterable))
808 self.assertFalse(issubclass(ItBlocked, Iterable))
809 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000810
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700811 def test_Reversible(self):
812 # Check some non-reversibles
813 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()]
814 for x in non_samples:
815 self.assertNotIsInstance(x, Reversible)
816 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700817 # Check some non-reversible iterables
818 non_reversibles = [dict().keys(), dict().items(), dict().values(),
819 Counter(), Counter().keys(), Counter().items(),
820 Counter().values(), _test_gen(),
821 (x for x in []), iter([]), reversed([])]
822 for x in non_reversibles:
823 self.assertNotIsInstance(x, Reversible)
824 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
825 # Check some reversible iterables
826 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
827 OrderedDict().keys(), OrderedDict().items(),
828 OrderedDict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700829 for x in samples:
830 self.assertIsInstance(x, Reversible)
831 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
832 # Check also Mapping, MutableMapping, and Sequence
833 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
834 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
835 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
836 # Check direct subclassing
837 class R(Reversible):
838 def __iter__(self):
839 return iter(list())
840 def __reversed__(self):
841 return iter(list())
842 self.assertEqual(list(reversed(R())), [])
843 self.assertFalse(issubclass(float, R))
844 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700845 # Check reversible non-iterable (which is not Reversible)
846 class RevNoIter:
847 def __reversed__(self): return reversed([])
848 class RevPlusIter(RevNoIter):
849 def __iter__(self): return iter([])
850 self.assertFalse(issubclass(RevNoIter, Reversible))
851 self.assertFalse(isinstance(RevNoIter(), Reversible))
852 self.assertTrue(issubclass(RevPlusIter, Reversible))
853 self.assertTrue(isinstance(RevPlusIter(), Reversible))
854 # Check None blocking
855 class Rev:
856 def __iter__(self): return iter([])
857 def __reversed__(self): return reversed([])
858 class RevItBlocked(Rev):
859 __iter__ = None
860 class RevRevBlocked(Rev):
861 __reversed__ = None
862 self.assertTrue(issubclass(Rev, Reversible))
863 self.assertTrue(isinstance(Rev(), Reversible))
864 self.assertFalse(issubclass(RevItBlocked, Reversible))
865 self.assertFalse(isinstance(RevItBlocked(), Reversible))
866 self.assertFalse(issubclass(RevRevBlocked, Reversible))
867 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700868
Guido van Rossumf0666942016-08-23 10:47:07 -0700869 def test_Collection(self):
870 # Check some non-collections
871 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
872 for x in non_collections:
873 self.assertNotIsInstance(x, Collection)
874 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
875 # Check some non-collection iterables
876 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800877 (x for x in [])]
Guido van Rossumf0666942016-08-23 10:47:07 -0700878 for x in non_col_iterables:
879 self.assertNotIsInstance(x, Collection)
880 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
881 # Check some collections
882 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800883 list(), dict().keys(), dict().items(), dict().values()]
Guido van Rossumf0666942016-08-23 10:47:07 -0700884 for x in samples:
885 self.assertIsInstance(x, Collection)
886 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
887 # Check also Mapping, MutableMapping, etc.
888 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
889 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
890 self.assertTrue(issubclass(MutableMapping, Collection),
891 repr(MutableMapping))
892 self.assertTrue(issubclass(Set, Collection), repr(Set))
893 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
894 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
895 # Check direct subclassing
896 class Col(Collection):
897 def __iter__(self):
898 return iter(list())
899 def __len__(self):
900 return 0
901 def __contains__(self, item):
902 return False
903 class DerCol(Col): pass
904 self.assertEqual(list(iter(Col())), [])
905 self.assertFalse(issubclass(list, Col))
906 self.assertFalse(issubclass(set, Col))
907 self.assertFalse(issubclass(float, Col))
908 self.assertEqual(list(iter(DerCol())), [])
909 self.assertFalse(issubclass(list, DerCol))
910 self.assertFalse(issubclass(set, DerCol))
911 self.assertFalse(issubclass(float, DerCol))
912 self.validate_abstract_methods(Collection, '__len__', '__iter__',
913 '__contains__')
914 # Check sized container non-iterable (which is not Collection) etc.
915 class ColNoIter:
916 def __len__(self): return 0
917 def __contains__(self, item): return False
918 class ColNoSize:
919 def __iter__(self): return iter([])
920 def __contains__(self, item): return False
921 class ColNoCont:
922 def __iter__(self): return iter([])
923 def __len__(self): return 0
924 self.assertFalse(issubclass(ColNoIter, Collection))
925 self.assertFalse(isinstance(ColNoIter(), Collection))
926 self.assertFalse(issubclass(ColNoSize, Collection))
927 self.assertFalse(isinstance(ColNoSize(), Collection))
928 self.assertFalse(issubclass(ColNoCont, Collection))
929 self.assertFalse(isinstance(ColNoCont(), Collection))
930 # Check None blocking
931 class SizeBlock:
932 def __iter__(self): return iter([])
933 def __contains__(self): return False
934 __len__ = None
935 class IterBlock:
936 def __len__(self): return 0
937 def __contains__(self): return True
938 __iter__ = None
939 self.assertFalse(issubclass(SizeBlock, Collection))
940 self.assertFalse(isinstance(SizeBlock(), Collection))
941 self.assertFalse(issubclass(IterBlock, Collection))
942 self.assertFalse(isinstance(IterBlock(), Collection))
943 # Check None blocking in subclass
944 class ColImpl:
945 def __iter__(self):
946 return iter(list())
947 def __len__(self):
948 return 0
949 def __contains__(self, item):
950 return False
951 class NonCol(ColImpl):
952 __contains__ = None
953 self.assertFalse(issubclass(NonCol, Collection))
954 self.assertFalse(isinstance(NonCol(), Collection))
955
956
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000957 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000958 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000959 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000960 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000961 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000962 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000963 iter(tuple()), iter(list()), iter(dict()),
964 iter(set()), iter(frozenset()),
965 iter(dict().keys()), iter(dict().items()),
966 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700967 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000968 (x for x in []),
969 ]
970 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000971 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000972 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000973 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
974
975 # Issue 10565
976 class NextOnly:
977 def __next__(self):
978 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800979 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000980 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000981
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400982 def test_Generator(self):
983 class NonGen1:
984 def __iter__(self): return self
985 def __next__(self): return None
986 def close(self): pass
987 def throw(self, typ, val=None, tb=None): pass
988
989 class NonGen2:
990 def __iter__(self): return self
991 def __next__(self): return None
992 def close(self): pass
993 def send(self, value): return value
994
995 class NonGen3:
996 def close(self): pass
997 def send(self, value): return value
998 def throw(self, typ, val=None, tb=None): pass
999
1000 non_samples = [
1001 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1002 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
1003 for x in non_samples:
1004 self.assertNotIsInstance(x, Generator)
1005 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
1006
1007 class Gen:
1008 def __iter__(self): return self
1009 def __next__(self): return None
1010 def close(self): pass
1011 def send(self, value): return value
1012 def throw(self, typ, val=None, tb=None): pass
1013
1014 class MinimalGen(Generator):
1015 def send(self, value):
1016 return value
1017 def throw(self, typ, val=None, tb=None):
1018 super().throw(typ, val, tb)
1019
1020 def gen():
1021 yield 1
1022
1023 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
1024 for x in samples:
1025 self.assertIsInstance(x, Iterator)
1026 self.assertIsInstance(x, Generator)
1027 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
1028 self.validate_abstract_methods(Generator, 'send', 'throw')
1029
1030 # mixin tests
1031 mgen = MinimalGen()
1032 self.assertIs(mgen, iter(mgen))
1033 self.assertIs(mgen.send(None), next(mgen))
1034 self.assertEqual(2, mgen.send(2))
1035 self.assertIsNone(mgen.close())
1036 self.assertRaises(ValueError, mgen.throw, ValueError)
1037 self.assertRaisesRegex(ValueError, "^huhu$",
1038 mgen.throw, ValueError, ValueError("huhu"))
1039 self.assertRaises(StopIteration, mgen.throw, StopIteration())
1040
1041 class FailOnClose(Generator):
1042 def send(self, value): return value
1043 def throw(self, *args): raise ValueError
1044
1045 self.assertRaises(ValueError, FailOnClose().close)
1046
1047 class IgnoreGeneratorExit(Generator):
1048 def send(self, value): return value
1049 def throw(self, *args): pass
1050
1051 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
1052
Yury Selivanov22214ab2016-11-16 18:25:04 -05001053 def test_AsyncGenerator(self):
1054 class NonAGen1:
1055 def __aiter__(self): return self
1056 def __anext__(self): return None
1057 def aclose(self): pass
1058 def athrow(self, typ, val=None, tb=None): pass
1059
1060 class NonAGen2:
1061 def __aiter__(self): return self
1062 def __anext__(self): return None
1063 def aclose(self): pass
1064 def asend(self, value): return value
1065
1066 class NonAGen3:
1067 def aclose(self): pass
1068 def asend(self, value): return value
1069 def athrow(self, typ, val=None, tb=None): pass
1070
1071 non_samples = [
1072 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1073 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
1074 for x in non_samples:
1075 self.assertNotIsInstance(x, AsyncGenerator)
1076 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
1077
1078 class Gen:
1079 def __aiter__(self): return self
1080 async def __anext__(self): return None
1081 async def aclose(self): pass
1082 async def asend(self, value): return value
1083 async def athrow(self, typ, val=None, tb=None): pass
1084
1085 class MinimalAGen(AsyncGenerator):
1086 async def asend(self, value):
1087 return value
1088 async def athrow(self, typ, val=None, tb=None):
1089 await super().athrow(typ, val, tb)
1090
1091 async def gen():
1092 yield 1
1093
1094 samples = [gen(), Gen(), MinimalAGen()]
1095 for x in samples:
1096 self.assertIsInstance(x, AsyncIterator)
1097 self.assertIsInstance(x, AsyncGenerator)
1098 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1099 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1100
1101 def run_async(coro):
1102 result = None
1103 while True:
1104 try:
1105 coro.send(None)
1106 except StopIteration as ex:
1107 result = ex.args[0] if ex.args else None
1108 break
1109 return result
1110
1111 # mixin tests
1112 mgen = MinimalAGen()
1113 self.assertIs(mgen, mgen.__aiter__())
1114 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1115 self.assertEqual(2, run_async(mgen.asend(2)))
1116 self.assertIsNone(run_async(mgen.aclose()))
1117 with self.assertRaises(ValueError):
1118 run_async(mgen.athrow(ValueError))
1119
1120 class FailOnClose(AsyncGenerator):
1121 async def asend(self, value): return value
1122 async def athrow(self, *args): raise ValueError
1123
1124 with self.assertRaises(ValueError):
1125 run_async(FailOnClose().aclose())
1126
1127 class IgnoreGeneratorExit(AsyncGenerator):
1128 async def asend(self, value): return value
1129 async def athrow(self, *args): pass
1130
1131 with self.assertRaises(RuntimeError):
1132 run_async(IgnoreGeneratorExit().aclose())
1133
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001134 def test_Sized(self):
1135 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001136 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001137 (x for x in []),
1138 ]
1139 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001140 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001141 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001142 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001143 tuple(), list(), set(), frozenset(), dict(),
1144 dict().keys(), dict().items(), dict().values(),
1145 ]
1146 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001147 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001148 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001149 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001150 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001151
1152 def test_Container(self):
1153 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001154 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001155 (x for x in []),
1156 ]
1157 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001158 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001159 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001160 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001161 tuple(), list(), set(), frozenset(), dict(),
1162 dict().keys(), dict().items(),
1163 ]
1164 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001165 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001166 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001167 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001168 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001169
1170 def test_Callable(self):
1171 non_samples = [None, 42, 3.14, 1j,
1172 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001173 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001174 (x for x in []),
1175 ]
1176 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001177 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001178 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001179 samples = [lambda: None,
1180 type, int, object,
1181 len,
1182 list.append, [].append,
1183 ]
1184 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001185 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001186 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001187 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001188 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001189
1190 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001191 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001192 class C(B):
1193 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001194 self.assertTrue(issubclass(C, B))
1195 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001196
1197 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001198 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001199 class C:
1200 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001201 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001202 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001203 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001204
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001205class WithSet(MutableSet):
1206
1207 def __init__(self, it=()):
1208 self.data = set(it)
1209
1210 def __len__(self):
1211 return len(self.data)
1212
1213 def __iter__(self):
1214 return iter(self.data)
1215
1216 def __contains__(self, item):
1217 return item in self.data
1218
1219 def add(self, item):
1220 self.data.add(item)
1221
1222 def discard(self, item):
1223 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001224
Raymond Hettingerae650182009-01-28 23:33:59 +00001225class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001226
1227 # XXX For now, we only test some virtual inheritance properties.
1228 # We should also test the proper behavior of the collection ABCs
1229 # as real base classes or mix-in classes.
1230
1231 def test_Set(self):
1232 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001233 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001234 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001235 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001236 class MySet(Set):
1237 def __contains__(self, x):
1238 return False
1239 def __len__(self):
1240 return 0
1241 def __iter__(self):
1242 return iter([])
1243 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001244
Benjamin Peterson41181742008-07-02 20:22:54 +00001245 def test_hash_Set(self):
1246 class OneTwoThreeSet(Set):
1247 def __init__(self):
1248 self.contents = [1, 2, 3]
1249 def __contains__(self, x):
1250 return x in self.contents
1251 def __len__(self):
1252 return len(self.contents)
1253 def __iter__(self):
1254 return iter(self.contents)
1255 def __hash__(self):
1256 return self._hash()
1257 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001258 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001259
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001260 def test_isdisjoint_Set(self):
1261 class MySet(Set):
1262 def __init__(self, itr):
1263 self.contents = itr
1264 def __contains__(self, x):
1265 return x in self.contents
1266 def __iter__(self):
1267 return iter(self.contents)
1268 def __len__(self):
1269 return len([x for x in self.contents])
1270 s1 = MySet((1, 2, 3))
1271 s2 = MySet((4, 5, 6))
1272 s3 = MySet((1, 5, 6))
1273 self.assertTrue(s1.isdisjoint(s2))
1274 self.assertFalse(s1.isdisjoint(s3))
1275
1276 def test_equality_Set(self):
1277 class MySet(Set):
1278 def __init__(self, itr):
1279 self.contents = itr
1280 def __contains__(self, x):
1281 return x in self.contents
1282 def __iter__(self):
1283 return iter(self.contents)
1284 def __len__(self):
1285 return len([x for x in self.contents])
1286 s1 = MySet((1,))
1287 s2 = MySet((1, 2))
1288 s3 = MySet((3, 4))
1289 s4 = MySet((3, 4))
1290 self.assertTrue(s2 > s1)
1291 self.assertTrue(s1 < s2)
1292 self.assertFalse(s2 <= s1)
1293 self.assertFalse(s2 <= s3)
1294 self.assertFalse(s1 >= s2)
1295 self.assertEqual(s3, s4)
1296 self.assertNotEqual(s2, s3)
1297
1298 def test_arithmetic_Set(self):
1299 class MySet(Set):
1300 def __init__(self, itr):
1301 self.contents = itr
1302 def __contains__(self, x):
1303 return x in self.contents
1304 def __iter__(self):
1305 return iter(self.contents)
1306 def __len__(self):
1307 return len([x for x in self.contents])
1308 s1 = MySet((1, 2, 3))
1309 s2 = MySet((3, 4, 5))
1310 s3 = s1 & s2
1311 self.assertEqual(s3, MySet((3,)))
1312
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001313 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001314 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001315 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001316 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001317 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001318 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1319 'add', 'discard')
1320
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001321 def test_issue_5647(self):
1322 # MutableSet.__iand__ mutated the set during iteration
1323 s = WithSet('abcd')
1324 s &= WithSet('cdef') # This used to fail
1325 self.assertEqual(set(s), set('cd'))
1326
Raymond Hettingerae650182009-01-28 23:33:59 +00001327 def test_issue_4920(self):
1328 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001329 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001330 __slots__=['__s']
1331 def __init__(self,items=None):
1332 if items is None:
1333 items=[]
1334 self.__s=set(items)
1335 def __contains__(self,v):
1336 return v in self.__s
1337 def __iter__(self):
1338 return iter(self.__s)
1339 def __len__(self):
1340 return len(self.__s)
1341 def add(self,v):
1342 result=v not in self.__s
1343 self.__s.add(v)
1344 return result
1345 def discard(self,v):
1346 result=v in self.__s
1347 self.__s.discard(v)
1348 return result
1349 def __repr__(self):
1350 return "MySet(%s)" % repr(list(self))
1351 s = MySet([5,43,2,1])
1352 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001353
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001354 def test_issue8750(self):
1355 empty = WithSet()
1356 full = WithSet(range(10))
1357 s = WithSet(full)
1358 s -= s
1359 self.assertEqual(s, empty)
1360 s = WithSet(full)
1361 s ^= s
1362 self.assertEqual(s, empty)
1363 s = WithSet(full)
1364 s &= s
1365 self.assertEqual(s, full)
1366 s |= s
1367 self.assertEqual(s, full)
1368
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001369 def test_issue16373(self):
1370 # Recursion error comparing comparable and noncomparable
1371 # Set instances
1372 class MyComparableSet(Set):
1373 def __contains__(self, x):
1374 return False
1375 def __len__(self):
1376 return 0
1377 def __iter__(self):
1378 return iter([])
1379 class MyNonComparableSet(Set):
1380 def __contains__(self, x):
1381 return False
1382 def __len__(self):
1383 return 0
1384 def __iter__(self):
1385 return iter([])
1386 def __le__(self, x):
1387 return NotImplemented
1388 def __lt__(self, x):
1389 return NotImplemented
1390
1391 cs = MyComparableSet()
1392 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001393 self.assertFalse(ncs < cs)
1394 self.assertTrue(ncs <= cs)
1395 self.assertFalse(ncs > cs)
1396 self.assertTrue(ncs >= cs)
1397
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001398 def test_issue26915(self):
1399 # Container membership test should check identity first
1400 class CustomEqualObject:
1401 def __eq__(self, other):
1402 return False
Xiang Zhangd5d32492017-03-08 11:04:24 +08001403 class CustomSequence(Sequence):
1404 def __init__(self, seq):
1405 self._seq = seq
1406 def __getitem__(self, index):
1407 return self._seq[index]
1408 def __len__(self):
1409 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001410
1411 nan = float('nan')
1412 obj = CustomEqualObject()
Xiang Zhangd5d32492017-03-08 11:04:24 +08001413 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001414 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001415 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001416 ItemsView({1: nan, 2: obj}),
1417 ValuesView({1: nan, 2: obj})
1418 ]
1419 for container in containers:
1420 for elem in container:
1421 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001422 self.assertEqual(seq.index(nan), 0)
1423 self.assertEqual(seq.index(obj), 1)
1424 self.assertEqual(seq.count(nan), 2)
1425 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001426
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001427 def assertSameSet(self, s1, s2):
1428 # coerce both to a real set then check equality
1429 self.assertSetEqual(set(s1), set(s2))
1430
1431 def test_Set_interoperability_with_real_sets(self):
1432 # Issue: 8743
1433 class ListSet(Set):
1434 def __init__(self, elements=()):
1435 self.data = []
1436 for elem in elements:
1437 if elem not in self.data:
1438 self.data.append(elem)
1439 def __contains__(self, elem):
1440 return elem in self.data
1441 def __iter__(self):
1442 return iter(self.data)
1443 def __len__(self):
1444 return len(self.data)
1445 def __repr__(self):
1446 return 'Set({!r})'.format(self.data)
1447
1448 r1 = set('abc')
1449 r2 = set('bcd')
1450 r3 = set('abcde')
1451 f1 = ListSet('abc')
1452 f2 = ListSet('bcd')
1453 f3 = ListSet('abcde')
1454 l1 = list('abccba')
1455 l2 = list('bcddcb')
1456 l3 = list('abcdeedcba')
1457
1458 target = r1 & r2
1459 self.assertSameSet(f1 & f2, target)
1460 self.assertSameSet(f1 & r2, target)
1461 self.assertSameSet(r2 & f1, target)
1462 self.assertSameSet(f1 & l2, 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 fwd_target = r1 - r2
1471 rev_target = r2 - r1
1472 self.assertSameSet(f1 - f2, fwd_target)
1473 self.assertSameSet(f2 - f1, rev_target)
1474 self.assertSameSet(f1 - r2, fwd_target)
1475 self.assertSameSet(f2 - r1, rev_target)
1476 self.assertSameSet(r1 - f2, fwd_target)
1477 self.assertSameSet(r2 - f1, rev_target)
1478 self.assertSameSet(f1 - l2, fwd_target)
1479 self.assertSameSet(f2 - l1, rev_target)
1480
1481 target = r1 ^ r2
1482 self.assertSameSet(f1 ^ f2, target)
1483 self.assertSameSet(f1 ^ r2, target)
1484 self.assertSameSet(r2 ^ f1, target)
1485 self.assertSameSet(f1 ^ l2, target)
1486
1487 # Don't change the following to use assertLess or other
1488 # "more specific" unittest assertions. The current
1489 # assertTrue/assertFalse style makes the pattern of test
1490 # case combinations clear and allows us to know for sure
1491 # the exact operator being invoked.
1492
1493 # proper subset
1494 self.assertTrue(f1 < f3)
1495 self.assertFalse(f1 < f1)
1496 self.assertFalse(f1 < f2)
1497 self.assertTrue(r1 < f3)
1498 self.assertFalse(r1 < f1)
1499 self.assertFalse(r1 < f2)
1500 self.assertTrue(r1 < r3)
1501 self.assertFalse(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
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001505 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001506 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001507 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001508 f1 < l2
1509
1510 # any subset
1511 self.assertTrue(f1 <= f3)
1512 self.assertTrue(f1 <= f1)
1513 self.assertFalse(f1 <= f2)
1514 self.assertTrue(r1 <= f3)
1515 self.assertTrue(r1 <= f1)
1516 self.assertFalse(r1 <= f2)
1517 self.assertTrue(r1 <= r3)
1518 self.assertTrue(r1 <= r1)
1519 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001520 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001521 f1 <= l3
1522 with self.assertRaises(TypeError):
1523 f1 <= l1
1524 with self.assertRaises(TypeError):
1525 f1 <= l2
1526
1527 # proper superset
1528 self.assertTrue(f3 > f1)
1529 self.assertFalse(f1 > f1)
1530 self.assertFalse(f2 > f1)
1531 self.assertTrue(r3 > r1)
1532 self.assertFalse(f1 > r1)
1533 self.assertFalse(f2 > r1)
1534 self.assertTrue(r3 > r1)
1535 self.assertFalse(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 # any superset
1545 self.assertTrue(f3 >= f1)
1546 self.assertTrue(f1 >= f1)
1547 self.assertFalse(f2 >= f1)
1548 self.assertTrue(r3 >= r1)
1549 self.assertTrue(f1 >= r1)
1550 self.assertFalse(f2 >= r1)
1551 self.assertTrue(r3 >= r1)
1552 self.assertTrue(r1 >= r1)
1553 self.assertFalse(r2 >= r1)
1554 with self.assertRaises(TypeError):
1555 f1 >= l3
1556 with self.assertRaises(TypeError):
1557 f1 >=l1
1558 with self.assertRaises(TypeError):
1559 f1 >= l2
1560
1561 # equality
1562 self.assertTrue(f1 == f1)
1563 self.assertTrue(r1 == f1)
1564 self.assertTrue(f1 == r1)
1565 self.assertFalse(f1 == f3)
1566 self.assertFalse(r1 == f3)
1567 self.assertFalse(f1 == r3)
1568 self.assertFalse(f1 == l3)
1569 self.assertFalse(f1 == l1)
1570 self.assertFalse(f1 == l2)
1571
1572 # inequality
1573 self.assertFalse(f1 != f1)
1574 self.assertFalse(r1 != f1)
1575 self.assertFalse(f1 != r1)
1576 self.assertTrue(f1 != f3)
1577 self.assertTrue(r1 != f3)
1578 self.assertTrue(f1 != r3)
1579 self.assertTrue(f1 != l3)
1580 self.assertTrue(f1 != l1)
1581 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001582
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001583 def test_Mapping(self):
1584 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001585 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001586 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001587 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1588 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001589 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001590 def __len__(self):
1591 return 0
1592 def __getitem__(self, i):
1593 raise IndexError
1594 def __iter__(self):
1595 return iter(())
1596 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001597 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001598
1599 def test_MutableMapping(self):
1600 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001601 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001602 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001603 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1604 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001605
Raymond Hettinger9117c752010-08-22 07:44:24 +00001606 def test_MutableMapping_subclass(self):
1607 # Test issue 9214
1608 mymap = UserDict()
1609 mymap['red'] = 5
1610 self.assertIsInstance(mymap.keys(), Set)
1611 self.assertIsInstance(mymap.keys(), KeysView)
1612 self.assertIsInstance(mymap.items(), Set)
1613 self.assertIsInstance(mymap.items(), ItemsView)
1614
1615 mymap = UserDict()
1616 mymap['red'] = 5
1617 z = mymap.keys() | {'orange'}
1618 self.assertIsInstance(z, set)
1619 list(z)
1620 mymap['blue'] = 7 # Shouldn't affect 'z'
1621 self.assertEqual(sorted(z), ['orange', 'red'])
1622
1623 mymap = UserDict()
1624 mymap['red'] = 5
1625 z = mymap.items() | {('orange', 3)}
1626 self.assertIsInstance(z, set)
1627 list(z)
1628 mymap['blue'] = 7 # Shouldn't affect 'z'
1629 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1630
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001631 def test_Sequence(self):
1632 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001633 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001634 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001635 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001636 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001637 self.assertIsInstance(memoryview(b""), Sequence)
1638 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001639 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001640 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1641 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001642
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001643 def test_Sequence_mixins(self):
1644 class SequenceSubclass(Sequence):
1645 def __init__(self, seq=()):
1646 self.seq = seq
1647
1648 def __getitem__(self, index):
1649 return self.seq[index]
1650
1651 def __len__(self):
1652 return len(self.seq)
1653
1654 # Compare Sequence.index() behavior to (list|str).index() behavior
1655 def assert_index_same(seq1, seq2, index_args):
1656 try:
1657 expected = seq1.index(*index_args)
1658 except ValueError:
1659 with self.assertRaises(ValueError):
1660 seq2.index(*index_args)
1661 else:
1662 actual = seq2.index(*index_args)
1663 self.assertEqual(
1664 actual, expected, '%r.index%s' % (seq1, index_args))
1665
1666 for ty in list, str:
1667 nativeseq = ty('abracadabra')
1668 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1669 seqseq = SequenceSubclass(nativeseq)
1670 for letter in set(nativeseq) | {'z'}:
1671 assert_index_same(nativeseq, seqseq, (letter,))
1672 for start in range(-3, len(nativeseq) + 3):
1673 assert_index_same(nativeseq, seqseq, (letter, start))
1674 for stop in range(-3, len(nativeseq) + 3):
1675 assert_index_same(
1676 nativeseq, seqseq, (letter, start, stop))
1677
Guido van Rossumd05eb002007-11-21 22:26:24 +00001678 def test_ByteString(self):
1679 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001680 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001681 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001682 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001683 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001684 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001685 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001686 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001687
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001688 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001689 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001690 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001691 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001692 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001693 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001694 self.assertTrue(issubclass(sample, MutableSequence))
1695 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001696 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1697 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001698
Eli Bendersky0716a572011-03-04 10:38:14 +00001699 def test_MutableSequence_mixins(self):
Mike53f7a7c2017-12-14 14:04:53 +03001700 # Test the mixins of MutableSequence by creating a minimal concrete
Eli Bendersky0716a572011-03-04 10:38:14 +00001701 # class inherited from it.
1702 class MutableSequenceSubclass(MutableSequence):
1703 def __init__(self):
1704 self.lst = []
1705
1706 def __setitem__(self, index, value):
1707 self.lst[index] = value
1708
1709 def __getitem__(self, index):
1710 return self.lst[index]
1711
1712 def __len__(self):
1713 return len(self.lst)
1714
1715 def __delitem__(self, index):
1716 del self.lst[index]
1717
1718 def insert(self, index, value):
1719 self.lst.insert(index, value)
1720
1721 mss = MutableSequenceSubclass()
1722 mss.append(0)
1723 mss.extend((1, 2, 3, 4))
1724 self.assertEqual(len(mss), 5)
1725 self.assertEqual(mss[3], 3)
1726 mss.reverse()
1727 self.assertEqual(mss[3], 1)
1728 mss.pop()
1729 self.assertEqual(len(mss), 4)
1730 mss.remove(3)
1731 self.assertEqual(len(mss), 3)
1732 mss += (10, 20, 30)
1733 self.assertEqual(len(mss), 6)
1734 self.assertEqual(mss[-1], 30)
1735 mss.clear()
1736 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001737
1738################################################################################
1739### Counter
1740################################################################################
1741
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001742class CounterSubclassWithSetItem(Counter):
1743 # Test a counter subclass that overrides __setitem__
1744 def __init__(self, *args, **kwds):
1745 self.called = False
1746 Counter.__init__(self, *args, **kwds)
1747 def __setitem__(self, key, value):
1748 self.called = True
1749 Counter.__setitem__(self, key, value)
1750
1751class CounterSubclassWithGet(Counter):
1752 # Test a counter subclass that overrides get()
1753 def __init__(self, *args, **kwds):
1754 self.called = False
1755 Counter.__init__(self, *args, **kwds)
1756 def get(self, key, default):
1757 self.called = True
1758 return Counter.get(self, key, default)
1759
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001760class TestCounter(unittest.TestCase):
1761
1762 def test_basics(self):
1763 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001764 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1765 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001766 self.assertIsInstance(c, dict)
1767 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001768 self.assertTrue(issubclass(Counter, dict))
1769 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001770 self.assertEqual(len(c), 3)
1771 self.assertEqual(sum(c.values()), 6)
1772 self.assertEqual(sorted(c.values()), [1, 2, 3])
1773 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1774 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1775 self.assertEqual(sorted(c.items()),
1776 [('a', 3), ('b', 2), ('c', 1)])
1777 self.assertEqual(c['b'], 2)
1778 self.assertEqual(c['z'], 0)
1779 self.assertEqual(c.__contains__('c'), True)
1780 self.assertEqual(c.__contains__('z'), False)
1781 self.assertEqual(c.get('b', 10), 2)
1782 self.assertEqual(c.get('z', 10), 10)
1783 self.assertEqual(c, dict(a=3, b=2, c=1))
1784 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1785 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1786 for i in range(5):
1787 self.assertEqual(c.most_common(i),
1788 [('a', 3), ('b', 2), ('c', 1)][:i])
1789 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1790 c['a'] += 1 # increment an existing value
1791 c['b'] -= 2 # sub existing value to zero
1792 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001793 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001794 c['d'] -= 2 # sub from a missing value
1795 c['e'] = -5 # directly assign a missing value
1796 c['f'] += 4 # add to a missing value
1797 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1798 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1799 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001800 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001801 for i in range(3):
1802 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001803 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001804 c.clear()
1805 self.assertEqual(c, {})
1806 self.assertEqual(repr(c), 'Counter()')
1807 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1808 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001809 c.update(dict(a=5, b=3))
1810 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001811 c.update(Counter('a' * 50 + 'b' * 30))
1812 c.update() # test case with no args
1813 c.__init__('a' * 500 + 'b' * 300)
1814 c.__init__('cdc')
1815 c.__init__()
1816 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1817 self.assertEqual(c.setdefault('d', 5), 1)
1818 self.assertEqual(c['d'], 1)
1819 self.assertEqual(c.setdefault('e', 5), 5)
1820 self.assertEqual(c['e'], 5)
1821
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001822 def test_init(self):
1823 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1824 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1825 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1826 self.assertRaises(TypeError, Counter, 42)
1827 self.assertRaises(TypeError, Counter, (), ())
1828 self.assertRaises(TypeError, Counter.__init__)
1829
1830 def test_update(self):
1831 c = Counter()
1832 c.update(self=42)
1833 self.assertEqual(list(c.items()), [('self', 42)])
1834 c = Counter()
1835 c.update(iterable=42)
1836 self.assertEqual(list(c.items()), [('iterable', 42)])
1837 c = Counter()
1838 c.update(iterable=None)
1839 self.assertEqual(list(c.items()), [('iterable', None)])
1840 self.assertRaises(TypeError, Counter().update, 42)
1841 self.assertRaises(TypeError, Counter().update, {}, {})
1842 self.assertRaises(TypeError, Counter.update)
1843
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001844 def test_copying(self):
1845 # Check that counters are copyable, deepcopyable, picklable, and
1846 #have a repr/eval round-trip
1847 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001848 def check(dup):
1849 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1850 self.assertIsNot(dup, words, msg)
1851 self.assertEqual(dup, words)
1852 check(words.copy())
1853 check(copy.copy(words))
1854 check(copy.deepcopy(words))
1855 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1856 with self.subTest(proto=proto):
1857 check(pickle.loads(pickle.dumps(words, proto)))
1858 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001859 update_test = Counter()
1860 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001861 check(update_test)
1862 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001863
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001864 def test_copy_subclass(self):
1865 class MyCounter(Counter):
1866 pass
1867 c = MyCounter('slartibartfast')
1868 d = c.copy()
1869 self.assertEqual(d, c)
1870 self.assertEqual(len(d), len(c))
1871 self.assertEqual(type(d), type(c))
1872
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001873 def test_conversions(self):
1874 # Convert to: set, list, dict
1875 s = 'she sells sea shells by the sea shore'
1876 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1877 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1878 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1879 self.assertEqual(set(Counter(s)), set(s))
1880
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001881 def test_invariant_for_the_in_operator(self):
1882 c = Counter(a=10, b=-2, c=0)
1883 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001884 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001885 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001886
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001887 def test_multiset_operations(self):
1888 # Verify that adding a zero counter will strip zeros and negatives
1889 c = Counter(a=10, b=-2, c=0) + Counter()
1890 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001891
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001892 elements = 'abcd'
1893 for i in range(1000):
1894 # test random pairs of multisets
1895 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001896 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001897 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001898 q.update(h=1, i=-1, j=0)
1899 for counterop, numberop in [
1900 (Counter.__add__, lambda x, y: max(0, x+y)),
1901 (Counter.__sub__, lambda x, y: max(0, x-y)),
1902 (Counter.__or__, lambda x, y: max(0,x,y)),
1903 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001904 ]:
1905 result = counterop(p, q)
1906 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001907 self.assertEqual(numberop(p[x], q[x]), result[x],
1908 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001909 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001910 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001911
1912 elements = 'abcdef'
1913 for i in range(100):
1914 # verify that random multisets with no repeats are exactly like sets
1915 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1916 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1917 for counterop, setop in [
1918 (Counter.__sub__, set.__sub__),
1919 (Counter.__or__, set.__or__),
1920 (Counter.__and__, set.__and__),
1921 ]:
1922 counter_result = counterop(p, q)
1923 set_result = setop(set(p.elements()), set(q.elements()))
1924 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001925
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001926 def test_inplace_operations(self):
1927 elements = 'abcd'
1928 for i in range(1000):
1929 # test random pairs of multisets
1930 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1931 p.update(e=1, f=-1, g=0)
1932 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1933 q.update(h=1, i=-1, j=0)
1934 for inplace_op, regular_op in [
1935 (Counter.__iadd__, Counter.__add__),
1936 (Counter.__isub__, Counter.__sub__),
1937 (Counter.__ior__, Counter.__or__),
1938 (Counter.__iand__, Counter.__and__),
1939 ]:
1940 c = p.copy()
1941 c_id = id(c)
1942 regular_result = regular_op(c, q)
1943 inplace_result = inplace_op(c, q)
1944 self.assertEqual(inplace_result, regular_result)
1945 self.assertEqual(id(inplace_result), c_id)
1946
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001947 def test_subtract(self):
1948 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1949 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1950 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1951 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1952 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1953 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1954 c = Counter('aaabbcd')
1955 c.subtract('aaaabbcce')
1956 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001957
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001958 c = Counter()
1959 c.subtract(self=42)
1960 self.assertEqual(list(c.items()), [('self', -42)])
1961 c = Counter()
1962 c.subtract(iterable=42)
1963 self.assertEqual(list(c.items()), [('iterable', -42)])
1964 self.assertRaises(TypeError, Counter().subtract, 42)
1965 self.assertRaises(TypeError, Counter().subtract, {}, {})
1966 self.assertRaises(TypeError, Counter.subtract)
1967
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001968 def test_unary(self):
1969 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1970 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1971 self.assertEqual(dict(-c), dict(a=5))
1972
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001973 def test_repr_nonsortable(self):
1974 c = Counter(a=2, b=None)
1975 r = repr(c)
1976 self.assertIn("'a': 2", r)
1977 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001978
Raymond Hettinger426e0522011-01-03 02:12:02 +00001979 def test_helper_function(self):
1980 # two paths, one for real dicts and one for other mappings
1981 elems = list('abracadabra')
1982
1983 d = dict()
1984 _count_elements(d, elems)
1985 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1986
1987 m = OrderedDict()
1988 _count_elements(m, elems)
1989 self.assertEqual(m,
1990 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1991
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001992 # test fidelity to the pure python version
1993 c = CounterSubclassWithSetItem('abracadabra')
1994 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001995 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001996 c = CounterSubclassWithGet('abracadabra')
1997 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001998 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001999
Raymond Hettinger499e1932011-02-23 07:56:53 +00002000
2001################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00002002### Run tests
2003################################################################################
2004
Guido van Rossumd8faa362007-04-27 19:54:29 +00002005def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00002006 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002007 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00002008 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06002009 TestUserObjects,
2010 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002011 support.run_unittest(*test_classes)
2012 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002013
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002014
Guido van Rossumd8faa362007-04-27 19:54:29 +00002015if __name__ == "__main__":
2016 test_main(verbose=True)