blob: 2099d236d0c4a1f299023407e5c6bb39fd167645 [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
Martin Pantereb995702016-07-28 01:11:04 +0000117 def test_constructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000118 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000119 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
120
Raymond Hettingerd0321312011-02-26 06:53:58 +0000121 def test_bool(self):
122 self.assertFalse(ChainMap())
123 self.assertFalse(ChainMap({}, {}))
124 self.assertTrue(ChainMap({1:2}, {}))
125 self.assertTrue(ChainMap({}, {1:2}))
126
Raymond Hettinger499e1932011-02-23 07:56:53 +0000127 def test_missing(self):
128 class DefaultChainMap(ChainMap):
129 def __missing__(self, key):
130 return 999
131 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
132 for k, v in dict(a=1, b=2, c=30, d=999).items():
133 self.assertEqual(d[k], v) # check __getitem__ w/missing
134 for k, v in dict(a=1, b=2, c=30, d=77).items():
135 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
136 for k, v in dict(a=True, b=True, c=True, d=False).items():
137 self.assertEqual(k in d, v) # check __contains__ w/missing
138 self.assertEqual(d.pop('a', 1001), 1, d)
139 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
140 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
141 with self.assertRaises(KeyError):
142 d.popitem()
143
Miss Islington (bot)170b3f72018-02-11 01:09:52 -0800144 def test_order_preservation(self):
145 d = ChainMap(
146 OrderedDict(j=0, h=88888),
147 OrderedDict(),
148 OrderedDict(i=9999, d=4444, c=3333),
149 OrderedDict(f=666, b=222, g=777, c=333, h=888),
150 OrderedDict(),
151 OrderedDict(e=55, b=22),
152 OrderedDict(a=1, b=2, c=3, d=4, e=5),
153 OrderedDict(),
154 )
155 self.assertEqual(''.join(d), 'abcdefghij')
156 self.assertEqual(list(d.items()),
157 [('a', 1), ('b', 222), ('c', 3333), ('d', 4444),
158 ('e', 55), ('f', 666), ('g', 777), ('h', 88888),
159 ('i', 9999), ('j', 0)])
160
Raymond Hettinger499e1932011-02-23 07:56:53 +0000161 def test_dict_coercion(self):
162 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
163 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
164 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
165
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000166 def test_new_child(self):
167 'Tests for changes for issue #16613.'
168 c = ChainMap()
169 c['a'] = 1
170 c['b'] = 2
171 m = {'b':20, 'c': 30}
172 d = c.new_child(m)
173 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
174 self.assertIs(m, d.maps[0])
175
176 # Use a different map than a dict
177 class lowerdict(dict):
178 def __getitem__(self, key):
179 if isinstance(key, str):
180 key = key.lower()
181 return dict.__getitem__(self, key)
182 def __contains__(self, key):
183 if isinstance(key, str):
184 key = key.lower()
185 return dict.__contains__(self, key)
186
187 c = ChainMap()
188 c['a'] = 1
189 c['b'] = 2
190 m = lowerdict(b=20, c=30)
191 d = c.new_child(m)
192 self.assertIs(m, d.maps[0])
193 for key in 'abc': # check contains
194 self.assertIn(key, d)
195 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
196 self.assertEqual(d.get(k, 100), v)
197
Raymond Hettinger499e1932011-02-23 07:56:53 +0000198
199################################################################################
200### Named Tuples
201################################################################################
202
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000203TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000204
205class TestNamedTuple(unittest.TestCase):
206
207 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000208 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000209 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000210 self.assertEqual(Point.__slots__, ())
211 self.assertEqual(Point.__module__, __name__)
212 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000213 self.assertEqual(Point._fields, ('x', 'y'))
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000214
215 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
216 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
217 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
218
219 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
220 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
221 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000222 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000223 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
224
225 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000226 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000227
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000228 nt = namedtuple('nt', 'the quick brown fox') # 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 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000231 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000232
Christian Heimesfaf2f632008-01-06 16:59:19 +0000233 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
234 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
235
Raymond Hettinger39482072018-01-10 21:45:19 -0800236 def test_defaults(self):
237 Point = namedtuple('Point', 'x y', defaults=(10, 20)) # 2 defaults
238 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
239 self.assertEqual(Point(1, 2), (1, 2))
240 self.assertEqual(Point(1), (1, 20))
241 self.assertEqual(Point(), (10, 20))
242
243 Point = namedtuple('Point', 'x y', defaults=(20,)) # 1 default
244 self.assertEqual(Point._fields_defaults, {'y': 20})
245 self.assertEqual(Point(1, 2), (1, 2))
246 self.assertEqual(Point(1), (1, 20))
247
248 Point = namedtuple('Point', 'x y', defaults=()) # 0 defaults
249 self.assertEqual(Point._fields_defaults, {})
250 self.assertEqual(Point(1, 2), (1, 2))
251 with self.assertRaises(TypeError):
252 Point(1)
253
254 with self.assertRaises(TypeError): # catch too few args
255 Point()
256 with self.assertRaises(TypeError): # catch too many args
257 Point(1, 2, 3)
258 with self.assertRaises(TypeError): # too many defaults
259 Point = namedtuple('Point', 'x y', defaults=(10, 20, 30))
260 with self.assertRaises(TypeError): # non-iterable defaults
261 Point = namedtuple('Point', 'x y', defaults=10)
262 with self.assertRaises(TypeError): # another non-iterable default
263 Point = namedtuple('Point', 'x y', defaults=False)
264
265 Point = namedtuple('Point', 'x y', defaults=None) # default is None
266 self.assertEqual(Point._fields_defaults, {})
267 self.assertIsNone(Point.__new__.__defaults__, None)
268 self.assertEqual(Point(10, 20), (10, 20))
269 with self.assertRaises(TypeError): # catch too few args
270 Point(10)
271
272 Point = namedtuple('Point', 'x y', defaults=[10, 20]) # allow non-tuple iterable
273 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
274 self.assertEqual(Point.__new__.__defaults__, (10, 20))
275 self.assertEqual(Point(1, 2), (1, 2))
276 self.assertEqual(Point(1), (1, 20))
277 self.assertEqual(Point(), (10, 20))
278
279 Point = namedtuple('Point', 'x y', defaults=iter([10, 20])) # allow plain iterator
280 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
281 self.assertEqual(Point.__new__.__defaults__, (10, 20))
282 self.assertEqual(Point(1, 2), (1, 2))
283 self.assertEqual(Point(1), (1, 20))
284 self.assertEqual(Point(), (10, 20))
285
286
R. David Murray378c0cf2010-02-24 01:46:21 +0000287 @unittest.skipIf(sys.flags.optimize >= 2,
288 "Docstrings are omitted with -O2 and above")
289 def test_factory_doc_attr(self):
290 Point = namedtuple('Point', 'x y')
291 self.assertEqual(Point.__doc__, 'Point(x, y)')
292
Raymond Hettingereac503a2015-05-13 01:09:59 -0700293 @unittest.skipIf(sys.flags.optimize >= 2,
294 "Docstrings are omitted with -O2 and above")
295 def test_doc_writable(self):
296 Point = namedtuple('Point', 'x y')
297 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
298 Point.x.__doc__ = 'docstring for Point.x'
299 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
300
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000301 def test_name_fixer(self):
302 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000303 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
304 [('abc', 'class'), ('abc', '_1')], # field has keyword
305 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
306 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
307 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
308 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000309 ]:
310 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
311
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700312 def test_module_parameter(self):
313 NT = namedtuple('NT', ['x', 'y'], module=collections)
314 self.assertEqual(NT.__module__, collections)
315
Guido van Rossumd8faa362007-04-27 19:54:29 +0000316 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000317 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000318 p = Point(11, 22)
319 self.assertEqual(p, Point(x=11, y=22))
320 self.assertEqual(p, Point(11, y=22))
321 self.assertEqual(p, Point(y=22, x=11))
322 self.assertEqual(p, Point(*(11, 22)))
323 self.assertEqual(p, Point(**dict(x=11, y=22)))
324 self.assertRaises(TypeError, Point, 1) # too few args
325 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
326 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
327 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
328 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000329 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000330 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000331 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
332 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700333 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000334
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000335 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000336 p._replace(x=1, error=2)
337 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000338 pass
339 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000340 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000341
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000342 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000343 Point = namedtuple('Point', 'x, y')
344 p = Point(x=11, y=22)
345 self.assertEqual(repr(p), 'Point(x=11, y=22)')
346
347 # verify that fieldspec can be a non-string sequence
348 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000349 p = Point(x=11, y=22)
350 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000351
352 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000353 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000354 p = Point(11, 22)
355
Ezio Melottie9615932010-01-24 19:26:24 +0000356 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000357 self.assertEqual(p, (11, 22)) # matches a real tuple
358 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
359 self.assertEqual(list(p), [11, 22]) # coercable to a list
360 self.assertEqual(max(p), 22) # iterable
361 self.assertEqual(max(*p), 22) # star-able
362 x, y = p
363 self.assertEqual(p, (x, y)) # unpacks like a tuple
364 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
365 self.assertRaises(IndexError, p.__getitem__, 3)
366
367 self.assertEqual(p.x, x)
368 self.assertEqual(p.y, y)
369 self.assertRaises(AttributeError, eval, 'p.z', locals())
370
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000371 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000372 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000373 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000374 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000375 self.assertEqual(repr(Zero()), 'Zero()')
376 self.assertEqual(Zero()._asdict(), {})
377 self.assertEqual(Zero()._fields, ())
378
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000379 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000380 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000381 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000382 self.assertEqual(Dot(1).d, 1)
383 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
384 self.assertEqual(Dot(1)._asdict(), {'d':1})
385 self.assertEqual(Dot(1)._replace(d=999), (999,))
386 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000387
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200388 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200389 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000390 for j in range(10)]) for i in range(n)))
391 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000392 Big = namedtuple('Big', names)
393 b = Big(*range(n))
394 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000395 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000396 for pos, name in enumerate(names):
397 self.assertEqual(getattr(b, name), pos)
398 repr(b) # make sure repr() doesn't blow-up
399 d = b._asdict()
400 d_expected = dict(zip(names, range(n)))
401 self.assertEqual(d, d_expected)
402 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
403 b2_expected = list(range(n))
404 b2_expected[1] = 999
405 b2_expected[-5] = 42
406 self.assertEqual(b2, tuple(b2_expected))
407 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000408
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000409 def test_pickle(self):
410 p = TestNT(x=10, y=20, z=30)
411 for module in (pickle,):
412 loads = getattr(module, 'loads')
413 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500414 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000415 q = loads(dumps(p, protocol))
416 self.assertEqual(p, q)
417 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700418 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000419
420 def test_copy(self):
421 p = TestNT(x=10, y=20, z=30)
422 for copier in copy.copy, copy.deepcopy:
423 q = copier(p)
424 self.assertEqual(p, q)
425 self.assertEqual(p._fields, q._fields)
426
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000427 def test_name_conflicts(self):
428 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
429 # failed when used as field names. Test to make sure these now work.
430 T = namedtuple('T', 'itemgetter property self cls tuple')
431 t = T(1, 2, 3, 4, 5)
432 self.assertEqual(t, (1,2,3,4,5))
433 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
434 self.assertEqual(newt, (10,20,30,40,50))
435
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700436 # Broader test of all interesting names taken from the code, old
437 # template, and an example
438 words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create',
439 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper',
440 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note',
441 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError',
442 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add',
443 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments',
444 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot',
445 'class_namespace', 'classmethod', 'cls', 'collections', 'convert',
446 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict',
447 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect',
448 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f',
449 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame',
450 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater',
451 'has', 'help', 'identifiers', 'index', 'indexable', 'instance',
452 'instantiate', 'interning', 'introspection', 'isidentifier',
453 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords',
454 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata',
455 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named',
456 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new',
457 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option',
458 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional',
459 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr',
460 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen',
461 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start',
462 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys',
463 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new',
464 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use',
465 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where',
466 'which', 'work', 'x', 'y', 'z', 'zip'}
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000467 T = namedtuple('T', words)
468 # test __new__
469 values = tuple(range(len(words)))
470 t = T(*values)
471 self.assertEqual(t, values)
472 t = T(**dict(zip(T._fields, values)))
473 self.assertEqual(t, values)
474 # test _make
475 t = T._make(values)
476 self.assertEqual(t, values)
477 # exercise __repr__
478 repr(t)
479 # test _asdict
480 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
481 # test _replace
482 t = T._make(values)
483 newvalues = tuple(v*10 for v in values)
484 newt = t._replace(**dict(zip(T._fields, newvalues)))
485 self.assertEqual(newt, newvalues)
486 # test _fields
487 self.assertEqual(T._fields, tuple(words))
488 # test __getnewargs__
489 self.assertEqual(t.__getnewargs__(), values)
490
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000491 def test_repr(self):
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700492 A = namedtuple('A', 'x')
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000493 self.assertEqual(repr(A(1)), 'A(x=1)')
494 # repr should show the name of the subclass
495 class B(A):
496 pass
497 self.assertEqual(repr(B(1)), 'B(x=1)')
498
Raymond Hettinger6538b432016-08-16 10:55:43 -0700499 def test_keyword_only_arguments(self):
500 # See issue 25628
Raymond Hettinger6538b432016-08-16 10:55:43 -0700501 with self.assertRaises(TypeError):
502 NT = namedtuple('NT', ['x', 'y'], True)
503
504 NT = namedtuple('NT', ['abc', 'def'], rename=True)
505 self.assertEqual(NT._fields, ('abc', '_1'))
506 with self.assertRaises(TypeError):
507 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000508
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700509 def test_namedtuple_subclass_issue_24931(self):
510 class Point(namedtuple('_Point', ['x', 'y'])):
511 pass
512
513 a = Point(3, 4)
514 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
515
516 a.w = 5
517 self.assertEqual(a.__dict__, {'w': 5})
518
519
Raymond Hettinger499e1932011-02-23 07:56:53 +0000520################################################################################
521### Abstract Base Classes
522################################################################################
523
Raymond Hettingerae650182009-01-28 23:33:59 +0000524class ABCTestCase(unittest.TestCase):
525
526 def validate_abstract_methods(self, abc, *names):
527 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
528
529 # everything should work will all required methods are present
530 C = type('C', (abc,), methodstubs)
531 C()
532
533 # instantiation should fail if a required method is missing
534 for name in names:
535 stubs = methodstubs.copy()
536 del stubs[name]
537 C = type('C', (abc,), stubs)
538 self.assertRaises(TypeError, C, name)
539
Florent Xiclunace153f62010-03-08 15:34:35 +0000540 def validate_isinstance(self, abc, name):
541 stub = lambda s, *args: 0
542
543 C = type('C', (object,), {'__hash__': None})
544 setattr(C, name, stub)
545 self.assertIsInstance(C(), abc)
546 self.assertTrue(issubclass(C, abc))
547
548 C = type('C', (object,), {'__hash__': None})
549 self.assertNotIsInstance(C(), abc)
550 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000551
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000552 def validate_comparison(self, instance):
553 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
554 operators = {}
555 for op in ops:
556 name = '__' + op + '__'
557 operators[name] = getattr(operator, name)
558
559 class Other:
560 def __init__(self):
561 self.right_side = False
562 def __eq__(self, other):
563 self.right_side = True
564 return True
565 __lt__ = __eq__
566 __gt__ = __eq__
567 __le__ = __eq__
568 __ge__ = __eq__
569 __ne__ = __eq__
570 __ror__ = __eq__
571 __rand__ = __eq__
572 __rxor__ = __eq__
573 __rsub__ = __eq__
574
575 for name, op in operators.items():
576 if not hasattr(instance, name):
577 continue
578 other = Other()
579 op(instance, other)
580 self.assertTrue(other.right_side,'Right side not called for %s.%s'
581 % (type(instance), name))
582
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700583def _test_gen():
584 yield
585
Raymond Hettingerae650182009-01-28 23:33:59 +0000586class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000587
Yury Selivanov75445082015-05-11 22:57:16 -0400588 def test_Awaitable(self):
589 def gen():
590 yield
591
592 @types.coroutine
593 def coro():
594 yield
595
596 async def new_coro():
597 pass
598
599 class Bar:
600 def __await__(self):
601 yield
602
603 class MinimalCoro(Coroutine):
604 def send(self, value):
605 return value
606 def throw(self, typ, val=None, tb=None):
607 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400608 def __await__(self):
609 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400610
611 non_samples = [None, int(), gen(), object()]
612 for x in non_samples:
613 self.assertNotIsInstance(x, Awaitable)
614 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
615
616 samples = [Bar(), MinimalCoro()]
617 for x in samples:
618 self.assertIsInstance(x, Awaitable)
619 self.assertTrue(issubclass(type(x), Awaitable))
620
621 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400622 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
623 # flag don't have '__await__' method, hence can't be instances
624 # of Awaitable. Use inspect.isawaitable to detect them.
625 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400626
627 c = new_coro()
628 self.assertIsInstance(c, Awaitable)
Mike53f7a7c2017-12-14 14:04:53 +0300629 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400630
Yury Selivanov56fc6142015-05-29 09:01:29 -0400631 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400632 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400633 self.assertTrue(isinstance(CoroLike(), Awaitable))
634 self.assertTrue(issubclass(CoroLike, Awaitable))
635 CoroLike = None
636 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400637
Yury Selivanov75445082015-05-11 22:57:16 -0400638 def test_Coroutine(self):
639 def gen():
640 yield
641
642 @types.coroutine
643 def coro():
644 yield
645
646 async def new_coro():
647 pass
648
649 class Bar:
650 def __await__(self):
651 yield
652
653 class MinimalCoro(Coroutine):
654 def send(self, value):
655 return value
656 def throw(self, typ, val=None, tb=None):
657 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400658 def __await__(self):
659 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400660
661 non_samples = [None, int(), gen(), object(), Bar()]
662 for x in non_samples:
663 self.assertNotIsInstance(x, Coroutine)
664 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
665
666 samples = [MinimalCoro()]
667 for x in samples:
668 self.assertIsInstance(x, Awaitable)
669 self.assertTrue(issubclass(type(x), Awaitable))
670
671 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400672 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
673 # flag don't have '__await__' method, hence can't be instances
674 # of Coroutine. Use inspect.isawaitable to detect them.
675 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400676
677 c = new_coro()
678 self.assertIsInstance(c, Coroutine)
Mike53f7a7c2017-12-14 14:04:53 +0300679 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400680
Yury Selivanov56fc6142015-05-29 09:01:29 -0400681 class CoroLike:
682 def send(self, value):
683 pass
684 def throw(self, typ, val=None, tb=None):
685 pass
686 def close(self):
687 pass
688 def __await__(self):
689 pass
690 self.assertTrue(isinstance(CoroLike(), Coroutine))
691 self.assertTrue(issubclass(CoroLike, Coroutine))
692
693 class CoroLike:
694 def send(self, value):
695 pass
696 def close(self):
697 pass
698 def __await__(self):
699 pass
700 self.assertFalse(isinstance(CoroLike(), Coroutine))
701 self.assertFalse(issubclass(CoroLike, Coroutine))
702
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000703 def test_Hashable(self):
704 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000705 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000706 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000707 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000708 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000709 # Check some hashables
710 samples = [None,
711 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000712 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000713 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000714 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000715 ]
716 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000717 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000718 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000719 self.assertRaises(TypeError, Hashable)
720 # Check direct subclassing
721 class H(Hashable):
722 def __hash__(self):
723 return super().__hash__()
724 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000725 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000726 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000727 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000728
Yury Selivanove0104ae2015-05-14 12:19:16 -0400729 def test_AsyncIterable(self):
730 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400731 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400732 return self
733 self.assertTrue(isinstance(AI(), AsyncIterable))
734 self.assertTrue(issubclass(AI, AsyncIterable))
735 # Check some non-iterables
736 non_samples = [None, object, []]
737 for x in non_samples:
738 self.assertNotIsInstance(x, AsyncIterable)
739 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
740 self.validate_abstract_methods(AsyncIterable, '__aiter__')
741 self.validate_isinstance(AsyncIterable, '__aiter__')
742
743 def test_AsyncIterator(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 async def __anext__(self):
748 raise StopAsyncIteration
749 self.assertTrue(isinstance(AI(), AsyncIterator))
750 self.assertTrue(issubclass(AI, AsyncIterator))
751 non_samples = [None, object, []]
752 # Check some non-iterables
753 for x in non_samples:
754 self.assertNotIsInstance(x, AsyncIterator)
755 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
756 # Similarly to regular iterators (see issue 10565)
757 class AnextOnly:
758 async def __anext__(self):
759 raise StopAsyncIteration
760 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
761 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
762
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000763 def test_Iterable(self):
764 # Check some non-iterables
765 non_samples = [None, 42, 3.14, 1j]
766 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000767 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000768 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000769 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000770 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000771 tuple(), list(), set(), frozenset(), dict(),
772 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700773 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000774 (x for x in []),
775 ]
776 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000777 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000778 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000779 # Check direct subclassing
780 class I(Iterable):
781 def __iter__(self):
782 return super().__iter__()
783 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000784 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000785 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000786 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700787 # Check None blocking
788 class It:
789 def __iter__(self): return iter([])
790 class ItBlocked(It):
791 __iter__ = None
792 self.assertTrue(issubclass(It, Iterable))
793 self.assertTrue(isinstance(It(), Iterable))
794 self.assertFalse(issubclass(ItBlocked, Iterable))
795 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000796
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700797 def test_Reversible(self):
798 # Check some non-reversibles
799 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()]
800 for x in non_samples:
801 self.assertNotIsInstance(x, Reversible)
802 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700803 # Check some non-reversible iterables
804 non_reversibles = [dict().keys(), dict().items(), dict().values(),
805 Counter(), Counter().keys(), Counter().items(),
806 Counter().values(), _test_gen(),
807 (x for x in []), iter([]), reversed([])]
808 for x in non_reversibles:
809 self.assertNotIsInstance(x, Reversible)
810 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
811 # Check some reversible iterables
812 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
813 OrderedDict().keys(), OrderedDict().items(),
814 OrderedDict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700815 for x in samples:
816 self.assertIsInstance(x, Reversible)
817 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
818 # Check also Mapping, MutableMapping, and Sequence
819 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
820 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
821 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
822 # Check direct subclassing
823 class R(Reversible):
824 def __iter__(self):
825 return iter(list())
826 def __reversed__(self):
827 return iter(list())
828 self.assertEqual(list(reversed(R())), [])
829 self.assertFalse(issubclass(float, R))
830 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700831 # Check reversible non-iterable (which is not Reversible)
832 class RevNoIter:
833 def __reversed__(self): return reversed([])
834 class RevPlusIter(RevNoIter):
835 def __iter__(self): return iter([])
836 self.assertFalse(issubclass(RevNoIter, Reversible))
837 self.assertFalse(isinstance(RevNoIter(), Reversible))
838 self.assertTrue(issubclass(RevPlusIter, Reversible))
839 self.assertTrue(isinstance(RevPlusIter(), Reversible))
840 # Check None blocking
841 class Rev:
842 def __iter__(self): return iter([])
843 def __reversed__(self): return reversed([])
844 class RevItBlocked(Rev):
845 __iter__ = None
846 class RevRevBlocked(Rev):
847 __reversed__ = None
848 self.assertTrue(issubclass(Rev, Reversible))
849 self.assertTrue(isinstance(Rev(), Reversible))
850 self.assertFalse(issubclass(RevItBlocked, Reversible))
851 self.assertFalse(isinstance(RevItBlocked(), Reversible))
852 self.assertFalse(issubclass(RevRevBlocked, Reversible))
853 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700854
Guido van Rossumf0666942016-08-23 10:47:07 -0700855 def test_Collection(self):
856 # Check some non-collections
857 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
858 for x in non_collections:
859 self.assertNotIsInstance(x, Collection)
860 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
861 # Check some non-collection iterables
862 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800863 (x for x in [])]
Guido van Rossumf0666942016-08-23 10:47:07 -0700864 for x in non_col_iterables:
865 self.assertNotIsInstance(x, Collection)
866 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
867 # Check some collections
868 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800869 list(), dict().keys(), dict().items(), dict().values()]
Guido van Rossumf0666942016-08-23 10:47:07 -0700870 for x in samples:
871 self.assertIsInstance(x, Collection)
872 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
873 # Check also Mapping, MutableMapping, etc.
874 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
875 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
876 self.assertTrue(issubclass(MutableMapping, Collection),
877 repr(MutableMapping))
878 self.assertTrue(issubclass(Set, Collection), repr(Set))
879 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
880 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
881 # Check direct subclassing
882 class Col(Collection):
883 def __iter__(self):
884 return iter(list())
885 def __len__(self):
886 return 0
887 def __contains__(self, item):
888 return False
889 class DerCol(Col): pass
890 self.assertEqual(list(iter(Col())), [])
891 self.assertFalse(issubclass(list, Col))
892 self.assertFalse(issubclass(set, Col))
893 self.assertFalse(issubclass(float, Col))
894 self.assertEqual(list(iter(DerCol())), [])
895 self.assertFalse(issubclass(list, DerCol))
896 self.assertFalse(issubclass(set, DerCol))
897 self.assertFalse(issubclass(float, DerCol))
898 self.validate_abstract_methods(Collection, '__len__', '__iter__',
899 '__contains__')
900 # Check sized container non-iterable (which is not Collection) etc.
901 class ColNoIter:
902 def __len__(self): return 0
903 def __contains__(self, item): return False
904 class ColNoSize:
905 def __iter__(self): return iter([])
906 def __contains__(self, item): return False
907 class ColNoCont:
908 def __iter__(self): return iter([])
909 def __len__(self): return 0
910 self.assertFalse(issubclass(ColNoIter, Collection))
911 self.assertFalse(isinstance(ColNoIter(), Collection))
912 self.assertFalse(issubclass(ColNoSize, Collection))
913 self.assertFalse(isinstance(ColNoSize(), Collection))
914 self.assertFalse(issubclass(ColNoCont, Collection))
915 self.assertFalse(isinstance(ColNoCont(), Collection))
916 # Check None blocking
917 class SizeBlock:
918 def __iter__(self): return iter([])
919 def __contains__(self): return False
920 __len__ = None
921 class IterBlock:
922 def __len__(self): return 0
923 def __contains__(self): return True
924 __iter__ = None
925 self.assertFalse(issubclass(SizeBlock, Collection))
926 self.assertFalse(isinstance(SizeBlock(), Collection))
927 self.assertFalse(issubclass(IterBlock, Collection))
928 self.assertFalse(isinstance(IterBlock(), Collection))
929 # Check None blocking in subclass
930 class ColImpl:
931 def __iter__(self):
932 return iter(list())
933 def __len__(self):
934 return 0
935 def __contains__(self, item):
936 return False
937 class NonCol(ColImpl):
938 __contains__ = None
939 self.assertFalse(issubclass(NonCol, Collection))
940 self.assertFalse(isinstance(NonCol(), Collection))
941
942
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000943 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000944 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000945 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000946 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000947 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000948 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000949 iter(tuple()), iter(list()), iter(dict()),
950 iter(set()), iter(frozenset()),
951 iter(dict().keys()), iter(dict().items()),
952 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700953 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000954 (x for x in []),
955 ]
956 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000957 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000958 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000959 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
960
961 # Issue 10565
962 class NextOnly:
963 def __next__(self):
964 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800965 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000966 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000967
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400968 def test_Generator(self):
969 class NonGen1:
970 def __iter__(self): return self
971 def __next__(self): return None
972 def close(self): pass
973 def throw(self, typ, val=None, tb=None): pass
974
975 class NonGen2:
976 def __iter__(self): return self
977 def __next__(self): return None
978 def close(self): pass
979 def send(self, value): return value
980
981 class NonGen3:
982 def close(self): pass
983 def send(self, value): return value
984 def throw(self, typ, val=None, tb=None): pass
985
986 non_samples = [
987 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
988 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
989 for x in non_samples:
990 self.assertNotIsInstance(x, Generator)
991 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
992
993 class Gen:
994 def __iter__(self): return self
995 def __next__(self): return None
996 def close(self): pass
997 def send(self, value): return value
998 def throw(self, typ, val=None, tb=None): pass
999
1000 class MinimalGen(Generator):
1001 def send(self, value):
1002 return value
1003 def throw(self, typ, val=None, tb=None):
1004 super().throw(typ, val, tb)
1005
1006 def gen():
1007 yield 1
1008
1009 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
1010 for x in samples:
1011 self.assertIsInstance(x, Iterator)
1012 self.assertIsInstance(x, Generator)
1013 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
1014 self.validate_abstract_methods(Generator, 'send', 'throw')
1015
1016 # mixin tests
1017 mgen = MinimalGen()
1018 self.assertIs(mgen, iter(mgen))
1019 self.assertIs(mgen.send(None), next(mgen))
1020 self.assertEqual(2, mgen.send(2))
1021 self.assertIsNone(mgen.close())
1022 self.assertRaises(ValueError, mgen.throw, ValueError)
1023 self.assertRaisesRegex(ValueError, "^huhu$",
1024 mgen.throw, ValueError, ValueError("huhu"))
1025 self.assertRaises(StopIteration, mgen.throw, StopIteration())
1026
1027 class FailOnClose(Generator):
1028 def send(self, value): return value
1029 def throw(self, *args): raise ValueError
1030
1031 self.assertRaises(ValueError, FailOnClose().close)
1032
1033 class IgnoreGeneratorExit(Generator):
1034 def send(self, value): return value
1035 def throw(self, *args): pass
1036
1037 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
1038
Yury Selivanov22214ab2016-11-16 18:25:04 -05001039 def test_AsyncGenerator(self):
1040 class NonAGen1:
1041 def __aiter__(self): return self
1042 def __anext__(self): return None
1043 def aclose(self): pass
1044 def athrow(self, typ, val=None, tb=None): pass
1045
1046 class NonAGen2:
1047 def __aiter__(self): return self
1048 def __anext__(self): return None
1049 def aclose(self): pass
1050 def asend(self, value): return value
1051
1052 class NonAGen3:
1053 def aclose(self): pass
1054 def asend(self, value): return value
1055 def athrow(self, typ, val=None, tb=None): pass
1056
1057 non_samples = [
1058 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1059 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
1060 for x in non_samples:
1061 self.assertNotIsInstance(x, AsyncGenerator)
1062 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
1063
1064 class Gen:
1065 def __aiter__(self): return self
1066 async def __anext__(self): return None
1067 async def aclose(self): pass
1068 async def asend(self, value): return value
1069 async def athrow(self, typ, val=None, tb=None): pass
1070
1071 class MinimalAGen(AsyncGenerator):
1072 async def asend(self, value):
1073 return value
1074 async def athrow(self, typ, val=None, tb=None):
1075 await super().athrow(typ, val, tb)
1076
1077 async def gen():
1078 yield 1
1079
1080 samples = [gen(), Gen(), MinimalAGen()]
1081 for x in samples:
1082 self.assertIsInstance(x, AsyncIterator)
1083 self.assertIsInstance(x, AsyncGenerator)
1084 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1085 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1086
1087 def run_async(coro):
1088 result = None
1089 while True:
1090 try:
1091 coro.send(None)
1092 except StopIteration as ex:
1093 result = ex.args[0] if ex.args else None
1094 break
1095 return result
1096
1097 # mixin tests
1098 mgen = MinimalAGen()
1099 self.assertIs(mgen, mgen.__aiter__())
1100 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1101 self.assertEqual(2, run_async(mgen.asend(2)))
1102 self.assertIsNone(run_async(mgen.aclose()))
1103 with self.assertRaises(ValueError):
1104 run_async(mgen.athrow(ValueError))
1105
1106 class FailOnClose(AsyncGenerator):
1107 async def asend(self, value): return value
1108 async def athrow(self, *args): raise ValueError
1109
1110 with self.assertRaises(ValueError):
1111 run_async(FailOnClose().aclose())
1112
1113 class IgnoreGeneratorExit(AsyncGenerator):
1114 async def asend(self, value): return value
1115 async def athrow(self, *args): pass
1116
1117 with self.assertRaises(RuntimeError):
1118 run_async(IgnoreGeneratorExit().aclose())
1119
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001120 def test_Sized(self):
1121 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001122 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001123 (x for x in []),
1124 ]
1125 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001126 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001127 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001128 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001129 tuple(), list(), set(), frozenset(), dict(),
1130 dict().keys(), dict().items(), dict().values(),
1131 ]
1132 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001133 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001134 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001135 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001136 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001137
1138 def test_Container(self):
1139 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001140 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001141 (x for x in []),
1142 ]
1143 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001144 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001145 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001146 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001147 tuple(), list(), set(), frozenset(), dict(),
1148 dict().keys(), dict().items(),
1149 ]
1150 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001151 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001152 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001153 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001154 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001155
1156 def test_Callable(self):
1157 non_samples = [None, 42, 3.14, 1j,
1158 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001159 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001160 (x for x in []),
1161 ]
1162 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001163 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001164 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001165 samples = [lambda: None,
1166 type, int, object,
1167 len,
1168 list.append, [].append,
1169 ]
1170 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001171 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001172 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001173 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001174 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001175
1176 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001177 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001178 class C(B):
1179 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001180 self.assertTrue(issubclass(C, B))
1181 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001182
1183 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001184 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001185 class C:
1186 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001187 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001188 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001189 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001190
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001191class WithSet(MutableSet):
1192
1193 def __init__(self, it=()):
1194 self.data = set(it)
1195
1196 def __len__(self):
1197 return len(self.data)
1198
1199 def __iter__(self):
1200 return iter(self.data)
1201
1202 def __contains__(self, item):
1203 return item in self.data
1204
1205 def add(self, item):
1206 self.data.add(item)
1207
1208 def discard(self, item):
1209 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001210
Raymond Hettingerae650182009-01-28 23:33:59 +00001211class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001212
1213 # XXX For now, we only test some virtual inheritance properties.
1214 # We should also test the proper behavior of the collection ABCs
1215 # as real base classes or mix-in classes.
1216
1217 def test_Set(self):
1218 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001219 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001220 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001221 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001222 class MySet(Set):
1223 def __contains__(self, x):
1224 return False
1225 def __len__(self):
1226 return 0
1227 def __iter__(self):
1228 return iter([])
1229 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001230
Benjamin Peterson41181742008-07-02 20:22:54 +00001231 def test_hash_Set(self):
1232 class OneTwoThreeSet(Set):
1233 def __init__(self):
1234 self.contents = [1, 2, 3]
1235 def __contains__(self, x):
1236 return x in self.contents
1237 def __len__(self):
1238 return len(self.contents)
1239 def __iter__(self):
1240 return iter(self.contents)
1241 def __hash__(self):
1242 return self._hash()
1243 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001244 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001245
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001246 def test_isdisjoint_Set(self):
1247 class MySet(Set):
1248 def __init__(self, itr):
1249 self.contents = itr
1250 def __contains__(self, x):
1251 return x in self.contents
1252 def __iter__(self):
1253 return iter(self.contents)
1254 def __len__(self):
1255 return len([x for x in self.contents])
1256 s1 = MySet((1, 2, 3))
1257 s2 = MySet((4, 5, 6))
1258 s3 = MySet((1, 5, 6))
1259 self.assertTrue(s1.isdisjoint(s2))
1260 self.assertFalse(s1.isdisjoint(s3))
1261
1262 def test_equality_Set(self):
1263 class MySet(Set):
1264 def __init__(self, itr):
1265 self.contents = itr
1266 def __contains__(self, x):
1267 return x in self.contents
1268 def __iter__(self):
1269 return iter(self.contents)
1270 def __len__(self):
1271 return len([x for x in self.contents])
1272 s1 = MySet((1,))
1273 s2 = MySet((1, 2))
1274 s3 = MySet((3, 4))
1275 s4 = MySet((3, 4))
1276 self.assertTrue(s2 > s1)
1277 self.assertTrue(s1 < s2)
1278 self.assertFalse(s2 <= s1)
1279 self.assertFalse(s2 <= s3)
1280 self.assertFalse(s1 >= s2)
1281 self.assertEqual(s3, s4)
1282 self.assertNotEqual(s2, s3)
1283
1284 def test_arithmetic_Set(self):
1285 class MySet(Set):
1286 def __init__(self, itr):
1287 self.contents = itr
1288 def __contains__(self, x):
1289 return x in self.contents
1290 def __iter__(self):
1291 return iter(self.contents)
1292 def __len__(self):
1293 return len([x for x in self.contents])
1294 s1 = MySet((1, 2, 3))
1295 s2 = MySet((3, 4, 5))
1296 s3 = s1 & s2
1297 self.assertEqual(s3, MySet((3,)))
1298
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001299 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001300 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001301 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001302 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001303 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001304 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1305 'add', 'discard')
1306
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001307 def test_issue_5647(self):
1308 # MutableSet.__iand__ mutated the set during iteration
1309 s = WithSet('abcd')
1310 s &= WithSet('cdef') # This used to fail
1311 self.assertEqual(set(s), set('cd'))
1312
Raymond Hettingerae650182009-01-28 23:33:59 +00001313 def test_issue_4920(self):
1314 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001315 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001316 __slots__=['__s']
1317 def __init__(self,items=None):
1318 if items is None:
1319 items=[]
1320 self.__s=set(items)
1321 def __contains__(self,v):
1322 return v in self.__s
1323 def __iter__(self):
1324 return iter(self.__s)
1325 def __len__(self):
1326 return len(self.__s)
1327 def add(self,v):
1328 result=v not in self.__s
1329 self.__s.add(v)
1330 return result
1331 def discard(self,v):
1332 result=v in self.__s
1333 self.__s.discard(v)
1334 return result
1335 def __repr__(self):
1336 return "MySet(%s)" % repr(list(self))
1337 s = MySet([5,43,2,1])
1338 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001339
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001340 def test_issue8750(self):
1341 empty = WithSet()
1342 full = WithSet(range(10))
1343 s = WithSet(full)
1344 s -= s
1345 self.assertEqual(s, empty)
1346 s = WithSet(full)
1347 s ^= s
1348 self.assertEqual(s, empty)
1349 s = WithSet(full)
1350 s &= s
1351 self.assertEqual(s, full)
1352 s |= s
1353 self.assertEqual(s, full)
1354
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001355 def test_issue16373(self):
1356 # Recursion error comparing comparable and noncomparable
1357 # Set instances
1358 class MyComparableSet(Set):
1359 def __contains__(self, x):
1360 return False
1361 def __len__(self):
1362 return 0
1363 def __iter__(self):
1364 return iter([])
1365 class MyNonComparableSet(Set):
1366 def __contains__(self, x):
1367 return False
1368 def __len__(self):
1369 return 0
1370 def __iter__(self):
1371 return iter([])
1372 def __le__(self, x):
1373 return NotImplemented
1374 def __lt__(self, x):
1375 return NotImplemented
1376
1377 cs = MyComparableSet()
1378 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001379 self.assertFalse(ncs < cs)
1380 self.assertTrue(ncs <= cs)
1381 self.assertFalse(ncs > cs)
1382 self.assertTrue(ncs >= cs)
1383
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001384 def test_issue26915(self):
1385 # Container membership test should check identity first
1386 class CustomEqualObject:
1387 def __eq__(self, other):
1388 return False
Xiang Zhangd5d32492017-03-08 11:04:24 +08001389 class CustomSequence(Sequence):
1390 def __init__(self, seq):
1391 self._seq = seq
1392 def __getitem__(self, index):
1393 return self._seq[index]
1394 def __len__(self):
1395 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001396
1397 nan = float('nan')
1398 obj = CustomEqualObject()
Xiang Zhangd5d32492017-03-08 11:04:24 +08001399 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001400 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001401 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001402 ItemsView({1: nan, 2: obj}),
1403 ValuesView({1: nan, 2: obj})
1404 ]
1405 for container in containers:
1406 for elem in container:
1407 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001408 self.assertEqual(seq.index(nan), 0)
1409 self.assertEqual(seq.index(obj), 1)
1410 self.assertEqual(seq.count(nan), 2)
1411 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001412
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001413 def assertSameSet(self, s1, s2):
1414 # coerce both to a real set then check equality
1415 self.assertSetEqual(set(s1), set(s2))
1416
1417 def test_Set_interoperability_with_real_sets(self):
1418 # Issue: 8743
1419 class ListSet(Set):
1420 def __init__(self, elements=()):
1421 self.data = []
1422 for elem in elements:
1423 if elem not in self.data:
1424 self.data.append(elem)
1425 def __contains__(self, elem):
1426 return elem in self.data
1427 def __iter__(self):
1428 return iter(self.data)
1429 def __len__(self):
1430 return len(self.data)
1431 def __repr__(self):
1432 return 'Set({!r})'.format(self.data)
1433
1434 r1 = set('abc')
1435 r2 = set('bcd')
1436 r3 = set('abcde')
1437 f1 = ListSet('abc')
1438 f2 = ListSet('bcd')
1439 f3 = ListSet('abcde')
1440 l1 = list('abccba')
1441 l2 = list('bcddcb')
1442 l3 = list('abcdeedcba')
1443
1444 target = r1 & r2
1445 self.assertSameSet(f1 & f2, target)
1446 self.assertSameSet(f1 & r2, target)
1447 self.assertSameSet(r2 & f1, target)
1448 self.assertSameSet(f1 & l2, target)
1449
1450 target = r1 | r2
1451 self.assertSameSet(f1 | f2, target)
1452 self.assertSameSet(f1 | r2, target)
1453 self.assertSameSet(r2 | f1, target)
1454 self.assertSameSet(f1 | l2, target)
1455
1456 fwd_target = r1 - r2
1457 rev_target = r2 - r1
1458 self.assertSameSet(f1 - f2, fwd_target)
1459 self.assertSameSet(f2 - f1, rev_target)
1460 self.assertSameSet(f1 - r2, fwd_target)
1461 self.assertSameSet(f2 - r1, rev_target)
1462 self.assertSameSet(r1 - f2, fwd_target)
1463 self.assertSameSet(r2 - f1, rev_target)
1464 self.assertSameSet(f1 - l2, fwd_target)
1465 self.assertSameSet(f2 - l1, rev_target)
1466
1467 target = r1 ^ r2
1468 self.assertSameSet(f1 ^ f2, target)
1469 self.assertSameSet(f1 ^ r2, target)
1470 self.assertSameSet(r2 ^ f1, target)
1471 self.assertSameSet(f1 ^ l2, target)
1472
1473 # Don't change the following to use assertLess or other
1474 # "more specific" unittest assertions. The current
1475 # assertTrue/assertFalse style makes the pattern of test
1476 # case combinations clear and allows us to know for sure
1477 # the exact operator being invoked.
1478
1479 # proper subset
1480 self.assertTrue(f1 < f3)
1481 self.assertFalse(f1 < f1)
1482 self.assertFalse(f1 < f2)
1483 self.assertTrue(r1 < f3)
1484 self.assertFalse(r1 < f1)
1485 self.assertFalse(r1 < f2)
1486 self.assertTrue(r1 < r3)
1487 self.assertFalse(r1 < r1)
1488 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001489 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001490 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001491 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001492 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001493 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001494 f1 < l2
1495
1496 # any subset
1497 self.assertTrue(f1 <= f3)
1498 self.assertTrue(f1 <= f1)
1499 self.assertFalse(f1 <= f2)
1500 self.assertTrue(r1 <= f3)
1501 self.assertTrue(r1 <= f1)
1502 self.assertFalse(r1 <= f2)
1503 self.assertTrue(r1 <= r3)
1504 self.assertTrue(r1 <= r1)
1505 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001506 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001507 f1 <= l3
1508 with self.assertRaises(TypeError):
1509 f1 <= l1
1510 with self.assertRaises(TypeError):
1511 f1 <= l2
1512
1513 # proper superset
1514 self.assertTrue(f3 > f1)
1515 self.assertFalse(f1 > f1)
1516 self.assertFalse(f2 > f1)
1517 self.assertTrue(r3 > r1)
1518 self.assertFalse(f1 > r1)
1519 self.assertFalse(f2 > r1)
1520 self.assertTrue(r3 > r1)
1521 self.assertFalse(r1 > r1)
1522 self.assertFalse(r2 > r1)
1523 with self.assertRaises(TypeError):
1524 f1 > l3
1525 with self.assertRaises(TypeError):
1526 f1 > l1
1527 with self.assertRaises(TypeError):
1528 f1 > l2
1529
1530 # any superset
1531 self.assertTrue(f3 >= f1)
1532 self.assertTrue(f1 >= f1)
1533 self.assertFalse(f2 >= f1)
1534 self.assertTrue(r3 >= r1)
1535 self.assertTrue(f1 >= r1)
1536 self.assertFalse(f2 >= r1)
1537 self.assertTrue(r3 >= r1)
1538 self.assertTrue(r1 >= r1)
1539 self.assertFalse(r2 >= r1)
1540 with self.assertRaises(TypeError):
1541 f1 >= l3
1542 with self.assertRaises(TypeError):
1543 f1 >=l1
1544 with self.assertRaises(TypeError):
1545 f1 >= l2
1546
1547 # equality
1548 self.assertTrue(f1 == f1)
1549 self.assertTrue(r1 == f1)
1550 self.assertTrue(f1 == r1)
1551 self.assertFalse(f1 == f3)
1552 self.assertFalse(r1 == f3)
1553 self.assertFalse(f1 == r3)
1554 self.assertFalse(f1 == l3)
1555 self.assertFalse(f1 == l1)
1556 self.assertFalse(f1 == l2)
1557
1558 # inequality
1559 self.assertFalse(f1 != f1)
1560 self.assertFalse(r1 != f1)
1561 self.assertFalse(f1 != r1)
1562 self.assertTrue(f1 != f3)
1563 self.assertTrue(r1 != f3)
1564 self.assertTrue(f1 != r3)
1565 self.assertTrue(f1 != l3)
1566 self.assertTrue(f1 != l1)
1567 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001568
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001569 def test_Mapping(self):
1570 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001571 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001572 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001573 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1574 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001575 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001576 def __len__(self):
1577 return 0
1578 def __getitem__(self, i):
1579 raise IndexError
1580 def __iter__(self):
1581 return iter(())
1582 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001583 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001584
1585 def test_MutableMapping(self):
1586 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001587 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001588 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001589 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1590 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001591
Raymond Hettinger9117c752010-08-22 07:44:24 +00001592 def test_MutableMapping_subclass(self):
1593 # Test issue 9214
1594 mymap = UserDict()
1595 mymap['red'] = 5
1596 self.assertIsInstance(mymap.keys(), Set)
1597 self.assertIsInstance(mymap.keys(), KeysView)
1598 self.assertIsInstance(mymap.items(), Set)
1599 self.assertIsInstance(mymap.items(), ItemsView)
1600
1601 mymap = UserDict()
1602 mymap['red'] = 5
1603 z = mymap.keys() | {'orange'}
1604 self.assertIsInstance(z, set)
1605 list(z)
1606 mymap['blue'] = 7 # Shouldn't affect 'z'
1607 self.assertEqual(sorted(z), ['orange', 'red'])
1608
1609 mymap = UserDict()
1610 mymap['red'] = 5
1611 z = mymap.items() | {('orange', 3)}
1612 self.assertIsInstance(z, set)
1613 list(z)
1614 mymap['blue'] = 7 # Shouldn't affect 'z'
1615 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1616
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001617 def test_Sequence(self):
1618 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001619 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001620 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001621 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001622 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001623 self.assertIsInstance(memoryview(b""), Sequence)
1624 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001625 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001626 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1627 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001628
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001629 def test_Sequence_mixins(self):
1630 class SequenceSubclass(Sequence):
1631 def __init__(self, seq=()):
1632 self.seq = seq
1633
1634 def __getitem__(self, index):
1635 return self.seq[index]
1636
1637 def __len__(self):
1638 return len(self.seq)
1639
1640 # Compare Sequence.index() behavior to (list|str).index() behavior
1641 def assert_index_same(seq1, seq2, index_args):
1642 try:
1643 expected = seq1.index(*index_args)
1644 except ValueError:
1645 with self.assertRaises(ValueError):
1646 seq2.index(*index_args)
1647 else:
1648 actual = seq2.index(*index_args)
1649 self.assertEqual(
1650 actual, expected, '%r.index%s' % (seq1, index_args))
1651
1652 for ty in list, str:
1653 nativeseq = ty('abracadabra')
1654 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1655 seqseq = SequenceSubclass(nativeseq)
1656 for letter in set(nativeseq) | {'z'}:
1657 assert_index_same(nativeseq, seqseq, (letter,))
1658 for start in range(-3, len(nativeseq) + 3):
1659 assert_index_same(nativeseq, seqseq, (letter, start))
1660 for stop in range(-3, len(nativeseq) + 3):
1661 assert_index_same(
1662 nativeseq, seqseq, (letter, start, stop))
1663
Guido van Rossumd05eb002007-11-21 22:26:24 +00001664 def test_ByteString(self):
1665 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001666 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001667 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001668 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001669 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001670 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001671 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001672 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001673
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001674 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001675 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001676 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001677 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001678 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001679 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001680 self.assertTrue(issubclass(sample, MutableSequence))
1681 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001682 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1683 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001684
Eli Bendersky0716a572011-03-04 10:38:14 +00001685 def test_MutableSequence_mixins(self):
Mike53f7a7c2017-12-14 14:04:53 +03001686 # Test the mixins of MutableSequence by creating a minimal concrete
Eli Bendersky0716a572011-03-04 10:38:14 +00001687 # class inherited from it.
1688 class MutableSequenceSubclass(MutableSequence):
1689 def __init__(self):
1690 self.lst = []
1691
1692 def __setitem__(self, index, value):
1693 self.lst[index] = value
1694
1695 def __getitem__(self, index):
1696 return self.lst[index]
1697
1698 def __len__(self):
1699 return len(self.lst)
1700
1701 def __delitem__(self, index):
1702 del self.lst[index]
1703
1704 def insert(self, index, value):
1705 self.lst.insert(index, value)
1706
1707 mss = MutableSequenceSubclass()
1708 mss.append(0)
1709 mss.extend((1, 2, 3, 4))
1710 self.assertEqual(len(mss), 5)
1711 self.assertEqual(mss[3], 3)
1712 mss.reverse()
1713 self.assertEqual(mss[3], 1)
1714 mss.pop()
1715 self.assertEqual(len(mss), 4)
1716 mss.remove(3)
1717 self.assertEqual(len(mss), 3)
1718 mss += (10, 20, 30)
1719 self.assertEqual(len(mss), 6)
1720 self.assertEqual(mss[-1], 30)
1721 mss.clear()
1722 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001723
1724################################################################################
1725### Counter
1726################################################################################
1727
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001728class CounterSubclassWithSetItem(Counter):
1729 # Test a counter subclass that overrides __setitem__
1730 def __init__(self, *args, **kwds):
1731 self.called = False
1732 Counter.__init__(self, *args, **kwds)
1733 def __setitem__(self, key, value):
1734 self.called = True
1735 Counter.__setitem__(self, key, value)
1736
1737class CounterSubclassWithGet(Counter):
1738 # Test a counter subclass that overrides get()
1739 def __init__(self, *args, **kwds):
1740 self.called = False
1741 Counter.__init__(self, *args, **kwds)
1742 def get(self, key, default):
1743 self.called = True
1744 return Counter.get(self, key, default)
1745
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001746class TestCounter(unittest.TestCase):
1747
1748 def test_basics(self):
1749 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001750 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1751 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001752 self.assertIsInstance(c, dict)
1753 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001754 self.assertTrue(issubclass(Counter, dict))
1755 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001756 self.assertEqual(len(c), 3)
1757 self.assertEqual(sum(c.values()), 6)
1758 self.assertEqual(sorted(c.values()), [1, 2, 3])
1759 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1760 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1761 self.assertEqual(sorted(c.items()),
1762 [('a', 3), ('b', 2), ('c', 1)])
1763 self.assertEqual(c['b'], 2)
1764 self.assertEqual(c['z'], 0)
1765 self.assertEqual(c.__contains__('c'), True)
1766 self.assertEqual(c.__contains__('z'), False)
1767 self.assertEqual(c.get('b', 10), 2)
1768 self.assertEqual(c.get('z', 10), 10)
1769 self.assertEqual(c, dict(a=3, b=2, c=1))
1770 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1771 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1772 for i in range(5):
1773 self.assertEqual(c.most_common(i),
1774 [('a', 3), ('b', 2), ('c', 1)][:i])
1775 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1776 c['a'] += 1 # increment an existing value
1777 c['b'] -= 2 # sub existing value to zero
1778 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001779 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001780 c['d'] -= 2 # sub from a missing value
1781 c['e'] = -5 # directly assign a missing value
1782 c['f'] += 4 # add to a missing value
1783 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1784 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1785 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001786 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001787 for i in range(3):
1788 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001789 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001790 c.clear()
1791 self.assertEqual(c, {})
1792 self.assertEqual(repr(c), 'Counter()')
1793 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1794 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001795 c.update(dict(a=5, b=3))
1796 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001797 c.update(Counter('a' * 50 + 'b' * 30))
1798 c.update() # test case with no args
1799 c.__init__('a' * 500 + 'b' * 300)
1800 c.__init__('cdc')
1801 c.__init__()
1802 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1803 self.assertEqual(c.setdefault('d', 5), 1)
1804 self.assertEqual(c['d'], 1)
1805 self.assertEqual(c.setdefault('e', 5), 5)
1806 self.assertEqual(c['e'], 5)
1807
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001808 def test_init(self):
1809 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1810 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1811 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1812 self.assertRaises(TypeError, Counter, 42)
1813 self.assertRaises(TypeError, Counter, (), ())
1814 self.assertRaises(TypeError, Counter.__init__)
1815
1816 def test_update(self):
1817 c = Counter()
1818 c.update(self=42)
1819 self.assertEqual(list(c.items()), [('self', 42)])
1820 c = Counter()
1821 c.update(iterable=42)
1822 self.assertEqual(list(c.items()), [('iterable', 42)])
1823 c = Counter()
1824 c.update(iterable=None)
1825 self.assertEqual(list(c.items()), [('iterable', None)])
1826 self.assertRaises(TypeError, Counter().update, 42)
1827 self.assertRaises(TypeError, Counter().update, {}, {})
1828 self.assertRaises(TypeError, Counter.update)
1829
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001830 def test_copying(self):
1831 # Check that counters are copyable, deepcopyable, picklable, and
1832 #have a repr/eval round-trip
1833 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001834 def check(dup):
1835 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1836 self.assertIsNot(dup, words, msg)
1837 self.assertEqual(dup, words)
1838 check(words.copy())
1839 check(copy.copy(words))
1840 check(copy.deepcopy(words))
1841 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1842 with self.subTest(proto=proto):
1843 check(pickle.loads(pickle.dumps(words, proto)))
1844 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001845 update_test = Counter()
1846 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001847 check(update_test)
1848 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001849
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001850 def test_copy_subclass(self):
1851 class MyCounter(Counter):
1852 pass
1853 c = MyCounter('slartibartfast')
1854 d = c.copy()
1855 self.assertEqual(d, c)
1856 self.assertEqual(len(d), len(c))
1857 self.assertEqual(type(d), type(c))
1858
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001859 def test_conversions(self):
1860 # Convert to: set, list, dict
1861 s = 'she sells sea shells by the sea shore'
1862 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1863 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1864 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1865 self.assertEqual(set(Counter(s)), set(s))
1866
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001867 def test_invariant_for_the_in_operator(self):
1868 c = Counter(a=10, b=-2, c=0)
1869 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001870 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001871 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001872
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001873 def test_multiset_operations(self):
1874 # Verify that adding a zero counter will strip zeros and negatives
1875 c = Counter(a=10, b=-2, c=0) + Counter()
1876 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001877
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001878 elements = 'abcd'
1879 for i in range(1000):
1880 # test random pairs of multisets
1881 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001882 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001883 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001884 q.update(h=1, i=-1, j=0)
1885 for counterop, numberop in [
1886 (Counter.__add__, lambda x, y: max(0, x+y)),
1887 (Counter.__sub__, lambda x, y: max(0, x-y)),
1888 (Counter.__or__, lambda x, y: max(0,x,y)),
1889 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001890 ]:
1891 result = counterop(p, q)
1892 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001893 self.assertEqual(numberop(p[x], q[x]), result[x],
1894 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001895 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001896 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001897
1898 elements = 'abcdef'
1899 for i in range(100):
1900 # verify that random multisets with no repeats are exactly like sets
1901 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1902 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1903 for counterop, setop in [
1904 (Counter.__sub__, set.__sub__),
1905 (Counter.__or__, set.__or__),
1906 (Counter.__and__, set.__and__),
1907 ]:
1908 counter_result = counterop(p, q)
1909 set_result = setop(set(p.elements()), set(q.elements()))
1910 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001911
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001912 def test_inplace_operations(self):
1913 elements = 'abcd'
1914 for i in range(1000):
1915 # test random pairs of multisets
1916 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1917 p.update(e=1, f=-1, g=0)
1918 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1919 q.update(h=1, i=-1, j=0)
1920 for inplace_op, regular_op in [
1921 (Counter.__iadd__, Counter.__add__),
1922 (Counter.__isub__, Counter.__sub__),
1923 (Counter.__ior__, Counter.__or__),
1924 (Counter.__iand__, Counter.__and__),
1925 ]:
1926 c = p.copy()
1927 c_id = id(c)
1928 regular_result = regular_op(c, q)
1929 inplace_result = inplace_op(c, q)
1930 self.assertEqual(inplace_result, regular_result)
1931 self.assertEqual(id(inplace_result), c_id)
1932
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001933 def test_subtract(self):
1934 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1935 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1936 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1937 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1938 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1939 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1940 c = Counter('aaabbcd')
1941 c.subtract('aaaabbcce')
1942 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001943
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001944 c = Counter()
1945 c.subtract(self=42)
1946 self.assertEqual(list(c.items()), [('self', -42)])
1947 c = Counter()
1948 c.subtract(iterable=42)
1949 self.assertEqual(list(c.items()), [('iterable', -42)])
1950 self.assertRaises(TypeError, Counter().subtract, 42)
1951 self.assertRaises(TypeError, Counter().subtract, {}, {})
1952 self.assertRaises(TypeError, Counter.subtract)
1953
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001954 def test_unary(self):
1955 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1956 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1957 self.assertEqual(dict(-c), dict(a=5))
1958
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001959 def test_repr_nonsortable(self):
1960 c = Counter(a=2, b=None)
1961 r = repr(c)
1962 self.assertIn("'a': 2", r)
1963 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001964
Raymond Hettinger426e0522011-01-03 02:12:02 +00001965 def test_helper_function(self):
1966 # two paths, one for real dicts and one for other mappings
1967 elems = list('abracadabra')
1968
1969 d = dict()
1970 _count_elements(d, elems)
1971 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1972
1973 m = OrderedDict()
1974 _count_elements(m, elems)
1975 self.assertEqual(m,
1976 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1977
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001978 # test fidelity to the pure python version
1979 c = CounterSubclassWithSetItem('abracadabra')
1980 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001981 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001982 c = CounterSubclassWithGet('abracadabra')
1983 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001984 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001985
Raymond Hettinger499e1932011-02-23 07:56:53 +00001986
1987################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001988### Run tests
1989################################################################################
1990
Guido van Rossumd8faa362007-04-27 19:54:29 +00001991def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001992 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001993 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001994 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06001995 TestUserObjects,
1996 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001997 support.run_unittest(*test_classes)
1998 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001999
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002000
Guido van Rossumd8faa362007-04-27 19:54:29 +00002001if __name__ == "__main__":
2002 test_main(verbose=True)