blob: 74372d28ed050d5d64cb841704767949a98802fa [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001"""Unit tests for collections.py."""
2
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02003import collections
4import copy
5import doctest
Serhiy Storchaka052b2df2018-12-31 14:15:16 +02006import inspect
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02007import operator
8import pickle
9from random import choice, randrange
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020010import string
R. David Murray378c0cf2010-02-24 01:46:21 +000011import sys
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020012from test import support
Yury Selivanov75445082015-05-11 22:57:16 -040013import types
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020014import unittest
15
16from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger573b44c2015-05-22 16:56:32 -070017from collections import UserDict, UserString, UserList
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000018from collections import ChainMap
Raymond Hettinger32ea1652015-03-21 01:37:37 -070019from collections import deque
Yury Selivanov22214ab2016-11-16 18:25:04 -050020from collections.abc import Awaitable, Coroutine
21from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator
Guido van Rossum16ca06b2016-04-04 10:59:29 -070022from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
Guido van Rossumf0666942016-08-23 10:47:07 -070023from collections.abc import Sized, Container, Callable, Collection
Raymond Hettinger57d1a882011-02-23 00:46:28 +000024from collections.abc import Set, MutableSet
Raymond Hettinger584e8ae2016-05-05 11:14:06 +030025from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
Raymond Hettinger57d1a882011-02-23 00:46:28 +000026from collections.abc import Sequence, MutableSequence
27from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000028
Raymond Hettinger499e1932011-02-23 07:56:53 +000029
Raymond Hettinger573b44c2015-05-22 16:56:32 -070030class TestUserObjects(unittest.TestCase):
31 def _superset_test(self, a, b):
32 self.assertGreaterEqual(
33 set(dir(a)),
34 set(dir(b)),
35 '{a} should have all the methods of {b}'.format(
36 a=a.__name__,
37 b=b.__name__,
38 ),
39 )
40 def test_str_protocol(self):
41 self._superset_test(UserString, str)
42
43 def test_list_protocol(self):
44 self._superset_test(UserList, list)
45
46 def test_dict_protocol(self):
47 self._superset_test(UserDict, dict)
48
49
Raymond Hettinger499e1932011-02-23 07:56:53 +000050################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000051### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000052################################################################################
53
54class TestChainMap(unittest.TestCase):
55
56 def test_basics(self):
57 c = ChainMap()
58 c['a'] = 1
59 c['b'] = 2
60 d = c.new_child()
61 d['b'] = 20
62 d['c'] = 30
63 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
64 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
65 self.assertEqual(len(d), 3) # check len
66 for key in 'abc': # check contains
67 self.assertIn(key, d)
68 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
69 self.assertEqual(d.get(k, 100), v)
70
71 del d['b'] # unmask a value
72 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
73 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
74 self.assertEqual(len(d), 3) # check len
75 for key in 'abc': # check contains
76 self.assertIn(key, d)
77 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
78 self.assertEqual(d.get(k, 100), v)
79 self.assertIn(repr(d), [ # check repr
80 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
81 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
82 ])
83
84 for e in d.copy(), copy.copy(d): # check shallow copies
85 self.assertEqual(d, e)
86 self.assertEqual(d.maps, e.maps)
87 self.assertIsNot(d, e)
88 self.assertIsNot(d.maps[0], e.maps[0])
89 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
90 self.assertIs(m1, m2)
91
Serhiy Storchakabad12572014-12-15 14:03:42 +020092 # check deep copies
93 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
94 e = pickle.loads(pickle.dumps(d, proto))
95 self.assertEqual(d, e)
96 self.assertEqual(d.maps, e.maps)
97 self.assertIsNot(d, e)
98 for m1, m2 in zip(d.maps, e.maps):
99 self.assertIsNot(m1, m2, e)
100 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +0000101 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200102 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000103 self.assertEqual(d, e)
104 self.assertEqual(d.maps, e.maps)
105 self.assertIsNot(d, e)
106 for m1, m2 in zip(d.maps, e.maps):
107 self.assertIsNot(m1, m2, e)
108
Raymond Hettingerd0321312011-02-26 06:53:58 +0000109 f = d.new_child()
110 f['b'] = 5
111 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
112 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
113 self.assertEqual(f['b'], 5) # find first in chain
114 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000115
Martin Pantereb995702016-07-28 01:11:04 +0000116 def test_constructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000117 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000118 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
119
Raymond Hettingerd0321312011-02-26 06:53:58 +0000120 def test_bool(self):
121 self.assertFalse(ChainMap())
122 self.assertFalse(ChainMap({}, {}))
123 self.assertTrue(ChainMap({1:2}, {}))
124 self.assertTrue(ChainMap({}, {1:2}))
125
Raymond Hettinger499e1932011-02-23 07:56:53 +0000126 def test_missing(self):
127 class DefaultChainMap(ChainMap):
128 def __missing__(self, key):
129 return 999
130 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
131 for k, v in dict(a=1, b=2, c=30, d=999).items():
132 self.assertEqual(d[k], v) # check __getitem__ w/missing
133 for k, v in dict(a=1, b=2, c=30, d=77).items():
134 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
135 for k, v in dict(a=True, b=True, c=True, d=False).items():
136 self.assertEqual(k in d, v) # check __contains__ w/missing
137 self.assertEqual(d.pop('a', 1001), 1, d)
138 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
139 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
140 with self.assertRaises(KeyError):
141 d.popitem()
142
Raymond Hettinger3793f952018-02-11 00:30:31 -0800143 def test_order_preservation(self):
144 d = ChainMap(
145 OrderedDict(j=0, h=88888),
146 OrderedDict(),
147 OrderedDict(i=9999, d=4444, c=3333),
148 OrderedDict(f=666, b=222, g=777, c=333, h=888),
149 OrderedDict(),
150 OrderedDict(e=55, b=22),
151 OrderedDict(a=1, b=2, c=3, d=4, e=5),
152 OrderedDict(),
153 )
154 self.assertEqual(''.join(d), 'abcdefghij')
155 self.assertEqual(list(d.items()),
156 [('a', 1), ('b', 222), ('c', 3333), ('d', 4444),
157 ('e', 55), ('f', 666), ('g', 777), ('h', 88888),
158 ('i', 9999), ('j', 0)])
159
Raymond Hettinger499e1932011-02-23 07:56:53 +0000160 def test_dict_coercion(self):
161 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
162 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
163 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
164
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000165 def test_new_child(self):
166 'Tests for changes for issue #16613.'
167 c = ChainMap()
168 c['a'] = 1
169 c['b'] = 2
170 m = {'b':20, 'c': 30}
171 d = c.new_child(m)
172 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
173 self.assertIs(m, d.maps[0])
174
175 # Use a different map than a dict
176 class lowerdict(dict):
177 def __getitem__(self, key):
178 if isinstance(key, str):
179 key = key.lower()
180 return dict.__getitem__(self, key)
181 def __contains__(self, key):
182 if isinstance(key, str):
183 key = key.lower()
184 return dict.__contains__(self, key)
185
186 c = ChainMap()
187 c['a'] = 1
188 c['b'] = 2
189 m = lowerdict(b=20, c=30)
190 d = c.new_child(m)
191 self.assertIs(m, d.maps[0])
192 for key in 'abc': # check contains
193 self.assertIn(key, d)
194 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
195 self.assertEqual(d.get(k, 100), v)
196
Raymond Hettinger499e1932011-02-23 07:56:53 +0000197
198################################################################################
199### Named Tuples
200################################################################################
201
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000202TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000203
204class TestNamedTuple(unittest.TestCase):
205
206 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000207 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000208 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000209 self.assertEqual(Point.__slots__, ())
210 self.assertEqual(Point.__module__, __name__)
211 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000212 self.assertEqual(Point._fields, ('x', 'y'))
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000213
214 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
215 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
216 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
217
218 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
219 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
220 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000221 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000222 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
223
224 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000225 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000226
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000227 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000228 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000229 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000230 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000231
Christian Heimesfaf2f632008-01-06 16:59:19 +0000232 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
233 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
234
Raymond Hettinger39482072018-01-10 21:45:19 -0800235 def test_defaults(self):
236 Point = namedtuple('Point', 'x y', defaults=(10, 20)) # 2 defaults
237 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
238 self.assertEqual(Point(1, 2), (1, 2))
239 self.assertEqual(Point(1), (1, 20))
240 self.assertEqual(Point(), (10, 20))
241
242 Point = namedtuple('Point', 'x y', defaults=(20,)) # 1 default
243 self.assertEqual(Point._fields_defaults, {'y': 20})
244 self.assertEqual(Point(1, 2), (1, 2))
245 self.assertEqual(Point(1), (1, 20))
246
247 Point = namedtuple('Point', 'x y', defaults=()) # 0 defaults
248 self.assertEqual(Point._fields_defaults, {})
249 self.assertEqual(Point(1, 2), (1, 2))
250 with self.assertRaises(TypeError):
251 Point(1)
252
253 with self.assertRaises(TypeError): # catch too few args
254 Point()
255 with self.assertRaises(TypeError): # catch too many args
256 Point(1, 2, 3)
257 with self.assertRaises(TypeError): # too many defaults
258 Point = namedtuple('Point', 'x y', defaults=(10, 20, 30))
259 with self.assertRaises(TypeError): # non-iterable defaults
260 Point = namedtuple('Point', 'x y', defaults=10)
261 with self.assertRaises(TypeError): # another non-iterable default
262 Point = namedtuple('Point', 'x y', defaults=False)
263
264 Point = namedtuple('Point', 'x y', defaults=None) # default is None
265 self.assertEqual(Point._fields_defaults, {})
266 self.assertIsNone(Point.__new__.__defaults__, None)
267 self.assertEqual(Point(10, 20), (10, 20))
268 with self.assertRaises(TypeError): # catch too few args
269 Point(10)
270
271 Point = namedtuple('Point', 'x y', defaults=[10, 20]) # allow non-tuple iterable
272 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
273 self.assertEqual(Point.__new__.__defaults__, (10, 20))
274 self.assertEqual(Point(1, 2), (1, 2))
275 self.assertEqual(Point(1), (1, 20))
276 self.assertEqual(Point(), (10, 20))
277
278 Point = namedtuple('Point', 'x y', defaults=iter([10, 20])) # allow plain iterator
279 self.assertEqual(Point._fields_defaults, {'x': 10, 'y': 20})
280 self.assertEqual(Point.__new__.__defaults__, (10, 20))
281 self.assertEqual(Point(1, 2), (1, 2))
282 self.assertEqual(Point(1), (1, 20))
283 self.assertEqual(Point(), (10, 20))
284
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200285 def test_readonly(self):
286 Point = namedtuple('Point', 'x y')
287 p = Point(11, 22)
288 with self.assertRaises(AttributeError):
289 p.x = 33
290 with self.assertRaises(AttributeError):
291 del p.x
292 with self.assertRaises(TypeError):
293 p[0] = 33
294 with self.assertRaises(TypeError):
295 del p[0]
296 self.assertEqual(p.x, 11)
297 self.assertEqual(p[0], 11)
Raymond Hettinger39482072018-01-10 21:45:19 -0800298
R. David Murray378c0cf2010-02-24 01:46:21 +0000299 @unittest.skipIf(sys.flags.optimize >= 2,
300 "Docstrings are omitted with -O2 and above")
301 def test_factory_doc_attr(self):
302 Point = namedtuple('Point', 'x y')
303 self.assertEqual(Point.__doc__, 'Point(x, y)')
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200304 Point.__doc__ = '2D point'
305 self.assertEqual(Point.__doc__, '2D point')
R. David Murray378c0cf2010-02-24 01:46:21 +0000306
Raymond Hettingereac503a2015-05-13 01:09:59 -0700307 @unittest.skipIf(sys.flags.optimize >= 2,
308 "Docstrings are omitted with -O2 and above")
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200309 def test_field_doc(self):
Raymond Hettingereac503a2015-05-13 01:09:59 -0700310 Point = namedtuple('Point', 'x y')
311 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200312 self.assertEqual(Point.y.__doc__, 'Alias for field number 1')
Raymond Hettingereac503a2015-05-13 01:09:59 -0700313 Point.x.__doc__ = 'docstring for Point.x'
314 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200315 # namedtuple can mutate doc of descriptors independently
316 Vector = namedtuple('Vector', 'x y')
317 self.assertEqual(Vector.x.__doc__, 'Alias for field number 0')
318 Vector.x.__doc__ = 'docstring for Vector.x'
319 self.assertEqual(Vector.x.__doc__, 'docstring for Vector.x')
320
321 @support.cpython_only
322 @unittest.skipIf(sys.flags.optimize >= 2,
323 "Docstrings are omitted with -O2 and above")
324 def test_field_doc_reuse(self):
325 P = namedtuple('P', ['m', 'n'])
326 Q = namedtuple('Q', ['o', 'p'])
327 self.assertIs(P.m.__doc__, Q.o.__doc__)
328 self.assertIs(P.n.__doc__, Q.p.__doc__)
Raymond Hettingereac503a2015-05-13 01:09:59 -0700329
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000330 def test_name_fixer(self):
331 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000332 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
333 [('abc', 'class'), ('abc', '_1')], # field has keyword
334 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
335 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
336 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
337 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000338 ]:
339 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
340
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700341 def test_module_parameter(self):
342 NT = namedtuple('NT', ['x', 'y'], module=collections)
343 self.assertEqual(NT.__module__, collections)
344
Guido van Rossumd8faa362007-04-27 19:54:29 +0000345 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000346 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000347 p = Point(11, 22)
348 self.assertEqual(p, Point(x=11, y=22))
349 self.assertEqual(p, Point(11, y=22))
350 self.assertEqual(p, Point(y=22, x=11))
351 self.assertEqual(p, Point(*(11, 22)))
352 self.assertEqual(p, Point(**dict(x=11, y=22)))
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200353 self.assertRaises(TypeError, Point, 1) # too few args
354 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
355 with self.assertRaises(TypeError): # wrong keyword argument
356 Point(XXX=1, y=2)
357 with self.assertRaises(TypeError): # missing keyword argument
358 Point(x=1)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000359 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000360 self.assertNotIn('__weakref__', dir(p))
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200361 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
362 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
363 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
364 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000365
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000366 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000367 p._replace(x=1, error=2)
368 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000369 pass
370 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000371 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000372
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000373 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000374 Point = namedtuple('Point', 'x, y')
375 p = Point(x=11, y=22)
376 self.assertEqual(repr(p), 'Point(x=11, y=22)')
377
378 # verify that fieldspec can be a non-string sequence
379 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000380 p = Point(x=11, y=22)
381 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000382
383 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000384 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000385 p = Point(11, 22)
386
Ezio Melottie9615932010-01-24 19:26:24 +0000387 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000388 self.assertEqual(p, (11, 22)) # matches a real tuple
389 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
390 self.assertEqual(list(p), [11, 22]) # coercable to a list
391 self.assertEqual(max(p), 22) # iterable
392 self.assertEqual(max(*p), 22) # star-able
393 x, y = p
394 self.assertEqual(p, (x, y)) # unpacks like a tuple
395 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200396 with self.assertRaises(IndexError):
397 p[3]
398 self.assertEqual(p[-1], 22)
399 self.assertEqual(hash(p), hash((11, 22)))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000400
401 self.assertEqual(p.x, x)
402 self.assertEqual(p.y, y)
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200403 with self.assertRaises(AttributeError):
404 p.z
Guido van Rossumd8faa362007-04-27 19:54:29 +0000405
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000406 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000407 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000408 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000409 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000410 self.assertEqual(repr(Zero()), 'Zero()')
411 self.assertEqual(Zero()._asdict(), {})
412 self.assertEqual(Zero()._fields, ())
413
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000414 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000415 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000416 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000417 self.assertEqual(Dot(1).d, 1)
418 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
419 self.assertEqual(Dot(1)._asdict(), {'d':1})
420 self.assertEqual(Dot(1)._replace(d=999), (999,))
421 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000422
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200423 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200424 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000425 for j in range(10)]) for i in range(n)))
426 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000427 Big = namedtuple('Big', names)
428 b = Big(*range(n))
429 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000430 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000431 for pos, name in enumerate(names):
432 self.assertEqual(getattr(b, name), pos)
433 repr(b) # make sure repr() doesn't blow-up
434 d = b._asdict()
435 d_expected = dict(zip(names, range(n)))
436 self.assertEqual(d, d_expected)
437 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
438 b2_expected = list(range(n))
439 b2_expected[1] = 999
440 b2_expected[-5] = 42
441 self.assertEqual(b2, tuple(b2_expected))
442 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000443
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000444 def test_pickle(self):
445 p = TestNT(x=10, y=20, z=30)
446 for module in (pickle,):
447 loads = getattr(module, 'loads')
448 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500449 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000450 q = loads(dumps(p, protocol))
451 self.assertEqual(p, q)
452 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700453 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000454
455 def test_copy(self):
456 p = TestNT(x=10, y=20, z=30)
457 for copier in copy.copy, copy.deepcopy:
458 q = copier(p)
459 self.assertEqual(p, q)
460 self.assertEqual(p._fields, q._fields)
461
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000462 def test_name_conflicts(self):
463 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
464 # failed when used as field names. Test to make sure these now work.
465 T = namedtuple('T', 'itemgetter property self cls tuple')
466 t = T(1, 2, 3, 4, 5)
467 self.assertEqual(t, (1,2,3,4,5))
468 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
469 self.assertEqual(newt, (10,20,30,40,50))
470
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700471 # Broader test of all interesting names taken from the code, old
472 # template, and an example
473 words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create',
474 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper',
475 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note',
476 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError',
477 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add',
478 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments',
479 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot',
480 'class_namespace', 'classmethod', 'cls', 'collections', 'convert',
481 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict',
482 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect',
483 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f',
484 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame',
485 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater',
486 'has', 'help', 'identifiers', 'index', 'indexable', 'instance',
487 'instantiate', 'interning', 'introspection', 'isidentifier',
488 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords',
489 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata',
490 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named',
491 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new',
492 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option',
493 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional',
494 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr',
495 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen',
496 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start',
497 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys',
498 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new',
499 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use',
500 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where',
501 'which', 'work', 'x', 'y', 'z', 'zip'}
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000502 T = namedtuple('T', words)
503 # test __new__
504 values = tuple(range(len(words)))
505 t = T(*values)
506 self.assertEqual(t, values)
507 t = T(**dict(zip(T._fields, values)))
508 self.assertEqual(t, values)
509 # test _make
510 t = T._make(values)
511 self.assertEqual(t, values)
512 # exercise __repr__
513 repr(t)
514 # test _asdict
515 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
516 # test _replace
517 t = T._make(values)
518 newvalues = tuple(v*10 for v in values)
519 newt = t._replace(**dict(zip(T._fields, newvalues)))
520 self.assertEqual(newt, newvalues)
521 # test _fields
522 self.assertEqual(T._fields, tuple(words))
523 # test __getnewargs__
524 self.assertEqual(t.__getnewargs__(), values)
525
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000526 def test_repr(self):
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700527 A = namedtuple('A', 'x')
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000528 self.assertEqual(repr(A(1)), 'A(x=1)')
529 # repr should show the name of the subclass
530 class B(A):
531 pass
532 self.assertEqual(repr(B(1)), 'B(x=1)')
533
Raymond Hettinger6538b432016-08-16 10:55:43 -0700534 def test_keyword_only_arguments(self):
535 # See issue 25628
Raymond Hettinger6538b432016-08-16 10:55:43 -0700536 with self.assertRaises(TypeError):
537 NT = namedtuple('NT', ['x', 'y'], True)
538
539 NT = namedtuple('NT', ['abc', 'def'], rename=True)
540 self.assertEqual(NT._fields, ('abc', '_1'))
541 with self.assertRaises(TypeError):
542 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000543
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700544 def test_namedtuple_subclass_issue_24931(self):
545 class Point(namedtuple('_Point', ['x', 'y'])):
546 pass
547
548 a = Point(3, 4)
549 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
550
551 a.w = 5
552 self.assertEqual(a.__dict__, {'w': 5})
553
Serhiy Storchaka052b2df2018-12-31 14:15:16 +0200554 def test_field_descriptor(self):
555 Point = namedtuple('Point', 'x y')
556 p = Point(11, 22)
557 self.assertTrue(inspect.isdatadescriptor(Point.x))
558 self.assertEqual(Point.x.__get__(p), 11)
559 self.assertRaises(AttributeError, Point.x.__set__, p, 33)
560 self.assertRaises(AttributeError, Point.x.__delete__, p)
Pablo Galindo3f5fc702018-12-30 09:24:03 +0000561
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700562
Raymond Hettinger499e1932011-02-23 07:56:53 +0000563################################################################################
564### Abstract Base Classes
565################################################################################
566
Raymond Hettingerae650182009-01-28 23:33:59 +0000567class ABCTestCase(unittest.TestCase):
568
569 def validate_abstract_methods(self, abc, *names):
570 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
571
572 # everything should work will all required methods are present
573 C = type('C', (abc,), methodstubs)
574 C()
575
576 # instantiation should fail if a required method is missing
577 for name in names:
578 stubs = methodstubs.copy()
579 del stubs[name]
580 C = type('C', (abc,), stubs)
581 self.assertRaises(TypeError, C, name)
582
Florent Xiclunace153f62010-03-08 15:34:35 +0000583 def validate_isinstance(self, abc, name):
584 stub = lambda s, *args: 0
585
586 C = type('C', (object,), {'__hash__': None})
587 setattr(C, name, stub)
588 self.assertIsInstance(C(), abc)
589 self.assertTrue(issubclass(C, abc))
590
591 C = type('C', (object,), {'__hash__': None})
592 self.assertNotIsInstance(C(), abc)
593 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000594
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000595 def validate_comparison(self, instance):
596 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
597 operators = {}
598 for op in ops:
599 name = '__' + op + '__'
600 operators[name] = getattr(operator, name)
601
602 class Other:
603 def __init__(self):
604 self.right_side = False
605 def __eq__(self, other):
606 self.right_side = True
607 return True
608 __lt__ = __eq__
609 __gt__ = __eq__
610 __le__ = __eq__
611 __ge__ = __eq__
612 __ne__ = __eq__
613 __ror__ = __eq__
614 __rand__ = __eq__
615 __rxor__ = __eq__
616 __rsub__ = __eq__
617
618 for name, op in operators.items():
619 if not hasattr(instance, name):
620 continue
621 other = Other()
622 op(instance, other)
623 self.assertTrue(other.right_side,'Right side not called for %s.%s'
624 % (type(instance), name))
625
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700626def _test_gen():
627 yield
628
Raymond Hettingerae650182009-01-28 23:33:59 +0000629class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000630
Yury Selivanov75445082015-05-11 22:57:16 -0400631 def test_Awaitable(self):
632 def gen():
633 yield
634
635 @types.coroutine
636 def coro():
637 yield
638
639 async def new_coro():
640 pass
641
642 class Bar:
643 def __await__(self):
644 yield
645
646 class MinimalCoro(Coroutine):
647 def send(self, value):
648 return value
649 def throw(self, typ, val=None, tb=None):
650 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400651 def __await__(self):
652 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400653
654 non_samples = [None, int(), gen(), object()]
655 for x in non_samples:
656 self.assertNotIsInstance(x, Awaitable)
657 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
658
659 samples = [Bar(), MinimalCoro()]
660 for x in samples:
661 self.assertIsInstance(x, Awaitable)
662 self.assertTrue(issubclass(type(x), Awaitable))
663
664 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400665 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
666 # flag don't have '__await__' method, hence can't be instances
667 # of Awaitable. Use inspect.isawaitable to detect them.
668 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400669
670 c = new_coro()
671 self.assertIsInstance(c, Awaitable)
Mike53f7a7c2017-12-14 14:04:53 +0300672 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400673
Yury Selivanov56fc6142015-05-29 09:01:29 -0400674 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400675 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400676 self.assertTrue(isinstance(CoroLike(), Awaitable))
677 self.assertTrue(issubclass(CoroLike, Awaitable))
678 CoroLike = None
679 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400680
Yury Selivanov75445082015-05-11 22:57:16 -0400681 def test_Coroutine(self):
682 def gen():
683 yield
684
685 @types.coroutine
686 def coro():
687 yield
688
689 async def new_coro():
690 pass
691
692 class Bar:
693 def __await__(self):
694 yield
695
696 class MinimalCoro(Coroutine):
697 def send(self, value):
698 return value
699 def throw(self, typ, val=None, tb=None):
700 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400701 def __await__(self):
702 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400703
704 non_samples = [None, int(), gen(), object(), Bar()]
705 for x in non_samples:
706 self.assertNotIsInstance(x, Coroutine)
707 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
708
709 samples = [MinimalCoro()]
710 for x in samples:
711 self.assertIsInstance(x, Awaitable)
712 self.assertTrue(issubclass(type(x), Awaitable))
713
714 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400715 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
716 # flag don't have '__await__' method, hence can't be instances
717 # of Coroutine. Use inspect.isawaitable to detect them.
718 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400719
720 c = new_coro()
721 self.assertIsInstance(c, Coroutine)
Mike53f7a7c2017-12-14 14:04:53 +0300722 c.close() # avoid RuntimeWarning that coro() was not awaited
Yury Selivanov75445082015-05-11 22:57:16 -0400723
Yury Selivanov56fc6142015-05-29 09:01:29 -0400724 class CoroLike:
725 def send(self, value):
726 pass
727 def throw(self, typ, val=None, tb=None):
728 pass
729 def close(self):
730 pass
731 def __await__(self):
732 pass
733 self.assertTrue(isinstance(CoroLike(), Coroutine))
734 self.assertTrue(issubclass(CoroLike, Coroutine))
735
736 class CoroLike:
737 def send(self, value):
738 pass
739 def close(self):
740 pass
741 def __await__(self):
742 pass
743 self.assertFalse(isinstance(CoroLike(), Coroutine))
744 self.assertFalse(issubclass(CoroLike, Coroutine))
745
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000746 def test_Hashable(self):
747 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000748 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000749 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000750 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000751 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000752 # Check some hashables
753 samples = [None,
754 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000755 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000756 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000757 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000758 ]
759 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000760 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000761 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000762 self.assertRaises(TypeError, Hashable)
763 # Check direct subclassing
764 class H(Hashable):
765 def __hash__(self):
766 return super().__hash__()
767 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000768 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000769 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000770 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000771
Yury Selivanove0104ae2015-05-14 12:19:16 -0400772 def test_AsyncIterable(self):
773 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400774 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400775 return self
776 self.assertTrue(isinstance(AI(), AsyncIterable))
777 self.assertTrue(issubclass(AI, AsyncIterable))
778 # Check some non-iterables
779 non_samples = [None, object, []]
780 for x in non_samples:
781 self.assertNotIsInstance(x, AsyncIterable)
782 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
783 self.validate_abstract_methods(AsyncIterable, '__aiter__')
784 self.validate_isinstance(AsyncIterable, '__aiter__')
785
786 def test_AsyncIterator(self):
787 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400788 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400789 return self
790 async def __anext__(self):
791 raise StopAsyncIteration
792 self.assertTrue(isinstance(AI(), AsyncIterator))
793 self.assertTrue(issubclass(AI, AsyncIterator))
794 non_samples = [None, object, []]
795 # Check some non-iterables
796 for x in non_samples:
797 self.assertNotIsInstance(x, AsyncIterator)
798 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
799 # Similarly to regular iterators (see issue 10565)
800 class AnextOnly:
801 async def __anext__(self):
802 raise StopAsyncIteration
803 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
804 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
805
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000806 def test_Iterable(self):
807 # Check some non-iterables
808 non_samples = [None, 42, 3.14, 1j]
809 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000810 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000811 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000812 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000813 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000814 tuple(), list(), set(), frozenset(), dict(),
815 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700816 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000817 (x for x in []),
818 ]
819 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000820 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000821 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000822 # Check direct subclassing
823 class I(Iterable):
824 def __iter__(self):
825 return super().__iter__()
826 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000827 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000828 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000829 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700830 # Check None blocking
831 class It:
832 def __iter__(self): return iter([])
833 class ItBlocked(It):
834 __iter__ = None
835 self.assertTrue(issubclass(It, Iterable))
836 self.assertTrue(isinstance(It(), Iterable))
837 self.assertFalse(issubclass(ItBlocked, Iterable))
838 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000839
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700840 def test_Reversible(self):
841 # Check some non-reversibles
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100842 non_samples = [None, 42, 3.14, 1j, set(), frozenset()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700843 for x in non_samples:
844 self.assertNotIsInstance(x, Reversible)
845 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700846 # Check some non-reversible iterables
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100847 non_reversibles = [_test_gen(), (x for x in []), iter([]), reversed([])]
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700848 for x in non_reversibles:
849 self.assertNotIsInstance(x, Reversible)
850 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
851 # Check some reversible iterables
852 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
853 OrderedDict().keys(), OrderedDict().items(),
Rémi Lapeyre6531bf62018-11-06 01:38:54 +0100854 OrderedDict().values(), Counter(), Counter().keys(),
855 Counter().items(), Counter().values(), dict(),
856 dict().keys(), dict().items(), dict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700857 for x in samples:
858 self.assertIsInstance(x, Reversible)
859 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
860 # Check also Mapping, MutableMapping, and Sequence
861 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
862 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
863 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
864 # Check direct subclassing
865 class R(Reversible):
866 def __iter__(self):
867 return iter(list())
868 def __reversed__(self):
869 return iter(list())
870 self.assertEqual(list(reversed(R())), [])
871 self.assertFalse(issubclass(float, R))
872 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700873 # Check reversible non-iterable (which is not Reversible)
874 class RevNoIter:
875 def __reversed__(self): return reversed([])
876 class RevPlusIter(RevNoIter):
877 def __iter__(self): return iter([])
878 self.assertFalse(issubclass(RevNoIter, Reversible))
879 self.assertFalse(isinstance(RevNoIter(), Reversible))
880 self.assertTrue(issubclass(RevPlusIter, Reversible))
881 self.assertTrue(isinstance(RevPlusIter(), Reversible))
882 # Check None blocking
883 class Rev:
884 def __iter__(self): return iter([])
885 def __reversed__(self): return reversed([])
886 class RevItBlocked(Rev):
887 __iter__ = None
888 class RevRevBlocked(Rev):
889 __reversed__ = None
890 self.assertTrue(issubclass(Rev, Reversible))
891 self.assertTrue(isinstance(Rev(), Reversible))
892 self.assertFalse(issubclass(RevItBlocked, Reversible))
893 self.assertFalse(isinstance(RevItBlocked(), Reversible))
894 self.assertFalse(issubclass(RevRevBlocked, Reversible))
895 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700896
Guido van Rossumf0666942016-08-23 10:47:07 -0700897 def test_Collection(self):
898 # Check some non-collections
899 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
900 for x in non_collections:
901 self.assertNotIsInstance(x, Collection)
902 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
903 # Check some non-collection iterables
904 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800905 (x for x in [])]
Guido van Rossumf0666942016-08-23 10:47:07 -0700906 for x in non_col_iterables:
907 self.assertNotIsInstance(x, Collection)
908 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
909 # Check some collections
910 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
Raymond Hettinger02556fb2018-01-11 21:53:49 -0800911 list(), dict().keys(), dict().items(), dict().values()]
Guido van Rossumf0666942016-08-23 10:47:07 -0700912 for x in samples:
913 self.assertIsInstance(x, Collection)
914 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
915 # Check also Mapping, MutableMapping, etc.
916 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
917 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
918 self.assertTrue(issubclass(MutableMapping, Collection),
919 repr(MutableMapping))
920 self.assertTrue(issubclass(Set, Collection), repr(Set))
921 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
922 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
923 # Check direct subclassing
924 class Col(Collection):
925 def __iter__(self):
926 return iter(list())
927 def __len__(self):
928 return 0
929 def __contains__(self, item):
930 return False
931 class DerCol(Col): pass
932 self.assertEqual(list(iter(Col())), [])
933 self.assertFalse(issubclass(list, Col))
934 self.assertFalse(issubclass(set, Col))
935 self.assertFalse(issubclass(float, Col))
936 self.assertEqual(list(iter(DerCol())), [])
937 self.assertFalse(issubclass(list, DerCol))
938 self.assertFalse(issubclass(set, DerCol))
939 self.assertFalse(issubclass(float, DerCol))
940 self.validate_abstract_methods(Collection, '__len__', '__iter__',
941 '__contains__')
942 # Check sized container non-iterable (which is not Collection) etc.
943 class ColNoIter:
944 def __len__(self): return 0
945 def __contains__(self, item): return False
946 class ColNoSize:
947 def __iter__(self): return iter([])
948 def __contains__(self, item): return False
949 class ColNoCont:
950 def __iter__(self): return iter([])
951 def __len__(self): return 0
952 self.assertFalse(issubclass(ColNoIter, Collection))
953 self.assertFalse(isinstance(ColNoIter(), Collection))
954 self.assertFalse(issubclass(ColNoSize, Collection))
955 self.assertFalse(isinstance(ColNoSize(), Collection))
956 self.assertFalse(issubclass(ColNoCont, Collection))
957 self.assertFalse(isinstance(ColNoCont(), Collection))
958 # Check None blocking
959 class SizeBlock:
960 def __iter__(self): return iter([])
961 def __contains__(self): return False
962 __len__ = None
963 class IterBlock:
964 def __len__(self): return 0
965 def __contains__(self): return True
966 __iter__ = None
967 self.assertFalse(issubclass(SizeBlock, Collection))
968 self.assertFalse(isinstance(SizeBlock(), Collection))
969 self.assertFalse(issubclass(IterBlock, Collection))
970 self.assertFalse(isinstance(IterBlock(), Collection))
971 # Check None blocking in subclass
972 class ColImpl:
973 def __iter__(self):
974 return iter(list())
975 def __len__(self):
976 return 0
977 def __contains__(self, item):
978 return False
979 class NonCol(ColImpl):
980 __contains__ = None
981 self.assertFalse(issubclass(NonCol, Collection))
982 self.assertFalse(isinstance(NonCol(), Collection))
983
984
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000985 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000986 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000987 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000988 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000989 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000990 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000991 iter(tuple()), iter(list()), iter(dict()),
992 iter(set()), iter(frozenset()),
993 iter(dict().keys()), iter(dict().items()),
994 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700995 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000996 (x for x in []),
997 ]
998 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000999 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001000 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +00001001 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
1002
1003 # Issue 10565
1004 class NextOnly:
1005 def __next__(self):
1006 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -08001007 return
Raymond Hettingeread22222010-11-29 03:56:12 +00001008 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001009
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -04001010 def test_Generator(self):
1011 class NonGen1:
1012 def __iter__(self): return self
1013 def __next__(self): return None
1014 def close(self): pass
1015 def throw(self, typ, val=None, tb=None): pass
1016
1017 class NonGen2:
1018 def __iter__(self): return self
1019 def __next__(self): return None
1020 def close(self): pass
1021 def send(self, value): return value
1022
1023 class NonGen3:
1024 def close(self): pass
1025 def send(self, value): return value
1026 def throw(self, typ, val=None, tb=None): pass
1027
1028 non_samples = [
1029 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1030 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
1031 for x in non_samples:
1032 self.assertNotIsInstance(x, Generator)
1033 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
1034
1035 class Gen:
1036 def __iter__(self): return self
1037 def __next__(self): return None
1038 def close(self): pass
1039 def send(self, value): return value
1040 def throw(self, typ, val=None, tb=None): pass
1041
1042 class MinimalGen(Generator):
1043 def send(self, value):
1044 return value
1045 def throw(self, typ, val=None, tb=None):
1046 super().throw(typ, val, tb)
1047
1048 def gen():
1049 yield 1
1050
1051 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
1052 for x in samples:
1053 self.assertIsInstance(x, Iterator)
1054 self.assertIsInstance(x, Generator)
1055 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
1056 self.validate_abstract_methods(Generator, 'send', 'throw')
1057
1058 # mixin tests
1059 mgen = MinimalGen()
1060 self.assertIs(mgen, iter(mgen))
1061 self.assertIs(mgen.send(None), next(mgen))
1062 self.assertEqual(2, mgen.send(2))
1063 self.assertIsNone(mgen.close())
1064 self.assertRaises(ValueError, mgen.throw, ValueError)
1065 self.assertRaisesRegex(ValueError, "^huhu$",
1066 mgen.throw, ValueError, ValueError("huhu"))
1067 self.assertRaises(StopIteration, mgen.throw, StopIteration())
1068
1069 class FailOnClose(Generator):
1070 def send(self, value): return value
1071 def throw(self, *args): raise ValueError
1072
1073 self.assertRaises(ValueError, FailOnClose().close)
1074
1075 class IgnoreGeneratorExit(Generator):
1076 def send(self, value): return value
1077 def throw(self, *args): pass
1078
1079 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
1080
Yury Selivanov22214ab2016-11-16 18:25:04 -05001081 def test_AsyncGenerator(self):
1082 class NonAGen1:
1083 def __aiter__(self): return self
1084 def __anext__(self): return None
1085 def aclose(self): pass
1086 def athrow(self, typ, val=None, tb=None): pass
1087
1088 class NonAGen2:
1089 def __aiter__(self): return self
1090 def __anext__(self): return None
1091 def aclose(self): pass
1092 def asend(self, value): return value
1093
1094 class NonAGen3:
1095 def aclose(self): pass
1096 def asend(self, value): return value
1097 def athrow(self, typ, val=None, tb=None): pass
1098
1099 non_samples = [
1100 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1101 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
1102 for x in non_samples:
1103 self.assertNotIsInstance(x, AsyncGenerator)
1104 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
1105
1106 class Gen:
1107 def __aiter__(self): return self
1108 async def __anext__(self): return None
1109 async def aclose(self): pass
1110 async def asend(self, value): return value
1111 async def athrow(self, typ, val=None, tb=None): pass
1112
1113 class MinimalAGen(AsyncGenerator):
1114 async def asend(self, value):
1115 return value
1116 async def athrow(self, typ, val=None, tb=None):
1117 await super().athrow(typ, val, tb)
1118
1119 async def gen():
1120 yield 1
1121
1122 samples = [gen(), Gen(), MinimalAGen()]
1123 for x in samples:
1124 self.assertIsInstance(x, AsyncIterator)
1125 self.assertIsInstance(x, AsyncGenerator)
1126 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1127 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1128
1129 def run_async(coro):
1130 result = None
1131 while True:
1132 try:
1133 coro.send(None)
1134 except StopIteration as ex:
1135 result = ex.args[0] if ex.args else None
1136 break
1137 return result
1138
1139 # mixin tests
1140 mgen = MinimalAGen()
1141 self.assertIs(mgen, mgen.__aiter__())
1142 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1143 self.assertEqual(2, run_async(mgen.asend(2)))
1144 self.assertIsNone(run_async(mgen.aclose()))
1145 with self.assertRaises(ValueError):
1146 run_async(mgen.athrow(ValueError))
1147
1148 class FailOnClose(AsyncGenerator):
1149 async def asend(self, value): return value
1150 async def athrow(self, *args): raise ValueError
1151
1152 with self.assertRaises(ValueError):
1153 run_async(FailOnClose().aclose())
1154
1155 class IgnoreGeneratorExit(AsyncGenerator):
1156 async def asend(self, value): return value
1157 async def athrow(self, *args): pass
1158
1159 with self.assertRaises(RuntimeError):
1160 run_async(IgnoreGeneratorExit().aclose())
1161
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001162 def test_Sized(self):
1163 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001164 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001165 (x for x in []),
1166 ]
1167 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001168 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001169 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001170 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001171 tuple(), list(), set(), frozenset(), dict(),
1172 dict().keys(), dict().items(), dict().values(),
1173 ]
1174 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001175 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001176 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001177 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001178 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001179
1180 def test_Container(self):
1181 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001182 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001183 (x for x in []),
1184 ]
1185 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001186 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001187 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001188 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001189 tuple(), list(), set(), frozenset(), dict(),
1190 dict().keys(), dict().items(),
1191 ]
1192 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001193 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001194 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001195 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001196 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001197
1198 def test_Callable(self):
1199 non_samples = [None, 42, 3.14, 1j,
1200 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001201 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001202 (x for x in []),
1203 ]
1204 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001205 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001206 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001207 samples = [lambda: None,
1208 type, int, object,
1209 len,
1210 list.append, [].append,
1211 ]
1212 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001213 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001214 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001215 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001216 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001217
1218 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001219 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001220 class C(B):
1221 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001222 self.assertTrue(issubclass(C, B))
1223 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001224
1225 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001226 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001227 class C:
1228 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001229 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001230 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001231 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001232
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001233class WithSet(MutableSet):
1234
1235 def __init__(self, it=()):
1236 self.data = set(it)
1237
1238 def __len__(self):
1239 return len(self.data)
1240
1241 def __iter__(self):
1242 return iter(self.data)
1243
1244 def __contains__(self, item):
1245 return item in self.data
1246
1247 def add(self, item):
1248 self.data.add(item)
1249
1250 def discard(self, item):
1251 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001252
Raymond Hettingerae650182009-01-28 23:33:59 +00001253class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001254
1255 # XXX For now, we only test some virtual inheritance properties.
1256 # We should also test the proper behavior of the collection ABCs
1257 # as real base classes or mix-in classes.
1258
1259 def test_Set(self):
1260 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001261 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001262 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001263 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001264 class MySet(Set):
1265 def __contains__(self, x):
1266 return False
1267 def __len__(self):
1268 return 0
1269 def __iter__(self):
1270 return iter([])
1271 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001272
Benjamin Peterson41181742008-07-02 20:22:54 +00001273 def test_hash_Set(self):
1274 class OneTwoThreeSet(Set):
1275 def __init__(self):
1276 self.contents = [1, 2, 3]
1277 def __contains__(self, x):
1278 return x in self.contents
1279 def __len__(self):
1280 return len(self.contents)
1281 def __iter__(self):
1282 return iter(self.contents)
1283 def __hash__(self):
1284 return self._hash()
1285 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001286 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001287
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001288 def test_isdisjoint_Set(self):
1289 class MySet(Set):
1290 def __init__(self, itr):
1291 self.contents = itr
1292 def __contains__(self, x):
1293 return x in self.contents
1294 def __iter__(self):
1295 return iter(self.contents)
1296 def __len__(self):
1297 return len([x for x in self.contents])
1298 s1 = MySet((1, 2, 3))
1299 s2 = MySet((4, 5, 6))
1300 s3 = MySet((1, 5, 6))
1301 self.assertTrue(s1.isdisjoint(s2))
1302 self.assertFalse(s1.isdisjoint(s3))
1303
1304 def test_equality_Set(self):
1305 class MySet(Set):
1306 def __init__(self, itr):
1307 self.contents = itr
1308 def __contains__(self, x):
1309 return x in self.contents
1310 def __iter__(self):
1311 return iter(self.contents)
1312 def __len__(self):
1313 return len([x for x in self.contents])
1314 s1 = MySet((1,))
1315 s2 = MySet((1, 2))
1316 s3 = MySet((3, 4))
1317 s4 = MySet((3, 4))
1318 self.assertTrue(s2 > s1)
1319 self.assertTrue(s1 < s2)
1320 self.assertFalse(s2 <= s1)
1321 self.assertFalse(s2 <= s3)
1322 self.assertFalse(s1 >= s2)
1323 self.assertEqual(s3, s4)
1324 self.assertNotEqual(s2, s3)
1325
1326 def test_arithmetic_Set(self):
1327 class MySet(Set):
1328 def __init__(self, itr):
1329 self.contents = itr
1330 def __contains__(self, x):
1331 return x in self.contents
1332 def __iter__(self):
1333 return iter(self.contents)
1334 def __len__(self):
1335 return len([x for x in self.contents])
1336 s1 = MySet((1, 2, 3))
1337 s2 = MySet((3, 4, 5))
1338 s3 = s1 & s2
1339 self.assertEqual(s3, MySet((3,)))
1340
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001341 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001342 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001343 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001344 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001345 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001346 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1347 'add', 'discard')
1348
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001349 def test_issue_5647(self):
1350 # MutableSet.__iand__ mutated the set during iteration
1351 s = WithSet('abcd')
1352 s &= WithSet('cdef') # This used to fail
1353 self.assertEqual(set(s), set('cd'))
1354
Raymond Hettingerae650182009-01-28 23:33:59 +00001355 def test_issue_4920(self):
1356 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001357 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001358 __slots__=['__s']
1359 def __init__(self,items=None):
1360 if items is None:
1361 items=[]
1362 self.__s=set(items)
1363 def __contains__(self,v):
1364 return v in self.__s
1365 def __iter__(self):
1366 return iter(self.__s)
1367 def __len__(self):
1368 return len(self.__s)
1369 def add(self,v):
1370 result=v not in self.__s
1371 self.__s.add(v)
1372 return result
1373 def discard(self,v):
1374 result=v in self.__s
1375 self.__s.discard(v)
1376 return result
1377 def __repr__(self):
1378 return "MySet(%s)" % repr(list(self))
1379 s = MySet([5,43,2,1])
1380 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001381
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001382 def test_issue8750(self):
1383 empty = WithSet()
1384 full = WithSet(range(10))
1385 s = WithSet(full)
1386 s -= s
1387 self.assertEqual(s, empty)
1388 s = WithSet(full)
1389 s ^= s
1390 self.assertEqual(s, empty)
1391 s = WithSet(full)
1392 s &= s
1393 self.assertEqual(s, full)
1394 s |= s
1395 self.assertEqual(s, full)
1396
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001397 def test_issue16373(self):
1398 # Recursion error comparing comparable and noncomparable
1399 # Set instances
1400 class MyComparableSet(Set):
1401 def __contains__(self, x):
1402 return False
1403 def __len__(self):
1404 return 0
1405 def __iter__(self):
1406 return iter([])
1407 class MyNonComparableSet(Set):
1408 def __contains__(self, x):
1409 return False
1410 def __len__(self):
1411 return 0
1412 def __iter__(self):
1413 return iter([])
1414 def __le__(self, x):
1415 return NotImplemented
1416 def __lt__(self, x):
1417 return NotImplemented
1418
1419 cs = MyComparableSet()
1420 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001421 self.assertFalse(ncs < cs)
1422 self.assertTrue(ncs <= cs)
1423 self.assertFalse(ncs > cs)
1424 self.assertTrue(ncs >= cs)
1425
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001426 def test_issue26915(self):
1427 # Container membership test should check identity first
1428 class CustomEqualObject:
1429 def __eq__(self, other):
1430 return False
Xiang Zhangd5d32492017-03-08 11:04:24 +08001431 class CustomSequence(Sequence):
1432 def __init__(self, seq):
1433 self._seq = seq
1434 def __getitem__(self, index):
1435 return self._seq[index]
1436 def __len__(self):
1437 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001438
1439 nan = float('nan')
1440 obj = CustomEqualObject()
Xiang Zhangd5d32492017-03-08 11:04:24 +08001441 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001442 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001443 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001444 ItemsView({1: nan, 2: obj}),
1445 ValuesView({1: nan, 2: obj})
1446 ]
1447 for container in containers:
1448 for elem in container:
1449 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001450 self.assertEqual(seq.index(nan), 0)
1451 self.assertEqual(seq.index(obj), 1)
1452 self.assertEqual(seq.count(nan), 2)
1453 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001454
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001455 def assertSameSet(self, s1, s2):
1456 # coerce both to a real set then check equality
1457 self.assertSetEqual(set(s1), set(s2))
1458
1459 def test_Set_interoperability_with_real_sets(self):
1460 # Issue: 8743
1461 class ListSet(Set):
1462 def __init__(self, elements=()):
1463 self.data = []
1464 for elem in elements:
1465 if elem not in self.data:
1466 self.data.append(elem)
1467 def __contains__(self, elem):
1468 return elem in self.data
1469 def __iter__(self):
1470 return iter(self.data)
1471 def __len__(self):
1472 return len(self.data)
1473 def __repr__(self):
1474 return 'Set({!r})'.format(self.data)
1475
1476 r1 = set('abc')
1477 r2 = set('bcd')
1478 r3 = set('abcde')
1479 f1 = ListSet('abc')
1480 f2 = ListSet('bcd')
1481 f3 = ListSet('abcde')
1482 l1 = list('abccba')
1483 l2 = list('bcddcb')
1484 l3 = list('abcdeedcba')
1485
1486 target = r1 & r2
1487 self.assertSameSet(f1 & f2, target)
1488 self.assertSameSet(f1 & r2, target)
1489 self.assertSameSet(r2 & f1, target)
1490 self.assertSameSet(f1 & l2, target)
1491
1492 target = r1 | r2
1493 self.assertSameSet(f1 | f2, target)
1494 self.assertSameSet(f1 | r2, target)
1495 self.assertSameSet(r2 | f1, target)
1496 self.assertSameSet(f1 | l2, target)
1497
1498 fwd_target = r1 - r2
1499 rev_target = r2 - r1
1500 self.assertSameSet(f1 - f2, fwd_target)
1501 self.assertSameSet(f2 - f1, rev_target)
1502 self.assertSameSet(f1 - r2, fwd_target)
1503 self.assertSameSet(f2 - r1, rev_target)
1504 self.assertSameSet(r1 - f2, fwd_target)
1505 self.assertSameSet(r2 - f1, rev_target)
1506 self.assertSameSet(f1 - l2, fwd_target)
1507 self.assertSameSet(f2 - l1, rev_target)
1508
1509 target = r1 ^ r2
1510 self.assertSameSet(f1 ^ f2, target)
1511 self.assertSameSet(f1 ^ r2, target)
1512 self.assertSameSet(r2 ^ f1, target)
1513 self.assertSameSet(f1 ^ l2, target)
1514
1515 # Don't change the following to use assertLess or other
1516 # "more specific" unittest assertions. The current
1517 # assertTrue/assertFalse style makes the pattern of test
1518 # case combinations clear and allows us to know for sure
1519 # the exact operator being invoked.
1520
1521 # proper subset
1522 self.assertTrue(f1 < f3)
1523 self.assertFalse(f1 < f1)
1524 self.assertFalse(f1 < f2)
1525 self.assertTrue(r1 < f3)
1526 self.assertFalse(r1 < f1)
1527 self.assertFalse(r1 < f2)
1528 self.assertTrue(r1 < r3)
1529 self.assertFalse(r1 < r1)
1530 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001531 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001532 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001533 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001534 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001535 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001536 f1 < l2
1537
1538 # any subset
1539 self.assertTrue(f1 <= f3)
1540 self.assertTrue(f1 <= f1)
1541 self.assertFalse(f1 <= f2)
1542 self.assertTrue(r1 <= f3)
1543 self.assertTrue(r1 <= f1)
1544 self.assertFalse(r1 <= f2)
1545 self.assertTrue(r1 <= r3)
1546 self.assertTrue(r1 <= r1)
1547 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001548 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001549 f1 <= l3
1550 with self.assertRaises(TypeError):
1551 f1 <= l1
1552 with self.assertRaises(TypeError):
1553 f1 <= l2
1554
1555 # proper superset
1556 self.assertTrue(f3 > f1)
1557 self.assertFalse(f1 > f1)
1558 self.assertFalse(f2 > f1)
1559 self.assertTrue(r3 > r1)
1560 self.assertFalse(f1 > r1)
1561 self.assertFalse(f2 > r1)
1562 self.assertTrue(r3 > r1)
1563 self.assertFalse(r1 > r1)
1564 self.assertFalse(r2 > r1)
1565 with self.assertRaises(TypeError):
1566 f1 > l3
1567 with self.assertRaises(TypeError):
1568 f1 > l1
1569 with self.assertRaises(TypeError):
1570 f1 > l2
1571
1572 # any superset
1573 self.assertTrue(f3 >= f1)
1574 self.assertTrue(f1 >= f1)
1575 self.assertFalse(f2 >= f1)
1576 self.assertTrue(r3 >= r1)
1577 self.assertTrue(f1 >= r1)
1578 self.assertFalse(f2 >= r1)
1579 self.assertTrue(r3 >= r1)
1580 self.assertTrue(r1 >= r1)
1581 self.assertFalse(r2 >= r1)
1582 with self.assertRaises(TypeError):
1583 f1 >= l3
1584 with self.assertRaises(TypeError):
1585 f1 >=l1
1586 with self.assertRaises(TypeError):
1587 f1 >= l2
1588
1589 # equality
1590 self.assertTrue(f1 == f1)
1591 self.assertTrue(r1 == f1)
1592 self.assertTrue(f1 == r1)
1593 self.assertFalse(f1 == f3)
1594 self.assertFalse(r1 == f3)
1595 self.assertFalse(f1 == r3)
1596 self.assertFalse(f1 == l3)
1597 self.assertFalse(f1 == l1)
1598 self.assertFalse(f1 == l2)
1599
1600 # inequality
1601 self.assertFalse(f1 != f1)
1602 self.assertFalse(r1 != f1)
1603 self.assertFalse(f1 != r1)
1604 self.assertTrue(f1 != f3)
1605 self.assertTrue(r1 != f3)
1606 self.assertTrue(f1 != r3)
1607 self.assertTrue(f1 != l3)
1608 self.assertTrue(f1 != l1)
1609 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001610
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001611 def test_Mapping(self):
1612 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001613 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001614 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001615 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1616 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001617 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001618 def __len__(self):
1619 return 0
1620 def __getitem__(self, i):
1621 raise IndexError
1622 def __iter__(self):
1623 return iter(())
1624 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001625 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001626
1627 def test_MutableMapping(self):
1628 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001629 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001630 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001631 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1632 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001633
Raymond Hettinger9117c752010-08-22 07:44:24 +00001634 def test_MutableMapping_subclass(self):
1635 # Test issue 9214
1636 mymap = UserDict()
1637 mymap['red'] = 5
1638 self.assertIsInstance(mymap.keys(), Set)
1639 self.assertIsInstance(mymap.keys(), KeysView)
1640 self.assertIsInstance(mymap.items(), Set)
1641 self.assertIsInstance(mymap.items(), ItemsView)
1642
1643 mymap = UserDict()
1644 mymap['red'] = 5
1645 z = mymap.keys() | {'orange'}
1646 self.assertIsInstance(z, set)
1647 list(z)
1648 mymap['blue'] = 7 # Shouldn't affect 'z'
1649 self.assertEqual(sorted(z), ['orange', 'red'])
1650
1651 mymap = UserDict()
1652 mymap['red'] = 5
1653 z = mymap.items() | {('orange', 3)}
1654 self.assertIsInstance(z, set)
1655 list(z)
1656 mymap['blue'] = 7 # Shouldn't affect 'z'
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001657 self.assertEqual(z, {('orange', 3), ('red', 5)})
Raymond Hettinger9117c752010-08-22 07:44:24 +00001658
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001659 def test_Sequence(self):
1660 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001661 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001662 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001663 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001664 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001665 self.assertIsInstance(memoryview(b""), Sequence)
1666 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001667 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001668 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1669 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001670
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001671 def test_Sequence_mixins(self):
1672 class SequenceSubclass(Sequence):
1673 def __init__(self, seq=()):
1674 self.seq = seq
1675
1676 def __getitem__(self, index):
1677 return self.seq[index]
1678
1679 def __len__(self):
1680 return len(self.seq)
1681
1682 # Compare Sequence.index() behavior to (list|str).index() behavior
1683 def assert_index_same(seq1, seq2, index_args):
1684 try:
1685 expected = seq1.index(*index_args)
1686 except ValueError:
1687 with self.assertRaises(ValueError):
1688 seq2.index(*index_args)
1689 else:
1690 actual = seq2.index(*index_args)
1691 self.assertEqual(
1692 actual, expected, '%r.index%s' % (seq1, index_args))
1693
1694 for ty in list, str:
1695 nativeseq = ty('abracadabra')
1696 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1697 seqseq = SequenceSubclass(nativeseq)
1698 for letter in set(nativeseq) | {'z'}:
1699 assert_index_same(nativeseq, seqseq, (letter,))
1700 for start in range(-3, len(nativeseq) + 3):
1701 assert_index_same(nativeseq, seqseq, (letter, start))
1702 for stop in range(-3, len(nativeseq) + 3):
1703 assert_index_same(
1704 nativeseq, seqseq, (letter, start, stop))
1705
Guido van Rossumd05eb002007-11-21 22:26:24 +00001706 def test_ByteString(self):
1707 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001708 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001709 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001710 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001711 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001712 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001713 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001714 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001715
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001716 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001717 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001718 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001719 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001720 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001721 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001722 self.assertTrue(issubclass(sample, MutableSequence))
1723 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001724 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1725 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001726
Eli Bendersky0716a572011-03-04 10:38:14 +00001727 def test_MutableSequence_mixins(self):
Mike53f7a7c2017-12-14 14:04:53 +03001728 # Test the mixins of MutableSequence by creating a minimal concrete
Eli Bendersky0716a572011-03-04 10:38:14 +00001729 # class inherited from it.
1730 class MutableSequenceSubclass(MutableSequence):
1731 def __init__(self):
1732 self.lst = []
1733
1734 def __setitem__(self, index, value):
1735 self.lst[index] = value
1736
1737 def __getitem__(self, index):
1738 return self.lst[index]
1739
1740 def __len__(self):
1741 return len(self.lst)
1742
1743 def __delitem__(self, index):
1744 del self.lst[index]
1745
1746 def insert(self, index, value):
1747 self.lst.insert(index, value)
1748
1749 mss = MutableSequenceSubclass()
1750 mss.append(0)
1751 mss.extend((1, 2, 3, 4))
1752 self.assertEqual(len(mss), 5)
1753 self.assertEqual(mss[3], 3)
1754 mss.reverse()
1755 self.assertEqual(mss[3], 1)
1756 mss.pop()
1757 self.assertEqual(len(mss), 4)
1758 mss.remove(3)
1759 self.assertEqual(len(mss), 3)
1760 mss += (10, 20, 30)
1761 self.assertEqual(len(mss), 6)
1762 self.assertEqual(mss[-1], 30)
1763 mss.clear()
1764 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001765
Naris R1b5f9c92018-08-31 02:56:14 +10001766 # issue 34427
1767 # extending self should not cause infinite loop
1768 items = 'ABCD'
1769 mss2 = MutableSequenceSubclass()
1770 mss2.extend(items + items)
1771 mss.clear()
1772 mss.extend(items)
1773 mss.extend(mss)
1774 self.assertEqual(len(mss), len(mss2))
1775 self.assertEqual(list(mss), list(mss2))
1776
1777
Raymond Hettinger499e1932011-02-23 07:56:53 +00001778################################################################################
1779### Counter
1780################################################################################
1781
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001782class CounterSubclassWithSetItem(Counter):
1783 # Test a counter subclass that overrides __setitem__
1784 def __init__(self, *args, **kwds):
1785 self.called = False
1786 Counter.__init__(self, *args, **kwds)
1787 def __setitem__(self, key, value):
1788 self.called = True
1789 Counter.__setitem__(self, key, value)
1790
1791class CounterSubclassWithGet(Counter):
1792 # Test a counter subclass that overrides get()
1793 def __init__(self, *args, **kwds):
1794 self.called = False
1795 Counter.__init__(self, *args, **kwds)
1796 def get(self, key, default):
1797 self.called = True
1798 return Counter.get(self, key, default)
1799
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001800class TestCounter(unittest.TestCase):
1801
1802 def test_basics(self):
1803 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001804 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1805 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001806 self.assertIsInstance(c, dict)
1807 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001808 self.assertTrue(issubclass(Counter, dict))
1809 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001810 self.assertEqual(len(c), 3)
1811 self.assertEqual(sum(c.values()), 6)
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001812 self.assertEqual(list(c.values()), [3, 2, 1])
1813 self.assertEqual(list(c.keys()), ['a', 'b', 'c'])
1814 self.assertEqual(list(c), ['a', 'b', 'c'])
1815 self.assertEqual(list(c.items()),
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001816 [('a', 3), ('b', 2), ('c', 1)])
1817 self.assertEqual(c['b'], 2)
1818 self.assertEqual(c['z'], 0)
1819 self.assertEqual(c.__contains__('c'), True)
1820 self.assertEqual(c.__contains__('z'), False)
1821 self.assertEqual(c.get('b', 10), 2)
1822 self.assertEqual(c.get('z', 10), 10)
1823 self.assertEqual(c, dict(a=3, b=2, c=1))
1824 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1825 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1826 for i in range(5):
1827 self.assertEqual(c.most_common(i),
1828 [('a', 3), ('b', 2), ('c', 1)][:i])
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001829 self.assertEqual(''.join(c.elements()), 'aaabbc')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001830 c['a'] += 1 # increment an existing value
1831 c['b'] -= 2 # sub existing value to zero
1832 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001833 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001834 c['d'] -= 2 # sub from a missing value
1835 c['e'] = -5 # directly assign a missing value
1836 c['f'] += 4 # add to a missing value
1837 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01001838 self.assertEqual(''.join(c.elements()), 'aaaaffff')
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001839 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001840 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001841 for i in range(3):
1842 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001843 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001844 c.clear()
1845 self.assertEqual(c, {})
1846 self.assertEqual(repr(c), 'Counter()')
1847 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1848 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001849 c.update(dict(a=5, b=3))
1850 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001851 c.update(Counter('a' * 50 + 'b' * 30))
1852 c.update() # test case with no args
1853 c.__init__('a' * 500 + 'b' * 300)
1854 c.__init__('cdc')
1855 c.__init__()
1856 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1857 self.assertEqual(c.setdefault('d', 5), 1)
1858 self.assertEqual(c['d'], 1)
1859 self.assertEqual(c.setdefault('e', 5), 5)
1860 self.assertEqual(c['e'], 5)
1861
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001862 def test_init(self):
1863 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1864 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1865 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1866 self.assertRaises(TypeError, Counter, 42)
1867 self.assertRaises(TypeError, Counter, (), ())
1868 self.assertRaises(TypeError, Counter.__init__)
1869
1870 def test_update(self):
1871 c = Counter()
1872 c.update(self=42)
1873 self.assertEqual(list(c.items()), [('self', 42)])
1874 c = Counter()
1875 c.update(iterable=42)
1876 self.assertEqual(list(c.items()), [('iterable', 42)])
1877 c = Counter()
1878 c.update(iterable=None)
1879 self.assertEqual(list(c.items()), [('iterable', None)])
1880 self.assertRaises(TypeError, Counter().update, 42)
1881 self.assertRaises(TypeError, Counter().update, {}, {})
1882 self.assertRaises(TypeError, Counter.update)
1883
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001884 def test_copying(self):
1885 # Check that counters are copyable, deepcopyable, picklable, and
1886 #have a repr/eval round-trip
1887 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001888 def check(dup):
1889 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1890 self.assertIsNot(dup, words, msg)
1891 self.assertEqual(dup, words)
1892 check(words.copy())
1893 check(copy.copy(words))
1894 check(copy.deepcopy(words))
1895 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1896 with self.subTest(proto=proto):
1897 check(pickle.loads(pickle.dumps(words, proto)))
1898 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001899 update_test = Counter()
1900 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001901 check(update_test)
1902 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001903
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001904 def test_copy_subclass(self):
1905 class MyCounter(Counter):
1906 pass
1907 c = MyCounter('slartibartfast')
1908 d = c.copy()
1909 self.assertEqual(d, c)
1910 self.assertEqual(len(d), len(c))
1911 self.assertEqual(type(d), type(c))
1912
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001913 def test_conversions(self):
1914 # Convert to: set, list, dict
1915 s = 'she sells sea shells by the sea shore'
1916 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1917 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1918 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1919 self.assertEqual(set(Counter(s)), set(s))
1920
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001921 def test_invariant_for_the_in_operator(self):
1922 c = Counter(a=10, b=-2, c=0)
1923 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001924 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001925 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001926
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001927 def test_multiset_operations(self):
1928 # Verify that adding a zero counter will strip zeros and negatives
1929 c = Counter(a=10, b=-2, c=0) + Counter()
1930 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001931
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001932 elements = 'abcd'
1933 for i in range(1000):
1934 # test random pairs of multisets
1935 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001936 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001937 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001938 q.update(h=1, i=-1, j=0)
1939 for counterop, numberop in [
1940 (Counter.__add__, lambda x, y: max(0, x+y)),
1941 (Counter.__sub__, lambda x, y: max(0, x-y)),
1942 (Counter.__or__, lambda x, y: max(0,x,y)),
1943 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001944 ]:
1945 result = counterop(p, q)
1946 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001947 self.assertEqual(numberop(p[x], q[x]), result[x],
1948 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001949 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001950 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001951
1952 elements = 'abcdef'
1953 for i in range(100):
1954 # verify that random multisets with no repeats are exactly like sets
1955 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1956 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1957 for counterop, setop in [
1958 (Counter.__sub__, set.__sub__),
1959 (Counter.__or__, set.__or__),
1960 (Counter.__and__, set.__and__),
1961 ]:
1962 counter_result = counterop(p, q)
1963 set_result = setop(set(p.elements()), set(q.elements()))
1964 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001965
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001966 def test_inplace_operations(self):
1967 elements = 'abcd'
1968 for i in range(1000):
1969 # test random pairs of multisets
1970 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1971 p.update(e=1, f=-1, g=0)
1972 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1973 q.update(h=1, i=-1, j=0)
1974 for inplace_op, regular_op in [
1975 (Counter.__iadd__, Counter.__add__),
1976 (Counter.__isub__, Counter.__sub__),
1977 (Counter.__ior__, Counter.__or__),
1978 (Counter.__iand__, Counter.__and__),
1979 ]:
1980 c = p.copy()
1981 c_id = id(c)
1982 regular_result = regular_op(c, q)
1983 inplace_result = inplace_op(c, q)
1984 self.assertEqual(inplace_result, regular_result)
1985 self.assertEqual(id(inplace_result), c_id)
1986
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001987 def test_subtract(self):
1988 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1989 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1990 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1991 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1992 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1993 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1994 c = Counter('aaabbcd')
1995 c.subtract('aaaabbcce')
1996 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001997
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001998 c = Counter()
1999 c.subtract(self=42)
2000 self.assertEqual(list(c.items()), [('self', -42)])
2001 c = Counter()
2002 c.subtract(iterable=42)
2003 self.assertEqual(list(c.items()), [('iterable', -42)])
2004 self.assertRaises(TypeError, Counter().subtract, 42)
2005 self.assertRaises(TypeError, Counter().subtract, {}, {})
2006 self.assertRaises(TypeError, Counter.subtract)
2007
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07002008 def test_unary(self):
2009 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2010 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
2011 self.assertEqual(dict(-c), dict(a=5))
2012
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07002013 def test_repr_nonsortable(self):
2014 c = Counter(a=2, b=None)
2015 r = repr(c)
2016 self.assertIn("'a': 2", r)
2017 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07002018
Raymond Hettinger426e0522011-01-03 02:12:02 +00002019 def test_helper_function(self):
2020 # two paths, one for real dicts and one for other mappings
2021 elems = list('abracadabra')
2022
2023 d = dict()
2024 _count_elements(d, elems)
2025 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
2026
2027 m = OrderedDict()
2028 _count_elements(m, elems)
2029 self.assertEqual(m,
2030 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
2031
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002032 # test fidelity to the pure python version
2033 c = CounterSubclassWithSetItem('abracadabra')
2034 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07002035 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002036 c = CounterSubclassWithGet('abracadabra')
2037 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07002038 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002039
Raymond Hettinger499e1932011-02-23 07:56:53 +00002040
2041################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00002042### Run tests
2043################################################################################
2044
Guido van Rossumd8faa362007-04-27 19:54:29 +00002045def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00002046 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002047 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00002048 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06002049 TestUserObjects,
2050 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002051 support.run_unittest(*test_classes)
2052 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002053
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002054
Guido van Rossumd8faa362007-04-27 19:54:29 +00002055if __name__ == "__main__":
2056 test_main(verbose=True)