blob: a55239e57302e72aeb24a6604d2903a95f4b2e76 [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
144 def test_dict_coercion(self):
145 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
146 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
147 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
148
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000149 def test_new_child(self):
150 'Tests for changes for issue #16613.'
151 c = ChainMap()
152 c['a'] = 1
153 c['b'] = 2
154 m = {'b':20, 'c': 30}
155 d = c.new_child(m)
156 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
157 self.assertIs(m, d.maps[0])
158
159 # Use a different map than a dict
160 class lowerdict(dict):
161 def __getitem__(self, key):
162 if isinstance(key, str):
163 key = key.lower()
164 return dict.__getitem__(self, key)
165 def __contains__(self, key):
166 if isinstance(key, str):
167 key = key.lower()
168 return dict.__contains__(self, key)
169
170 c = ChainMap()
171 c['a'] = 1
172 c['b'] = 2
173 m = lowerdict(b=20, c=30)
174 d = c.new_child(m)
175 self.assertIs(m, d.maps[0])
176 for key in 'abc': # check contains
177 self.assertIn(key, d)
178 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
179 self.assertEqual(d.get(k, 100), v)
180
Raymond Hettinger499e1932011-02-23 07:56:53 +0000181
182################################################################################
183### Named Tuples
184################################################################################
185
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000186TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000187
188class TestNamedTuple(unittest.TestCase):
189
190 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000191 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000192 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000193 self.assertEqual(Point.__slots__, ())
194 self.assertEqual(Point.__module__, __name__)
195 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000196 self.assertEqual(Point._fields, ('x', 'y'))
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000197
198 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
199 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
200 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
201
202 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
203 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
204 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000205 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000206 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
207
208 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000209 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000210
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000211 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000212 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000213 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000214 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000215
Christian Heimesfaf2f632008-01-06 16:59:19 +0000216 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
217 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
218
Raymond Hettinger39482072018-01-10 21:45:19 -0800219 def test_defaults(self):
220 Point = namedtuple('Point', 'x y', defaults=(10, 20)) # 2 defaults
221 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
222 self.assertEqual(Point(1, 2), (1, 2))
223 self.assertEqual(Point(1), (1, 20))
224 self.assertEqual(Point(), (10, 20))
225
226 Point = namedtuple('Point', 'x y', defaults=(20,)) # 1 default
227 self.assertEqual(Point._fields_defaults, {'y': 20})
228 self.assertEqual(Point(1, 2), (1, 2))
229 self.assertEqual(Point(1), (1, 20))
230
231 Point = namedtuple('Point', 'x y', defaults=()) # 0 defaults
232 self.assertEqual(Point._fields_defaults, {})
233 self.assertEqual(Point(1, 2), (1, 2))
234 with self.assertRaises(TypeError):
235 Point(1)
236
237 with self.assertRaises(TypeError): # catch too few args
238 Point()
239 with self.assertRaises(TypeError): # catch too many args
240 Point(1, 2, 3)
241 with self.assertRaises(TypeError): # too many defaults
242 Point = namedtuple('Point', 'x y', defaults=(10, 20, 30))
243 with self.assertRaises(TypeError): # non-iterable defaults
244 Point = namedtuple('Point', 'x y', defaults=10)
245 with self.assertRaises(TypeError): # another non-iterable default
246 Point = namedtuple('Point', 'x y', defaults=False)
247
248 Point = namedtuple('Point', 'x y', defaults=None) # default is None
249 self.assertEqual(Point._fields_defaults, {})
250 self.assertIsNone(Point.__new__.__defaults__, None)
251 self.assertEqual(Point(10, 20), (10, 20))
252 with self.assertRaises(TypeError): # catch too few args
253 Point(10)
254
255 Point = namedtuple('Point', 'x y', defaults=[10, 20]) # allow non-tuple iterable
256 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
257 self.assertEqual(Point.__new__.__defaults__, (10, 20))
258 self.assertEqual(Point(1, 2), (1, 2))
259 self.assertEqual(Point(1), (1, 20))
260 self.assertEqual(Point(), (10, 20))
261
262 Point = namedtuple('Point', 'x y', defaults=iter([10, 20])) # allow plain iterator
263 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
264 self.assertEqual(Point.__new__.__defaults__, (10, 20))
265 self.assertEqual(Point(1, 2), (1, 2))
266 self.assertEqual(Point(1), (1, 20))
267 self.assertEqual(Point(), (10, 20))
268
269
R. David Murray378c0cf2010-02-24 01:46:21 +0000270 @unittest.skipIf(sys.flags.optimize >= 2,
271 "Docstrings are omitted with -O2 and above")
272 def test_factory_doc_attr(self):
273 Point = namedtuple('Point', 'x y')
274 self.assertEqual(Point.__doc__, 'Point(x, y)')
275
Raymond Hettingereac503a2015-05-13 01:09:59 -0700276 @unittest.skipIf(sys.flags.optimize >= 2,
277 "Docstrings are omitted with -O2 and above")
278 def test_doc_writable(self):
279 Point = namedtuple('Point', 'x y')
280 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
281 Point.x.__doc__ = 'docstring for Point.x'
282 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
283
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000284 def test_name_fixer(self):
285 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000286 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
287 [('abc', 'class'), ('abc', '_1')], # field has keyword
288 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
289 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
290 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
291 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000292 ]:
293 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
294
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700295 def test_module_parameter(self):
296 NT = namedtuple('NT', ['x', 'y'], module=collections)
297 self.assertEqual(NT.__module__, collections)
298
Guido van Rossumd8faa362007-04-27 19:54:29 +0000299 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000300 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000301 p = Point(11, 22)
302 self.assertEqual(p, Point(x=11, y=22))
303 self.assertEqual(p, Point(11, y=22))
304 self.assertEqual(p, Point(y=22, x=11))
305 self.assertEqual(p, Point(*(11, 22)))
306 self.assertEqual(p, Point(**dict(x=11, y=22)))
307 self.assertRaises(TypeError, Point, 1) # too few args
308 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
309 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
310 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
311 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000312 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000313 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000314 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
315 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700316 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000317
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000318 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000319 p._replace(x=1, error=2)
320 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000321 pass
322 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000323 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000324
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000325 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000326 Point = namedtuple('Point', 'x, y')
327 p = Point(x=11, y=22)
328 self.assertEqual(repr(p), 'Point(x=11, y=22)')
329
330 # verify that fieldspec can be a non-string sequence
331 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000332 p = Point(x=11, y=22)
333 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000334
335 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000336 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000337 p = Point(11, 22)
338
Ezio Melottie9615932010-01-24 19:26:24 +0000339 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000340 self.assertEqual(p, (11, 22)) # matches a real tuple
341 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
342 self.assertEqual(list(p), [11, 22]) # coercable to a list
343 self.assertEqual(max(p), 22) # iterable
344 self.assertEqual(max(*p), 22) # star-able
345 x, y = p
346 self.assertEqual(p, (x, y)) # unpacks like a tuple
347 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
348 self.assertRaises(IndexError, p.__getitem__, 3)
349
350 self.assertEqual(p.x, x)
351 self.assertEqual(p.y, y)
352 self.assertRaises(AttributeError, eval, 'p.z', locals())
353
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000354 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000355 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000356 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000357 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000358 self.assertEqual(repr(Zero()), 'Zero()')
359 self.assertEqual(Zero()._asdict(), {})
360 self.assertEqual(Zero()._fields, ())
361
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000362 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000363 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000364 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000365 self.assertEqual(Dot(1).d, 1)
366 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
367 self.assertEqual(Dot(1)._asdict(), {'d':1})
368 self.assertEqual(Dot(1)._replace(d=999), (999,))
369 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000370
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200371 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200372 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000373 for j in range(10)]) for i in range(n)))
374 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000375 Big = namedtuple('Big', names)
376 b = Big(*range(n))
377 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000378 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000379 for pos, name in enumerate(names):
380 self.assertEqual(getattr(b, name), pos)
381 repr(b) # make sure repr() doesn't blow-up
382 d = b._asdict()
383 d_expected = dict(zip(names, range(n)))
384 self.assertEqual(d, d_expected)
385 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
386 b2_expected = list(range(n))
387 b2_expected[1] = 999
388 b2_expected[-5] = 42
389 self.assertEqual(b2, tuple(b2_expected))
390 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000391
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000392 def test_pickle(self):
393 p = TestNT(x=10, y=20, z=30)
394 for module in (pickle,):
395 loads = getattr(module, 'loads')
396 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500397 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000398 q = loads(dumps(p, protocol))
399 self.assertEqual(p, q)
400 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700401 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000402
403 def test_copy(self):
404 p = TestNT(x=10, y=20, z=30)
405 for copier in copy.copy, copy.deepcopy:
406 q = copier(p)
407 self.assertEqual(p, q)
408 self.assertEqual(p._fields, q._fields)
409
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000410 def test_name_conflicts(self):
411 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
412 # failed when used as field names. Test to make sure these now work.
413 T = namedtuple('T', 'itemgetter property self cls tuple')
414 t = T(1, 2, 3, 4, 5)
415 self.assertEqual(t, (1,2,3,4,5))
416 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
417 self.assertEqual(newt, (10,20,30,40,50))
418
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700419 # Broader test of all interesting names taken from the code, old
420 # template, and an example
421 words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create',
422 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper',
423 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note',
424 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError',
425 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add',
426 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments',
427 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot',
428 'class_namespace', 'classmethod', 'cls', 'collections', 'convert',
429 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict',
430 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect',
431 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f',
432 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame',
433 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater',
434 'has', 'help', 'identifiers', 'index', 'indexable', 'instance',
435 'instantiate', 'interning', 'introspection', 'isidentifier',
436 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords',
437 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata',
438 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named',
439 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new',
440 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option',
441 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional',
442 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr',
443 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen',
444 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start',
445 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys',
446 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new',
447 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use',
448 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where',
449 'which', 'work', 'x', 'y', 'z', 'zip'}
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000450 T = namedtuple('T', words)
451 # test __new__
452 values = tuple(range(len(words)))
453 t = T(*values)
454 self.assertEqual(t, values)
455 t = T(**dict(zip(T._fields, values)))
456 self.assertEqual(t, values)
457 # test _make
458 t = T._make(values)
459 self.assertEqual(t, values)
460 # exercise __repr__
461 repr(t)
462 # test _asdict
463 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
464 # test _replace
465 t = T._make(values)
466 newvalues = tuple(v*10 for v in values)
467 newt = t._replace(**dict(zip(T._fields, newvalues)))
468 self.assertEqual(newt, newvalues)
469 # test _fields
470 self.assertEqual(T._fields, tuple(words))
471 # test __getnewargs__
472 self.assertEqual(t.__getnewargs__(), values)
473
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000474 def test_repr(self):
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700475 A = namedtuple('A', 'x')
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000476 self.assertEqual(repr(A(1)), 'A(x=1)')
477 # repr should show the name of the subclass
478 class B(A):
479 pass
480 self.assertEqual(repr(B(1)), 'B(x=1)')
481
Raymond Hettinger6538b432016-08-16 10:55:43 -0700482 def test_keyword_only_arguments(self):
483 # See issue 25628
Raymond Hettinger6538b432016-08-16 10:55:43 -0700484 with self.assertRaises(TypeError):
485 NT = namedtuple('NT', ['x', 'y'], True)
486
487 NT = namedtuple('NT', ['abc', 'def'], rename=True)
488 self.assertEqual(NT._fields, ('abc', '_1'))
489 with self.assertRaises(TypeError):
490 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000491
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700492 def test_namedtuple_subclass_issue_24931(self):
493 class Point(namedtuple('_Point', ['x', 'y'])):
494 pass
495
496 a = Point(3, 4)
497 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
498
499 a.w = 5
500 self.assertEqual(a.__dict__, {'w': 5})
501
502
Raymond Hettinger499e1932011-02-23 07:56:53 +0000503################################################################################
504### Abstract Base Classes
505################################################################################
506
Raymond Hettingerae650182009-01-28 23:33:59 +0000507class ABCTestCase(unittest.TestCase):
508
509 def validate_abstract_methods(self, abc, *names):
510 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
511
512 # everything should work will all required methods are present
513 C = type('C', (abc,), methodstubs)
514 C()
515
516 # instantiation should fail if a required method is missing
517 for name in names:
518 stubs = methodstubs.copy()
519 del stubs[name]
520 C = type('C', (abc,), stubs)
521 self.assertRaises(TypeError, C, name)
522
Florent Xiclunace153f62010-03-08 15:34:35 +0000523 def validate_isinstance(self, abc, name):
524 stub = lambda s, *args: 0
525
526 C = type('C', (object,), {'__hash__': None})
527 setattr(C, name, stub)
528 self.assertIsInstance(C(), abc)
529 self.assertTrue(issubclass(C, abc))
530
531 C = type('C', (object,), {'__hash__': None})
532 self.assertNotIsInstance(C(), abc)
533 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000534
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000535 def validate_comparison(self, instance):
536 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
537 operators = {}
538 for op in ops:
539 name = '__' + op + '__'
540 operators[name] = getattr(operator, name)
541
542 class Other:
543 def __init__(self):
544 self.right_side = False
545 def __eq__(self, other):
546 self.right_side = True
547 return True
548 __lt__ = __eq__
549 __gt__ = __eq__
550 __le__ = __eq__
551 __ge__ = __eq__
552 __ne__ = __eq__
553 __ror__ = __eq__
554 __rand__ = __eq__
555 __rxor__ = __eq__
556 __rsub__ = __eq__
557
558 for name, op in operators.items():
559 if not hasattr(instance, name):
560 continue
561 other = Other()
562 op(instance, other)
563 self.assertTrue(other.right_side,'Right side not called for %s.%s'
564 % (type(instance), name))
565
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700566def _test_gen():
567 yield
568
Raymond Hettingerae650182009-01-28 23:33:59 +0000569class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000570
Yury Selivanov75445082015-05-11 22:57:16 -0400571 def test_Awaitable(self):
572 def gen():
573 yield
574
575 @types.coroutine
576 def coro():
577 yield
578
579 async def new_coro():
580 pass
581
582 class Bar:
583 def __await__(self):
584 yield
585
586 class MinimalCoro(Coroutine):
587 def send(self, value):
588 return value
589 def throw(self, typ, val=None, tb=None):
590 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400591 def __await__(self):
592 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400593
594 non_samples = [None, int(), gen(), object()]
595 for x in non_samples:
596 self.assertNotIsInstance(x, Awaitable)
597 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
598
599 samples = [Bar(), MinimalCoro()]
600 for x in samples:
601 self.assertIsInstance(x, Awaitable)
602 self.assertTrue(issubclass(type(x), Awaitable))
603
604 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400605 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
606 # flag don't have '__await__' method, hence can't be instances
607 # of Awaitable. Use inspect.isawaitable to detect them.
608 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400609
610 c = new_coro()
611 self.assertIsInstance(c, Awaitable)
Mike53f7a7c2017-12-14 14:04:53 +0300612 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400613
Yury Selivanov56fc6142015-05-29 09:01:29 -0400614 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400615 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400616 self.assertTrue(isinstance(CoroLike(), Awaitable))
617 self.assertTrue(issubclass(CoroLike, Awaitable))
618 CoroLike = None
619 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400620
Yury Selivanov75445082015-05-11 22:57:16 -0400621 def test_Coroutine(self):
622 def gen():
623 yield
624
625 @types.coroutine
626 def coro():
627 yield
628
629 async def new_coro():
630 pass
631
632 class Bar:
633 def __await__(self):
634 yield
635
636 class MinimalCoro(Coroutine):
637 def send(self, value):
638 return value
639 def throw(self, typ, val=None, tb=None):
640 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400641 def __await__(self):
642 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400643
644 non_samples = [None, int(), gen(), object(), Bar()]
645 for x in non_samples:
646 self.assertNotIsInstance(x, Coroutine)
647 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
648
649 samples = [MinimalCoro()]
650 for x in samples:
651 self.assertIsInstance(x, Awaitable)
652 self.assertTrue(issubclass(type(x), Awaitable))
653
654 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400655 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
656 # flag don't have '__await__' method, hence can't be instances
657 # of Coroutine. Use inspect.isawaitable to detect them.
658 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400659
660 c = new_coro()
661 self.assertIsInstance(c, Coroutine)
Mike53f7a7c2017-12-14 14:04:53 +0300662 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400663
Yury Selivanov56fc6142015-05-29 09:01:29 -0400664 class CoroLike:
665 def send(self, value):
666 pass
667 def throw(self, typ, val=None, tb=None):
668 pass
669 def close(self):
670 pass
671 def __await__(self):
672 pass
673 self.assertTrue(isinstance(CoroLike(), Coroutine))
674 self.assertTrue(issubclass(CoroLike, Coroutine))
675
676 class CoroLike:
677 def send(self, value):
678 pass
679 def close(self):
680 pass
681 def __await__(self):
682 pass
683 self.assertFalse(isinstance(CoroLike(), Coroutine))
684 self.assertFalse(issubclass(CoroLike, Coroutine))
685
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000686 def test_Hashable(self):
687 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000688 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000689 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000690 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000691 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000692 # Check some hashables
693 samples = [None,
694 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000695 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000696 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000697 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000698 ]
699 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000700 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000701 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000702 self.assertRaises(TypeError, Hashable)
703 # Check direct subclassing
704 class H(Hashable):
705 def __hash__(self):
706 return super().__hash__()
707 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000708 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000709 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000710 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000711
Yury Selivanove0104ae2015-05-14 12:19:16 -0400712 def test_AsyncIterable(self):
713 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400714 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400715 return self
716 self.assertTrue(isinstance(AI(), AsyncIterable))
717 self.assertTrue(issubclass(AI, AsyncIterable))
718 # Check some non-iterables
719 non_samples = [None, object, []]
720 for x in non_samples:
721 self.assertNotIsInstance(x, AsyncIterable)
722 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
723 self.validate_abstract_methods(AsyncIterable, '__aiter__')
724 self.validate_isinstance(AsyncIterable, '__aiter__')
725
726 def test_AsyncIterator(self):
727 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400728 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400729 return self
730 async def __anext__(self):
731 raise StopAsyncIteration
732 self.assertTrue(isinstance(AI(), AsyncIterator))
733 self.assertTrue(issubclass(AI, AsyncIterator))
734 non_samples = [None, object, []]
735 # Check some non-iterables
736 for x in non_samples:
737 self.assertNotIsInstance(x, AsyncIterator)
738 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
739 # Similarly to regular iterators (see issue 10565)
740 class AnextOnly:
741 async def __anext__(self):
742 raise StopAsyncIteration
743 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
744 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
745
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000746 def test_Iterable(self):
747 # Check some non-iterables
748 non_samples = [None, 42, 3.14, 1j]
749 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000750 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000751 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000752 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000753 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000754 tuple(), list(), set(), frozenset(), dict(),
755 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700756 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000757 (x for x in []),
758 ]
759 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000760 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000761 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000762 # Check direct subclassing
763 class I(Iterable):
764 def __iter__(self):
765 return super().__iter__()
766 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000767 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000768 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000769 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700770 # Check None blocking
771 class It:
772 def __iter__(self): return iter([])
773 class ItBlocked(It):
774 __iter__ = None
775 self.assertTrue(issubclass(It, Iterable))
776 self.assertTrue(isinstance(It(), Iterable))
777 self.assertFalse(issubclass(ItBlocked, Iterable))
778 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000779
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700780 def test_Reversible(self):
781 # Check some non-reversibles
782 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()]
783 for x in non_samples:
784 self.assertNotIsInstance(x, Reversible)
785 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700786 # Check some non-reversible iterables
787 non_reversibles = [dict().keys(), dict().items(), dict().values(),
788 Counter(), Counter().keys(), Counter().items(),
789 Counter().values(), _test_gen(),
790 (x for x in []), iter([]), reversed([])]
791 for x in non_reversibles:
792 self.assertNotIsInstance(x, Reversible)
793 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
794 # Check some reversible iterables
795 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
796 OrderedDict().keys(), OrderedDict().items(),
797 OrderedDict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700798 for x in samples:
799 self.assertIsInstance(x, Reversible)
800 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
801 # Check also Mapping, MutableMapping, and Sequence
802 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
803 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
804 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
805 # Check direct subclassing
806 class R(Reversible):
807 def __iter__(self):
808 return iter(list())
809 def __reversed__(self):
810 return iter(list())
811 self.assertEqual(list(reversed(R())), [])
812 self.assertFalse(issubclass(float, R))
813 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700814 # Check reversible non-iterable (which is not Reversible)
815 class RevNoIter:
816 def __reversed__(self): return reversed([])
817 class RevPlusIter(RevNoIter):
818 def __iter__(self): return iter([])
819 self.assertFalse(issubclass(RevNoIter, Reversible))
820 self.assertFalse(isinstance(RevNoIter(), Reversible))
821 self.assertTrue(issubclass(RevPlusIter, Reversible))
822 self.assertTrue(isinstance(RevPlusIter(), Reversible))
823 # Check None blocking
824 class Rev:
825 def __iter__(self): return iter([])
826 def __reversed__(self): return reversed([])
827 class RevItBlocked(Rev):
828 __iter__ = None
829 class RevRevBlocked(Rev):
830 __reversed__ = None
831 self.assertTrue(issubclass(Rev, Reversible))
832 self.assertTrue(isinstance(Rev(), Reversible))
833 self.assertFalse(issubclass(RevItBlocked, Reversible))
834 self.assertFalse(isinstance(RevItBlocked(), Reversible))
835 self.assertFalse(issubclass(RevRevBlocked, Reversible))
836 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700837
Guido van Rossumf0666942016-08-23 10:47:07 -0700838 def test_Collection(self):
839 # Check some non-collections
840 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
841 for x in non_collections:
842 self.assertNotIsInstance(x, Collection)
843 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
844 # Check some non-collection iterables
845 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800846 (x for x in [])]
Guido van Rossumf0666942016-08-23 10:47:07 -0700847 for x in non_col_iterables:
848 self.assertNotIsInstance(x, Collection)
849 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
850 # Check some collections
851 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800852 list(), dict().keys(), dict().items(), dict().values()]
Guido van Rossumf0666942016-08-23 10:47:07 -0700853 for x in samples:
854 self.assertIsInstance(x, Collection)
855 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
856 # Check also Mapping, MutableMapping, etc.
857 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
858 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
859 self.assertTrue(issubclass(MutableMapping, Collection),
860 repr(MutableMapping))
861 self.assertTrue(issubclass(Set, Collection), repr(Set))
862 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
863 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
864 # Check direct subclassing
865 class Col(Collection):
866 def __iter__(self):
867 return iter(list())
868 def __len__(self):
869 return 0
870 def __contains__(self, item):
871 return False
872 class DerCol(Col): pass
873 self.assertEqual(list(iter(Col())), [])
874 self.assertFalse(issubclass(list, Col))
875 self.assertFalse(issubclass(set, Col))
876 self.assertFalse(issubclass(float, Col))
877 self.assertEqual(list(iter(DerCol())), [])
878 self.assertFalse(issubclass(list, DerCol))
879 self.assertFalse(issubclass(set, DerCol))
880 self.assertFalse(issubclass(float, DerCol))
881 self.validate_abstract_methods(Collection, '__len__', '__iter__',
882 '__contains__')
883 # Check sized container non-iterable (which is not Collection) etc.
884 class ColNoIter:
885 def __len__(self): return 0
886 def __contains__(self, item): return False
887 class ColNoSize:
888 def __iter__(self): return iter([])
889 def __contains__(self, item): return False
890 class ColNoCont:
891 def __iter__(self): return iter([])
892 def __len__(self): return 0
893 self.assertFalse(issubclass(ColNoIter, Collection))
894 self.assertFalse(isinstance(ColNoIter(), Collection))
895 self.assertFalse(issubclass(ColNoSize, Collection))
896 self.assertFalse(isinstance(ColNoSize(), Collection))
897 self.assertFalse(issubclass(ColNoCont, Collection))
898 self.assertFalse(isinstance(ColNoCont(), Collection))
899 # Check None blocking
900 class SizeBlock:
901 def __iter__(self): return iter([])
902 def __contains__(self): return False
903 __len__ = None
904 class IterBlock:
905 def __len__(self): return 0
906 def __contains__(self): return True
907 __iter__ = None
908 self.assertFalse(issubclass(SizeBlock, Collection))
909 self.assertFalse(isinstance(SizeBlock(), Collection))
910 self.assertFalse(issubclass(IterBlock, Collection))
911 self.assertFalse(isinstance(IterBlock(), Collection))
912 # Check None blocking in subclass
913 class ColImpl:
914 def __iter__(self):
915 return iter(list())
916 def __len__(self):
917 return 0
918 def __contains__(self, item):
919 return False
920 class NonCol(ColImpl):
921 __contains__ = None
922 self.assertFalse(issubclass(NonCol, Collection))
923 self.assertFalse(isinstance(NonCol(), Collection))
924
925
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000926 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000927 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000928 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000929 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000930 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000931 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000932 iter(tuple()), iter(list()), iter(dict()),
933 iter(set()), iter(frozenset()),
934 iter(dict().keys()), iter(dict().items()),
935 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700936 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000937 (x for x in []),
938 ]
939 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000940 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000941 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000942 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
943
944 # Issue 10565
945 class NextOnly:
946 def __next__(self):
947 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800948 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000949 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000950
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400951 def test_Generator(self):
952 class NonGen1:
953 def __iter__(self): return self
954 def __next__(self): return None
955 def close(self): pass
956 def throw(self, typ, val=None, tb=None): pass
957
958 class NonGen2:
959 def __iter__(self): return self
960 def __next__(self): return None
961 def close(self): pass
962 def send(self, value): return value
963
964 class NonGen3:
965 def close(self): pass
966 def send(self, value): return value
967 def throw(self, typ, val=None, tb=None): pass
968
969 non_samples = [
970 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
971 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
972 for x in non_samples:
973 self.assertNotIsInstance(x, Generator)
974 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
975
976 class Gen:
977 def __iter__(self): return self
978 def __next__(self): return None
979 def close(self): pass
980 def send(self, value): return value
981 def throw(self, typ, val=None, tb=None): pass
982
983 class MinimalGen(Generator):
984 def send(self, value):
985 return value
986 def throw(self, typ, val=None, tb=None):
987 super().throw(typ, val, tb)
988
989 def gen():
990 yield 1
991
992 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
993 for x in samples:
994 self.assertIsInstance(x, Iterator)
995 self.assertIsInstance(x, Generator)
996 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
997 self.validate_abstract_methods(Generator, 'send', 'throw')
998
999 # mixin tests
1000 mgen = MinimalGen()
1001 self.assertIs(mgen, iter(mgen))
1002 self.assertIs(mgen.send(None), next(mgen))
1003 self.assertEqual(2, mgen.send(2))
1004 self.assertIsNone(mgen.close())
1005 self.assertRaises(ValueError, mgen.throw, ValueError)
1006 self.assertRaisesRegex(ValueError, "^huhu$",
1007 mgen.throw, ValueError, ValueError("huhu"))
1008 self.assertRaises(StopIteration, mgen.throw, StopIteration())
1009
1010 class FailOnClose(Generator):
1011 def send(self, value): return value
1012 def throw(self, *args): raise ValueError
1013
1014 self.assertRaises(ValueError, FailOnClose().close)
1015
1016 class IgnoreGeneratorExit(Generator):
1017 def send(self, value): return value
1018 def throw(self, *args): pass
1019
1020 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
1021
Yury Selivanov22214ab2016-11-16 18:25:04 -05001022 def test_AsyncGenerator(self):
1023 class NonAGen1:
1024 def __aiter__(self): return self
1025 def __anext__(self): return None
1026 def aclose(self): pass
1027 def athrow(self, typ, val=None, tb=None): pass
1028
1029 class NonAGen2:
1030 def __aiter__(self): return self
1031 def __anext__(self): return None
1032 def aclose(self): pass
1033 def asend(self, value): return value
1034
1035 class NonAGen3:
1036 def aclose(self): pass
1037 def asend(self, value): return value
1038 def athrow(self, typ, val=None, tb=None): pass
1039
1040 non_samples = [
1041 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1042 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
1043 for x in non_samples:
1044 self.assertNotIsInstance(x, AsyncGenerator)
1045 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
1046
1047 class Gen:
1048 def __aiter__(self): return self
1049 async def __anext__(self): return None
1050 async def aclose(self): pass
1051 async def asend(self, value): return value
1052 async def athrow(self, typ, val=None, tb=None): pass
1053
1054 class MinimalAGen(AsyncGenerator):
1055 async def asend(self, value):
1056 return value
1057 async def athrow(self, typ, val=None, tb=None):
1058 await super().athrow(typ, val, tb)
1059
1060 async def gen():
1061 yield 1
1062
1063 samples = [gen(), Gen(), MinimalAGen()]
1064 for x in samples:
1065 self.assertIsInstance(x, AsyncIterator)
1066 self.assertIsInstance(x, AsyncGenerator)
1067 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1068 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1069
1070 def run_async(coro):
1071 result = None
1072 while True:
1073 try:
1074 coro.send(None)
1075 except StopIteration as ex:
1076 result = ex.args[0] if ex.args else None
1077 break
1078 return result
1079
1080 # mixin tests
1081 mgen = MinimalAGen()
1082 self.assertIs(mgen, mgen.__aiter__())
1083 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1084 self.assertEqual(2, run_async(mgen.asend(2)))
1085 self.assertIsNone(run_async(mgen.aclose()))
1086 with self.assertRaises(ValueError):
1087 run_async(mgen.athrow(ValueError))
1088
1089 class FailOnClose(AsyncGenerator):
1090 async def asend(self, value): return value
1091 async def athrow(self, *args): raise ValueError
1092
1093 with self.assertRaises(ValueError):
1094 run_async(FailOnClose().aclose())
1095
1096 class IgnoreGeneratorExit(AsyncGenerator):
1097 async def asend(self, value): return value
1098 async def athrow(self, *args): pass
1099
1100 with self.assertRaises(RuntimeError):
1101 run_async(IgnoreGeneratorExit().aclose())
1102
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001103 def test_Sized(self):
1104 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001105 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001106 (x for x in []),
1107 ]
1108 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001109 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001110 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001111 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001112 tuple(), list(), set(), frozenset(), dict(),
1113 dict().keys(), dict().items(), dict().values(),
1114 ]
1115 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001116 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001117 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001118 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001119 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001120
1121 def test_Container(self):
1122 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001123 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001124 (x for x in []),
1125 ]
1126 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001127 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001128 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001129 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001130 tuple(), list(), set(), frozenset(), dict(),
1131 dict().keys(), dict().items(),
1132 ]
1133 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001134 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001135 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001136 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001137 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001138
1139 def test_Callable(self):
1140 non_samples = [None, 42, 3.14, 1j,
1141 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001142 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001143 (x for x in []),
1144 ]
1145 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001146 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001147 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001148 samples = [lambda: None,
1149 type, int, object,
1150 len,
1151 list.append, [].append,
1152 ]
1153 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001154 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001155 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001156 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001157 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001158
1159 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001160 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001161 class C(B):
1162 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001163 self.assertTrue(issubclass(C, B))
1164 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001165
1166 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001167 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001168 class C:
1169 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001170 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001171 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001172 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001173
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001174class WithSet(MutableSet):
1175
1176 def __init__(self, it=()):
1177 self.data = set(it)
1178
1179 def __len__(self):
1180 return len(self.data)
1181
1182 def __iter__(self):
1183 return iter(self.data)
1184
1185 def __contains__(self, item):
1186 return item in self.data
1187
1188 def add(self, item):
1189 self.data.add(item)
1190
1191 def discard(self, item):
1192 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001193
Raymond Hettingerae650182009-01-28 23:33:59 +00001194class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001195
1196 # XXX For now, we only test some virtual inheritance properties.
1197 # We should also test the proper behavior of the collection ABCs
1198 # as real base classes or mix-in classes.
1199
1200 def test_Set(self):
1201 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001202 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001203 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001204 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001205 class MySet(Set):
1206 def __contains__(self, x):
1207 return False
1208 def __len__(self):
1209 return 0
1210 def __iter__(self):
1211 return iter([])
1212 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001213
Benjamin Peterson41181742008-07-02 20:22:54 +00001214 def test_hash_Set(self):
1215 class OneTwoThreeSet(Set):
1216 def __init__(self):
1217 self.contents = [1, 2, 3]
1218 def __contains__(self, x):
1219 return x in self.contents
1220 def __len__(self):
1221 return len(self.contents)
1222 def __iter__(self):
1223 return iter(self.contents)
1224 def __hash__(self):
1225 return self._hash()
1226 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001227 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001228
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001229 def test_isdisjoint_Set(self):
1230 class MySet(Set):
1231 def __init__(self, itr):
1232 self.contents = itr
1233 def __contains__(self, x):
1234 return x in self.contents
1235 def __iter__(self):
1236 return iter(self.contents)
1237 def __len__(self):
1238 return len([x for x in self.contents])
1239 s1 = MySet((1, 2, 3))
1240 s2 = MySet((4, 5, 6))
1241 s3 = MySet((1, 5, 6))
1242 self.assertTrue(s1.isdisjoint(s2))
1243 self.assertFalse(s1.isdisjoint(s3))
1244
1245 def test_equality_Set(self):
1246 class MySet(Set):
1247 def __init__(self, itr):
1248 self.contents = itr
1249 def __contains__(self, x):
1250 return x in self.contents
1251 def __iter__(self):
1252 return iter(self.contents)
1253 def __len__(self):
1254 return len([x for x in self.contents])
1255 s1 = MySet((1,))
1256 s2 = MySet((1, 2))
1257 s3 = MySet((3, 4))
1258 s4 = MySet((3, 4))
1259 self.assertTrue(s2 > s1)
1260 self.assertTrue(s1 < s2)
1261 self.assertFalse(s2 <= s1)
1262 self.assertFalse(s2 <= s3)
1263 self.assertFalse(s1 >= s2)
1264 self.assertEqual(s3, s4)
1265 self.assertNotEqual(s2, s3)
1266
1267 def test_arithmetic_Set(self):
1268 class MySet(Set):
1269 def __init__(self, itr):
1270 self.contents = itr
1271 def __contains__(self, x):
1272 return x in self.contents
1273 def __iter__(self):
1274 return iter(self.contents)
1275 def __len__(self):
1276 return len([x for x in self.contents])
1277 s1 = MySet((1, 2, 3))
1278 s2 = MySet((3, 4, 5))
1279 s3 = s1 & s2
1280 self.assertEqual(s3, MySet((3,)))
1281
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001282 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001283 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001284 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001285 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001286 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001287 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1288 'add', 'discard')
1289
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001290 def test_issue_5647(self):
1291 # MutableSet.__iand__ mutated the set during iteration
1292 s = WithSet('abcd')
1293 s &= WithSet('cdef') # This used to fail
1294 self.assertEqual(set(s), set('cd'))
1295
Raymond Hettingerae650182009-01-28 23:33:59 +00001296 def test_issue_4920(self):
1297 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001298 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001299 __slots__=['__s']
1300 def __init__(self,items=None):
1301 if items is None:
1302 items=[]
1303 self.__s=set(items)
1304 def __contains__(self,v):
1305 return v in self.__s
1306 def __iter__(self):
1307 return iter(self.__s)
1308 def __len__(self):
1309 return len(self.__s)
1310 def add(self,v):
1311 result=v not in self.__s
1312 self.__s.add(v)
1313 return result
1314 def discard(self,v):
1315 result=v in self.__s
1316 self.__s.discard(v)
1317 return result
1318 def __repr__(self):
1319 return "MySet(%s)" % repr(list(self))
1320 s = MySet([5,43,2,1])
1321 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001322
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001323 def test_issue8750(self):
1324 empty = WithSet()
1325 full = WithSet(range(10))
1326 s = WithSet(full)
1327 s -= s
1328 self.assertEqual(s, empty)
1329 s = WithSet(full)
1330 s ^= s
1331 self.assertEqual(s, empty)
1332 s = WithSet(full)
1333 s &= s
1334 self.assertEqual(s, full)
1335 s |= s
1336 self.assertEqual(s, full)
1337
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001338 def test_issue16373(self):
1339 # Recursion error comparing comparable and noncomparable
1340 # Set instances
1341 class MyComparableSet(Set):
1342 def __contains__(self, x):
1343 return False
1344 def __len__(self):
1345 return 0
1346 def __iter__(self):
1347 return iter([])
1348 class MyNonComparableSet(Set):
1349 def __contains__(self, x):
1350 return False
1351 def __len__(self):
1352 return 0
1353 def __iter__(self):
1354 return iter([])
1355 def __le__(self, x):
1356 return NotImplemented
1357 def __lt__(self, x):
1358 return NotImplemented
1359
1360 cs = MyComparableSet()
1361 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001362 self.assertFalse(ncs < cs)
1363 self.assertTrue(ncs <= cs)
1364 self.assertFalse(ncs > cs)
1365 self.assertTrue(ncs >= cs)
1366
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001367 def test_issue26915(self):
1368 # Container membership test should check identity first
1369 class CustomEqualObject:
1370 def __eq__(self, other):
1371 return False
Xiang Zhangd5d32492017-03-08 11:04:24 +08001372 class CustomSequence(Sequence):
1373 def __init__(self, seq):
1374 self._seq = seq
1375 def __getitem__(self, index):
1376 return self._seq[index]
1377 def __len__(self):
1378 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001379
1380 nan = float('nan')
1381 obj = CustomEqualObject()
Xiang Zhangd5d32492017-03-08 11:04:24 +08001382 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001383 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001384 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001385 ItemsView({1: nan, 2: obj}),
1386 ValuesView({1: nan, 2: obj})
1387 ]
1388 for container in containers:
1389 for elem in container:
1390 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001391 self.assertEqual(seq.index(nan), 0)
1392 self.assertEqual(seq.index(obj), 1)
1393 self.assertEqual(seq.count(nan), 2)
1394 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001395
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001396 def assertSameSet(self, s1, s2):
1397 # coerce both to a real set then check equality
1398 self.assertSetEqual(set(s1), set(s2))
1399
1400 def test_Set_interoperability_with_real_sets(self):
1401 # Issue: 8743
1402 class ListSet(Set):
1403 def __init__(self, elements=()):
1404 self.data = []
1405 for elem in elements:
1406 if elem not in self.data:
1407 self.data.append(elem)
1408 def __contains__(self, elem):
1409 return elem in self.data
1410 def __iter__(self):
1411 return iter(self.data)
1412 def __len__(self):
1413 return len(self.data)
1414 def __repr__(self):
1415 return 'Set({!r})'.format(self.data)
1416
1417 r1 = set('abc')
1418 r2 = set('bcd')
1419 r3 = set('abcde')
1420 f1 = ListSet('abc')
1421 f2 = ListSet('bcd')
1422 f3 = ListSet('abcde')
1423 l1 = list('abccba')
1424 l2 = list('bcddcb')
1425 l3 = list('abcdeedcba')
1426
1427 target = r1 & r2
1428 self.assertSameSet(f1 & f2, target)
1429 self.assertSameSet(f1 & r2, target)
1430 self.assertSameSet(r2 & f1, target)
1431 self.assertSameSet(f1 & l2, target)
1432
1433 target = r1 | r2
1434 self.assertSameSet(f1 | f2, target)
1435 self.assertSameSet(f1 | r2, target)
1436 self.assertSameSet(r2 | f1, target)
1437 self.assertSameSet(f1 | l2, target)
1438
1439 fwd_target = r1 - r2
1440 rev_target = r2 - r1
1441 self.assertSameSet(f1 - f2, fwd_target)
1442 self.assertSameSet(f2 - f1, rev_target)
1443 self.assertSameSet(f1 - r2, fwd_target)
1444 self.assertSameSet(f2 - r1, rev_target)
1445 self.assertSameSet(r1 - f2, fwd_target)
1446 self.assertSameSet(r2 - f1, rev_target)
1447 self.assertSameSet(f1 - l2, fwd_target)
1448 self.assertSameSet(f2 - l1, rev_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 # Don't change the following to use assertLess or other
1457 # "more specific" unittest assertions. The current
1458 # assertTrue/assertFalse style makes the pattern of test
1459 # case combinations clear and allows us to know for sure
1460 # the exact operator being invoked.
1461
1462 # proper subset
1463 self.assertTrue(f1 < f3)
1464 self.assertFalse(f1 < f1)
1465 self.assertFalse(f1 < f2)
1466 self.assertTrue(r1 < f3)
1467 self.assertFalse(r1 < f1)
1468 self.assertFalse(r1 < f2)
1469 self.assertTrue(r1 < r3)
1470 self.assertFalse(r1 < r1)
1471 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001472 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001473 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001474 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001475 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001476 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001477 f1 < l2
1478
1479 # any subset
1480 self.assertTrue(f1 <= f3)
1481 self.assertTrue(f1 <= f1)
1482 self.assertFalse(f1 <= f2)
1483 self.assertTrue(r1 <= f3)
1484 self.assertTrue(r1 <= f1)
1485 self.assertFalse(r1 <= f2)
1486 self.assertTrue(r1 <= r3)
1487 self.assertTrue(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
1491 with self.assertRaises(TypeError):
1492 f1 <= l1
1493 with self.assertRaises(TypeError):
1494 f1 <= l2
1495
1496 # proper superset
1497 self.assertTrue(f3 > f1)
1498 self.assertFalse(f1 > f1)
1499 self.assertFalse(f2 > f1)
1500 self.assertTrue(r3 > r1)
1501 self.assertFalse(f1 > r1)
1502 self.assertFalse(f2 > r1)
1503 self.assertTrue(r3 > r1)
1504 self.assertFalse(r1 > r1)
1505 self.assertFalse(r2 > r1)
1506 with self.assertRaises(TypeError):
1507 f1 > l3
1508 with self.assertRaises(TypeError):
1509 f1 > l1
1510 with self.assertRaises(TypeError):
1511 f1 > l2
1512
1513 # any superset
1514 self.assertTrue(f3 >= f1)
1515 self.assertTrue(f1 >= f1)
1516 self.assertFalse(f2 >= f1)
1517 self.assertTrue(r3 >= r1)
1518 self.assertTrue(f1 >= r1)
1519 self.assertFalse(f2 >= r1)
1520 self.assertTrue(r3 >= r1)
1521 self.assertTrue(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 # equality
1531 self.assertTrue(f1 == f1)
1532 self.assertTrue(r1 == f1)
1533 self.assertTrue(f1 == r1)
1534 self.assertFalse(f1 == f3)
1535 self.assertFalse(r1 == f3)
1536 self.assertFalse(f1 == r3)
1537 self.assertFalse(f1 == l3)
1538 self.assertFalse(f1 == l1)
1539 self.assertFalse(f1 == l2)
1540
1541 # inequality
1542 self.assertFalse(f1 != f1)
1543 self.assertFalse(r1 != f1)
1544 self.assertFalse(f1 != r1)
1545 self.assertTrue(f1 != f3)
1546 self.assertTrue(r1 != f3)
1547 self.assertTrue(f1 != r3)
1548 self.assertTrue(f1 != l3)
1549 self.assertTrue(f1 != l1)
1550 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001551
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001552 def test_Mapping(self):
1553 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001554 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001555 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001556 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1557 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001558 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001559 def __len__(self):
1560 return 0
1561 def __getitem__(self, i):
1562 raise IndexError
1563 def __iter__(self):
1564 return iter(())
1565 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001566 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001567
1568 def test_MutableMapping(self):
1569 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001570 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001571 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001572 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1573 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001574
Raymond Hettinger9117c752010-08-22 07:44:24 +00001575 def test_MutableMapping_subclass(self):
1576 # Test issue 9214
1577 mymap = UserDict()
1578 mymap['red'] = 5
1579 self.assertIsInstance(mymap.keys(), Set)
1580 self.assertIsInstance(mymap.keys(), KeysView)
1581 self.assertIsInstance(mymap.items(), Set)
1582 self.assertIsInstance(mymap.items(), ItemsView)
1583
1584 mymap = UserDict()
1585 mymap['red'] = 5
1586 z = mymap.keys() | {'orange'}
1587 self.assertIsInstance(z, set)
1588 list(z)
1589 mymap['blue'] = 7 # Shouldn't affect 'z'
1590 self.assertEqual(sorted(z), ['orange', 'red'])
1591
1592 mymap = UserDict()
1593 mymap['red'] = 5
1594 z = mymap.items() | {('orange', 3)}
1595 self.assertIsInstance(z, set)
1596 list(z)
1597 mymap['blue'] = 7 # Shouldn't affect 'z'
1598 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1599
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001600 def test_Sequence(self):
1601 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001602 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001603 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001604 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001605 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001606 self.assertIsInstance(memoryview(b""), Sequence)
1607 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001608 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001609 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1610 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001611
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001612 def test_Sequence_mixins(self):
1613 class SequenceSubclass(Sequence):
1614 def __init__(self, seq=()):
1615 self.seq = seq
1616
1617 def __getitem__(self, index):
1618 return self.seq[index]
1619
1620 def __len__(self):
1621 return len(self.seq)
1622
1623 # Compare Sequence.index() behavior to (list|str).index() behavior
1624 def assert_index_same(seq1, seq2, index_args):
1625 try:
1626 expected = seq1.index(*index_args)
1627 except ValueError:
1628 with self.assertRaises(ValueError):
1629 seq2.index(*index_args)
1630 else:
1631 actual = seq2.index(*index_args)
1632 self.assertEqual(
1633 actual, expected, '%r.index%s' % (seq1, index_args))
1634
1635 for ty in list, str:
1636 nativeseq = ty('abracadabra')
1637 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1638 seqseq = SequenceSubclass(nativeseq)
1639 for letter in set(nativeseq) | {'z'}:
1640 assert_index_same(nativeseq, seqseq, (letter,))
1641 for start in range(-3, len(nativeseq) + 3):
1642 assert_index_same(nativeseq, seqseq, (letter, start))
1643 for stop in range(-3, len(nativeseq) + 3):
1644 assert_index_same(
1645 nativeseq, seqseq, (letter, start, stop))
1646
Guido van Rossumd05eb002007-11-21 22:26:24 +00001647 def test_ByteString(self):
1648 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001649 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001650 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001651 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001652 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001653 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001654 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001655 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001656
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001657 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001658 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001659 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001660 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001661 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001662 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001663 self.assertTrue(issubclass(sample, MutableSequence))
1664 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001665 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1666 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001667
Eli Bendersky0716a572011-03-04 10:38:14 +00001668 def test_MutableSequence_mixins(self):
Mike53f7a7c2017-12-14 14:04:53 +03001669 # Test the mixins of MutableSequence by creating a minimal concrete
Eli Bendersky0716a572011-03-04 10:38:14 +00001670 # class inherited from it.
1671 class MutableSequenceSubclass(MutableSequence):
1672 def __init__(self):
1673 self.lst = []
1674
1675 def __setitem__(self, index, value):
1676 self.lst[index] = value
1677
1678 def __getitem__(self, index):
1679 return self.lst[index]
1680
1681 def __len__(self):
1682 return len(self.lst)
1683
1684 def __delitem__(self, index):
1685 del self.lst[index]
1686
1687 def insert(self, index, value):
1688 self.lst.insert(index, value)
1689
1690 mss = MutableSequenceSubclass()
1691 mss.append(0)
1692 mss.extend((1, 2, 3, 4))
1693 self.assertEqual(len(mss), 5)
1694 self.assertEqual(mss[3], 3)
1695 mss.reverse()
1696 self.assertEqual(mss[3], 1)
1697 mss.pop()
1698 self.assertEqual(len(mss), 4)
1699 mss.remove(3)
1700 self.assertEqual(len(mss), 3)
1701 mss += (10, 20, 30)
1702 self.assertEqual(len(mss), 6)
1703 self.assertEqual(mss[-1], 30)
1704 mss.clear()
1705 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001706
1707################################################################################
1708### Counter
1709################################################################################
1710
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001711class CounterSubclassWithSetItem(Counter):
1712 # Test a counter subclass that overrides __setitem__
1713 def __init__(self, *args, **kwds):
1714 self.called = False
1715 Counter.__init__(self, *args, **kwds)
1716 def __setitem__(self, key, value):
1717 self.called = True
1718 Counter.__setitem__(self, key, value)
1719
1720class CounterSubclassWithGet(Counter):
1721 # Test a counter subclass that overrides get()
1722 def __init__(self, *args, **kwds):
1723 self.called = False
1724 Counter.__init__(self, *args, **kwds)
1725 def get(self, key, default):
1726 self.called = True
1727 return Counter.get(self, key, default)
1728
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001729class TestCounter(unittest.TestCase):
1730
1731 def test_basics(self):
1732 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001733 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1734 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001735 self.assertIsInstance(c, dict)
1736 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001737 self.assertTrue(issubclass(Counter, dict))
1738 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001739 self.assertEqual(len(c), 3)
1740 self.assertEqual(sum(c.values()), 6)
1741 self.assertEqual(sorted(c.values()), [1, 2, 3])
1742 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1743 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1744 self.assertEqual(sorted(c.items()),
1745 [('a', 3), ('b', 2), ('c', 1)])
1746 self.assertEqual(c['b'], 2)
1747 self.assertEqual(c['z'], 0)
1748 self.assertEqual(c.__contains__('c'), True)
1749 self.assertEqual(c.__contains__('z'), False)
1750 self.assertEqual(c.get('b', 10), 2)
1751 self.assertEqual(c.get('z', 10), 10)
1752 self.assertEqual(c, dict(a=3, b=2, c=1))
1753 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1754 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1755 for i in range(5):
1756 self.assertEqual(c.most_common(i),
1757 [('a', 3), ('b', 2), ('c', 1)][:i])
1758 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1759 c['a'] += 1 # increment an existing value
1760 c['b'] -= 2 # sub existing value to zero
1761 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001762 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001763 c['d'] -= 2 # sub from a missing value
1764 c['e'] = -5 # directly assign a missing value
1765 c['f'] += 4 # add to a missing value
1766 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1767 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1768 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001769 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001770 for i in range(3):
1771 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001772 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001773 c.clear()
1774 self.assertEqual(c, {})
1775 self.assertEqual(repr(c), 'Counter()')
1776 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1777 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001778 c.update(dict(a=5, b=3))
1779 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001780 c.update(Counter('a' * 50 + 'b' * 30))
1781 c.update() # test case with no args
1782 c.__init__('a' * 500 + 'b' * 300)
1783 c.__init__('cdc')
1784 c.__init__()
1785 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1786 self.assertEqual(c.setdefault('d', 5), 1)
1787 self.assertEqual(c['d'], 1)
1788 self.assertEqual(c.setdefault('e', 5), 5)
1789 self.assertEqual(c['e'], 5)
1790
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001791 def test_init(self):
1792 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1793 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1794 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1795 self.assertRaises(TypeError, Counter, 42)
1796 self.assertRaises(TypeError, Counter, (), ())
1797 self.assertRaises(TypeError, Counter.__init__)
1798
1799 def test_update(self):
1800 c = Counter()
1801 c.update(self=42)
1802 self.assertEqual(list(c.items()), [('self', 42)])
1803 c = Counter()
1804 c.update(iterable=42)
1805 self.assertEqual(list(c.items()), [('iterable', 42)])
1806 c = Counter()
1807 c.update(iterable=None)
1808 self.assertEqual(list(c.items()), [('iterable', None)])
1809 self.assertRaises(TypeError, Counter().update, 42)
1810 self.assertRaises(TypeError, Counter().update, {}, {})
1811 self.assertRaises(TypeError, Counter.update)
1812
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001813 def test_copying(self):
1814 # Check that counters are copyable, deepcopyable, picklable, and
1815 #have a repr/eval round-trip
1816 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001817 def check(dup):
1818 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1819 self.assertIsNot(dup, words, msg)
1820 self.assertEqual(dup, words)
1821 check(words.copy())
1822 check(copy.copy(words))
1823 check(copy.deepcopy(words))
1824 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1825 with self.subTest(proto=proto):
1826 check(pickle.loads(pickle.dumps(words, proto)))
1827 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001828 update_test = Counter()
1829 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001830 check(update_test)
1831 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001832
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001833 def test_copy_subclass(self):
1834 class MyCounter(Counter):
1835 pass
1836 c = MyCounter('slartibartfast')
1837 d = c.copy()
1838 self.assertEqual(d, c)
1839 self.assertEqual(len(d), len(c))
1840 self.assertEqual(type(d), type(c))
1841
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001842 def test_conversions(self):
1843 # Convert to: set, list, dict
1844 s = 'she sells sea shells by the sea shore'
1845 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1846 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1847 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1848 self.assertEqual(set(Counter(s)), set(s))
1849
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001850 def test_invariant_for_the_in_operator(self):
1851 c = Counter(a=10, b=-2, c=0)
1852 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001853 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001854 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001855
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001856 def test_multiset_operations(self):
1857 # Verify that adding a zero counter will strip zeros and negatives
1858 c = Counter(a=10, b=-2, c=0) + Counter()
1859 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001860
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001861 elements = 'abcd'
1862 for i in range(1000):
1863 # test random pairs of multisets
1864 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001865 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001866 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001867 q.update(h=1, i=-1, j=0)
1868 for counterop, numberop in [
1869 (Counter.__add__, lambda x, y: max(0, x+y)),
1870 (Counter.__sub__, lambda x, y: max(0, x-y)),
1871 (Counter.__or__, lambda x, y: max(0,x,y)),
1872 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001873 ]:
1874 result = counterop(p, q)
1875 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001876 self.assertEqual(numberop(p[x], q[x]), result[x],
1877 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001878 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001879 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001880
1881 elements = 'abcdef'
1882 for i in range(100):
1883 # verify that random multisets with no repeats are exactly like sets
1884 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1885 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1886 for counterop, setop in [
1887 (Counter.__sub__, set.__sub__),
1888 (Counter.__or__, set.__or__),
1889 (Counter.__and__, set.__and__),
1890 ]:
1891 counter_result = counterop(p, q)
1892 set_result = setop(set(p.elements()), set(q.elements()))
1893 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001894
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001895 def test_inplace_operations(self):
1896 elements = 'abcd'
1897 for i in range(1000):
1898 # test random pairs of multisets
1899 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1900 p.update(e=1, f=-1, g=0)
1901 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1902 q.update(h=1, i=-1, j=0)
1903 for inplace_op, regular_op in [
1904 (Counter.__iadd__, Counter.__add__),
1905 (Counter.__isub__, Counter.__sub__),
1906 (Counter.__ior__, Counter.__or__),
1907 (Counter.__iand__, Counter.__and__),
1908 ]:
1909 c = p.copy()
1910 c_id = id(c)
1911 regular_result = regular_op(c, q)
1912 inplace_result = inplace_op(c, q)
1913 self.assertEqual(inplace_result, regular_result)
1914 self.assertEqual(id(inplace_result), c_id)
1915
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001916 def test_subtract(self):
1917 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1918 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1919 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1920 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1921 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1922 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1923 c = Counter('aaabbcd')
1924 c.subtract('aaaabbcce')
1925 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001926
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001927 c = Counter()
1928 c.subtract(self=42)
1929 self.assertEqual(list(c.items()), [('self', -42)])
1930 c = Counter()
1931 c.subtract(iterable=42)
1932 self.assertEqual(list(c.items()), [('iterable', -42)])
1933 self.assertRaises(TypeError, Counter().subtract, 42)
1934 self.assertRaises(TypeError, Counter().subtract, {}, {})
1935 self.assertRaises(TypeError, Counter.subtract)
1936
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001937 def test_unary(self):
1938 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1939 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1940 self.assertEqual(dict(-c), dict(a=5))
1941
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001942 def test_repr_nonsortable(self):
1943 c = Counter(a=2, b=None)
1944 r = repr(c)
1945 self.assertIn("'a': 2", r)
1946 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001947
Raymond Hettinger426e0522011-01-03 02:12:02 +00001948 def test_helper_function(self):
1949 # two paths, one for real dicts and one for other mappings
1950 elems = list('abracadabra')
1951
1952 d = dict()
1953 _count_elements(d, elems)
1954 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1955
1956 m = OrderedDict()
1957 _count_elements(m, elems)
1958 self.assertEqual(m,
1959 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1960
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001961 # test fidelity to the pure python version
1962 c = CounterSubclassWithSetItem('abracadabra')
1963 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001964 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001965 c = CounterSubclassWithGet('abracadabra')
1966 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001967 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001968
Raymond Hettinger499e1932011-02-23 07:56:53 +00001969
1970################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001971### Run tests
1972################################################################################
1973
Guido van Rossumd8faa362007-04-27 19:54:29 +00001974def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001975 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001976 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001977 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06001978 TestUserObjects,
1979 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001980 support.run_unittest(*test_classes)
1981 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001982
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001983
Guido van Rossumd8faa362007-04-27 19:54:29 +00001984if __name__ == "__main__":
1985 test_main(verbose=True)