blob: 3bf15786189b307724922196ff2573517e9859d7 [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001"""Unit tests for collections.py."""
2
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02003import collections
4import copy
5import doctest
Raymond Hettinger499b2ee2009-05-27 01:53:46 +00006import keyword
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02007import operator
8import pickle
9from random import choice, randrange
Raymond Hettinger499b2ee2009-05-27 01:53:46 +000010import re
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020011import string
R. David Murray378c0cf2010-02-24 01:46:21 +000012import sys
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020013from test import support
Yury Selivanov75445082015-05-11 22:57:16 -040014import types
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020015import unittest
16
17from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger573b44c2015-05-22 16:56:32 -070018from collections import UserDict, UserString, UserList
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000019from collections import ChainMap
Raymond Hettinger32ea1652015-03-21 01:37:37 -070020from collections import deque
Yury Selivanov22214ab2016-11-16 18:25:04 -050021from collections.abc import Awaitable, Coroutine
22from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator
Guido van Rossum16ca06b2016-04-04 10:59:29 -070023from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
Guido van Rossumf0666942016-08-23 10:47:07 -070024from collections.abc import Sized, Container, Callable, Collection
Raymond Hettinger57d1a882011-02-23 00:46:28 +000025from collections.abc import Set, MutableSet
Raymond Hettinger584e8ae2016-05-05 11:14:06 +030026from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
Raymond Hettinger57d1a882011-02-23 00:46:28 +000027from collections.abc import Sequence, MutableSequence
28from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000029
Raymond Hettinger499e1932011-02-23 07:56:53 +000030
Raymond Hettinger573b44c2015-05-22 16:56:32 -070031class TestUserObjects(unittest.TestCase):
32 def _superset_test(self, a, b):
33 self.assertGreaterEqual(
34 set(dir(a)),
35 set(dir(b)),
36 '{a} should have all the methods of {b}'.format(
37 a=a.__name__,
38 b=b.__name__,
39 ),
40 )
41 def test_str_protocol(self):
42 self._superset_test(UserString, str)
43
44 def test_list_protocol(self):
45 self._superset_test(UserList, list)
46
47 def test_dict_protocol(self):
48 self._superset_test(UserDict, dict)
49
50
Raymond Hettinger499e1932011-02-23 07:56:53 +000051################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000052### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000053################################################################################
54
55class TestChainMap(unittest.TestCase):
56
57 def test_basics(self):
58 c = ChainMap()
59 c['a'] = 1
60 c['b'] = 2
61 d = c.new_child()
62 d['b'] = 20
63 d['c'] = 30
64 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
65 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
66 self.assertEqual(len(d), 3) # check len
67 for key in 'abc': # check contains
68 self.assertIn(key, d)
69 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
70 self.assertEqual(d.get(k, 100), v)
71
72 del d['b'] # unmask a value
73 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
74 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
75 self.assertEqual(len(d), 3) # check len
76 for key in 'abc': # check contains
77 self.assertIn(key, d)
78 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
79 self.assertEqual(d.get(k, 100), v)
80 self.assertIn(repr(d), [ # check repr
81 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
82 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
83 ])
84
85 for e in d.copy(), copy.copy(d): # check shallow copies
86 self.assertEqual(d, e)
87 self.assertEqual(d.maps, e.maps)
88 self.assertIsNot(d, e)
89 self.assertIsNot(d.maps[0], e.maps[0])
90 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
91 self.assertIs(m1, m2)
92
Serhiy Storchakabad12572014-12-15 14:03:42 +020093 # check deep copies
94 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
95 e = pickle.loads(pickle.dumps(d, proto))
96 self.assertEqual(d, e)
97 self.assertEqual(d.maps, e.maps)
98 self.assertIsNot(d, e)
99 for m1, m2 in zip(d.maps, e.maps):
100 self.assertIsNot(m1, m2, e)
101 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +0000102 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200103 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000104 self.assertEqual(d, e)
105 self.assertEqual(d.maps, e.maps)
106 self.assertIsNot(d, e)
107 for m1, m2 in zip(d.maps, e.maps):
108 self.assertIsNot(m1, m2, e)
109
Raymond Hettingerd0321312011-02-26 06:53:58 +0000110 f = d.new_child()
111 f['b'] = 5
112 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
113 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
114 self.assertEqual(f['b'], 5) # find first in chain
115 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000116
Martin Pantereb995702016-07-28 01:11:04 +0000117 def test_constructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000118 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000119 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
120
Raymond Hettingerd0321312011-02-26 06:53:58 +0000121 def test_bool(self):
122 self.assertFalse(ChainMap())
123 self.assertFalse(ChainMap({}, {}))
124 self.assertTrue(ChainMap({1:2}, {}))
125 self.assertTrue(ChainMap({}, {1:2}))
126
Raymond Hettinger499e1932011-02-23 07:56:53 +0000127 def test_missing(self):
128 class DefaultChainMap(ChainMap):
129 def __missing__(self, key):
130 return 999
131 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
132 for k, v in dict(a=1, b=2, c=30, d=999).items():
133 self.assertEqual(d[k], v) # check __getitem__ w/missing
134 for k, v in dict(a=1, b=2, c=30, d=77).items():
135 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
136 for k, v in dict(a=True, b=True, c=True, d=False).items():
137 self.assertEqual(k in d, v) # check __contains__ w/missing
138 self.assertEqual(d.pop('a', 1001), 1, d)
139 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
140 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
141 with self.assertRaises(KeyError):
142 d.popitem()
143
144 def test_dict_coercion(self):
145 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
146 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
147 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
148
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000149 def test_new_child(self):
150 'Tests for changes for issue #16613.'
151 c = ChainMap()
152 c['a'] = 1
153 c['b'] = 2
154 m = {'b':20, 'c': 30}
155 d = c.new_child(m)
156 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
157 self.assertIs(m, d.maps[0])
158
159 # Use a different map than a dict
160 class lowerdict(dict):
161 def __getitem__(self, key):
162 if isinstance(key, str):
163 key = key.lower()
164 return dict.__getitem__(self, key)
165 def __contains__(self, key):
166 if isinstance(key, str):
167 key = key.lower()
168 return dict.__contains__(self, key)
169
170 c = ChainMap()
171 c['a'] = 1
172 c['b'] = 2
173 m = lowerdict(b=20, c=30)
174 d = c.new_child(m)
175 self.assertIs(m, d.maps[0])
176 for key in 'abc': # check contains
177 self.assertIn(key, d)
178 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
179 self.assertEqual(d.get(k, 100), v)
180
Raymond Hettinger499e1932011-02-23 07:56:53 +0000181
182################################################################################
183### Named Tuples
184################################################################################
185
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000186TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000187
188class TestNamedTuple(unittest.TestCase):
189
190 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000191 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000192 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000193 self.assertEqual(Point.__slots__, ())
194 self.assertEqual(Point.__module__, __name__)
195 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000196 self.assertEqual(Point._fields, ('x', 'y'))
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700197 self.assertIn('class Point(tuple)', Point._source)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000198
199 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
200 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
201 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
202
203 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
204 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
205 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000206 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000207 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
208
209 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000210 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000211
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000212 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000213 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000214 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000215 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000216
Christian Heimesfaf2f632008-01-06 16:59:19 +0000217 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
218 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
219
R. David Murray378c0cf2010-02-24 01:46:21 +0000220 @unittest.skipIf(sys.flags.optimize >= 2,
221 "Docstrings are omitted with -O2 and above")
222 def test_factory_doc_attr(self):
223 Point = namedtuple('Point', 'x y')
224 self.assertEqual(Point.__doc__, 'Point(x, y)')
225
Raymond Hettingereac503a2015-05-13 01:09:59 -0700226 @unittest.skipIf(sys.flags.optimize >= 2,
227 "Docstrings are omitted with -O2 and above")
228 def test_doc_writable(self):
229 Point = namedtuple('Point', 'x y')
230 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
231 Point.x.__doc__ = 'docstring for Point.x'
232 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
233
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000234 def test_name_fixer(self):
235 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000236 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
237 [('abc', 'class'), ('abc', '_1')], # field has keyword
238 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
239 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
240 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
241 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000242 ]:
243 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
244
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700245 def test_module_parameter(self):
246 NT = namedtuple('NT', ['x', 'y'], module=collections)
247 self.assertEqual(NT.__module__, collections)
248
Guido van Rossumd8faa362007-04-27 19:54:29 +0000249 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000250 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000251 p = Point(11, 22)
252 self.assertEqual(p, Point(x=11, y=22))
253 self.assertEqual(p, Point(11, y=22))
254 self.assertEqual(p, Point(y=22, x=11))
255 self.assertEqual(p, Point(*(11, 22)))
256 self.assertEqual(p, Point(**dict(x=11, y=22)))
257 self.assertRaises(TypeError, Point, 1) # too few args
258 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
259 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
260 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
261 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000262 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000263 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000264 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
265 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700266 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000267
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000268 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000269 p._replace(x=1, error=2)
270 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000271 pass
272 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000273 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000274
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000275 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000276 Point = namedtuple('Point', 'x, y')
277 p = Point(x=11, y=22)
278 self.assertEqual(repr(p), 'Point(x=11, y=22)')
279
280 # verify that fieldspec can be a non-string sequence
281 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000282 p = Point(x=11, y=22)
283 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000284
285 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000286 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000287 p = Point(11, 22)
288
Ezio Melottie9615932010-01-24 19:26:24 +0000289 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000290 self.assertEqual(p, (11, 22)) # matches a real tuple
291 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
292 self.assertEqual(list(p), [11, 22]) # coercable to a list
293 self.assertEqual(max(p), 22) # iterable
294 self.assertEqual(max(*p), 22) # star-able
295 x, y = p
296 self.assertEqual(p, (x, y)) # unpacks like a tuple
297 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
298 self.assertRaises(IndexError, p.__getitem__, 3)
299
300 self.assertEqual(p.x, x)
301 self.assertEqual(p.y, y)
302 self.assertRaises(AttributeError, eval, 'p.z', locals())
303
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000304 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000305 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000306 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000307 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000308 self.assertEqual(repr(Zero()), 'Zero()')
309 self.assertEqual(Zero()._asdict(), {})
310 self.assertEqual(Zero()._fields, ())
311
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000312 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000313 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000314 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000315 self.assertEqual(Dot(1).d, 1)
316 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
317 self.assertEqual(Dot(1)._asdict(), {'d':1})
318 self.assertEqual(Dot(1)._replace(d=999), (999,))
319 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000320
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200321 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200322 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000323 for j in range(10)]) for i in range(n)))
324 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000325 Big = namedtuple('Big', names)
326 b = Big(*range(n))
327 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000328 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000329 for pos, name in enumerate(names):
330 self.assertEqual(getattr(b, name), pos)
331 repr(b) # make sure repr() doesn't blow-up
332 d = b._asdict()
333 d_expected = dict(zip(names, range(n)))
334 self.assertEqual(d, d_expected)
335 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
336 b2_expected = list(range(n))
337 b2_expected[1] = 999
338 b2_expected[-5] = 42
339 self.assertEqual(b2, tuple(b2_expected))
340 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000341
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000342 def test_pickle(self):
343 p = TestNT(x=10, y=20, z=30)
344 for module in (pickle,):
345 loads = getattr(module, 'loads')
346 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500347 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000348 q = loads(dumps(p, protocol))
349 self.assertEqual(p, q)
350 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700351 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000352
353 def test_copy(self):
354 p = TestNT(x=10, y=20, z=30)
355 for copier in copy.copy, copy.deepcopy:
356 q = copier(p)
357 self.assertEqual(p, q)
358 self.assertEqual(p._fields, q._fields)
359
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000360 def test_name_conflicts(self):
361 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
362 # failed when used as field names. Test to make sure these now work.
363 T = namedtuple('T', 'itemgetter property self cls tuple')
364 t = T(1, 2, 3, 4, 5)
365 self.assertEqual(t, (1,2,3,4,5))
366 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
367 self.assertEqual(newt, (10,20,30,40,50))
368
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000369 # Broader test of all interesting names in a template
370 with support.captured_stdout() as template:
371 T = namedtuple('T', 'x', verbose=True)
372 words = set(re.findall('[A-Za-z]+', template.getvalue()))
373 words -= set(keyword.kwlist)
374 T = namedtuple('T', words)
375 # test __new__
376 values = tuple(range(len(words)))
377 t = T(*values)
378 self.assertEqual(t, values)
379 t = T(**dict(zip(T._fields, values)))
380 self.assertEqual(t, values)
381 # test _make
382 t = T._make(values)
383 self.assertEqual(t, values)
384 # exercise __repr__
385 repr(t)
386 # test _asdict
387 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
388 # test _replace
389 t = T._make(values)
390 newvalues = tuple(v*10 for v in values)
391 newt = t._replace(**dict(zip(T._fields, newvalues)))
392 self.assertEqual(newt, newvalues)
393 # test _fields
394 self.assertEqual(T._fields, tuple(words))
395 # test __getnewargs__
396 self.assertEqual(t.__getnewargs__(), values)
397
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000398 def test_repr(self):
399 with support.captured_stdout() as template:
400 A = namedtuple('A', 'x', verbose=True)
401 self.assertEqual(repr(A(1)), 'A(x=1)')
402 # repr should show the name of the subclass
403 class B(A):
404 pass
405 self.assertEqual(repr(B(1)), 'B(x=1)')
406
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700407 def test_source(self):
408 # verify that _source can be run through exec()
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700409 tmp = namedtuple('NTColor', 'red green blue')
410 globals().pop('NTColor', None) # remove artifacts from other tests
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700411 exec(tmp._source, globals())
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700412 self.assertIn('NTColor', globals())
413 c = NTColor(10, 20, 30)
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700414 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700415 self.assertEqual(NTColor._fields, ('red', 'green', 'blue'))
416 globals().pop('NTColor', None) # clean-up after this test
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700417
Raymond Hettinger6538b432016-08-16 10:55:43 -0700418 def test_keyword_only_arguments(self):
419 # See issue 25628
420 with support.captured_stdout() as template:
421 NT = namedtuple('NT', ['x', 'y'], verbose=True)
422 self.assertIn('class NT', NT._source)
423 with self.assertRaises(TypeError):
424 NT = namedtuple('NT', ['x', 'y'], True)
425
426 NT = namedtuple('NT', ['abc', 'def'], rename=True)
427 self.assertEqual(NT._fields, ('abc', '_1'))
428 with self.assertRaises(TypeError):
429 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000430
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700431 def test_namedtuple_subclass_issue_24931(self):
432 class Point(namedtuple('_Point', ['x', 'y'])):
433 pass
434
435 a = Point(3, 4)
436 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
437
438 a.w = 5
439 self.assertEqual(a.__dict__, {'w': 5})
440
441
Raymond Hettinger499e1932011-02-23 07:56:53 +0000442################################################################################
443### Abstract Base Classes
444################################################################################
445
Raymond Hettingerae650182009-01-28 23:33:59 +0000446class ABCTestCase(unittest.TestCase):
447
448 def validate_abstract_methods(self, abc, *names):
449 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
450
451 # everything should work will all required methods are present
452 C = type('C', (abc,), methodstubs)
453 C()
454
455 # instantiation should fail if a required method is missing
456 for name in names:
457 stubs = methodstubs.copy()
458 del stubs[name]
459 C = type('C', (abc,), stubs)
460 self.assertRaises(TypeError, C, name)
461
Florent Xiclunace153f62010-03-08 15:34:35 +0000462 def validate_isinstance(self, abc, name):
463 stub = lambda s, *args: 0
464
465 C = type('C', (object,), {'__hash__': None})
466 setattr(C, name, stub)
467 self.assertIsInstance(C(), abc)
468 self.assertTrue(issubclass(C, abc))
469
470 C = type('C', (object,), {'__hash__': None})
471 self.assertNotIsInstance(C(), abc)
472 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000473
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000474 def validate_comparison(self, instance):
475 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
476 operators = {}
477 for op in ops:
478 name = '__' + op + '__'
479 operators[name] = getattr(operator, name)
480
481 class Other:
482 def __init__(self):
483 self.right_side = False
484 def __eq__(self, other):
485 self.right_side = True
486 return True
487 __lt__ = __eq__
488 __gt__ = __eq__
489 __le__ = __eq__
490 __ge__ = __eq__
491 __ne__ = __eq__
492 __ror__ = __eq__
493 __rand__ = __eq__
494 __rxor__ = __eq__
495 __rsub__ = __eq__
496
497 for name, op in operators.items():
498 if not hasattr(instance, name):
499 continue
500 other = Other()
501 op(instance, other)
502 self.assertTrue(other.right_side,'Right side not called for %s.%s'
503 % (type(instance), name))
504
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700505def _test_gen():
506 yield
507
Raymond Hettingerae650182009-01-28 23:33:59 +0000508class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000509
Yury Selivanov75445082015-05-11 22:57:16 -0400510 def test_Awaitable(self):
511 def gen():
512 yield
513
514 @types.coroutine
515 def coro():
516 yield
517
518 async def new_coro():
519 pass
520
521 class Bar:
522 def __await__(self):
523 yield
524
525 class MinimalCoro(Coroutine):
526 def send(self, value):
527 return value
528 def throw(self, typ, val=None, tb=None):
529 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400530 def __await__(self):
531 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400532
533 non_samples = [None, int(), gen(), object()]
534 for x in non_samples:
535 self.assertNotIsInstance(x, Awaitable)
536 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
537
538 samples = [Bar(), MinimalCoro()]
539 for x in samples:
540 self.assertIsInstance(x, Awaitable)
541 self.assertTrue(issubclass(type(x), Awaitable))
542
543 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400544 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
545 # flag don't have '__await__' method, hence can't be instances
546 # of Awaitable. Use inspect.isawaitable to detect them.
547 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400548
549 c = new_coro()
550 self.assertIsInstance(c, Awaitable)
551 c.close() # awoid RuntimeWarning that coro() was not awaited
552
Yury Selivanov56fc6142015-05-29 09:01:29 -0400553 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400554 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400555 self.assertTrue(isinstance(CoroLike(), Awaitable))
556 self.assertTrue(issubclass(CoroLike, Awaitable))
557 CoroLike = None
558 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400559
Yury Selivanov75445082015-05-11 22:57:16 -0400560 def test_Coroutine(self):
561 def gen():
562 yield
563
564 @types.coroutine
565 def coro():
566 yield
567
568 async def new_coro():
569 pass
570
571 class Bar:
572 def __await__(self):
573 yield
574
575 class MinimalCoro(Coroutine):
576 def send(self, value):
577 return value
578 def throw(self, typ, val=None, tb=None):
579 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400580 def __await__(self):
581 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400582
583 non_samples = [None, int(), gen(), object(), Bar()]
584 for x in non_samples:
585 self.assertNotIsInstance(x, Coroutine)
586 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
587
588 samples = [MinimalCoro()]
589 for x in samples:
590 self.assertIsInstance(x, Awaitable)
591 self.assertTrue(issubclass(type(x), Awaitable))
592
593 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400594 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
595 # flag don't have '__await__' method, hence can't be instances
596 # of Coroutine. Use inspect.isawaitable to detect them.
597 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400598
599 c = new_coro()
600 self.assertIsInstance(c, Coroutine)
601 c.close() # awoid RuntimeWarning that coro() was not awaited
602
Yury Selivanov56fc6142015-05-29 09:01:29 -0400603 class CoroLike:
604 def send(self, value):
605 pass
606 def throw(self, typ, val=None, tb=None):
607 pass
608 def close(self):
609 pass
610 def __await__(self):
611 pass
612 self.assertTrue(isinstance(CoroLike(), Coroutine))
613 self.assertTrue(issubclass(CoroLike, Coroutine))
614
615 class CoroLike:
616 def send(self, value):
617 pass
618 def close(self):
619 pass
620 def __await__(self):
621 pass
622 self.assertFalse(isinstance(CoroLike(), Coroutine))
623 self.assertFalse(issubclass(CoroLike, Coroutine))
624
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000625 def test_Hashable(self):
626 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000627 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000628 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000629 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000630 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000631 # Check some hashables
632 samples = [None,
633 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000634 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000635 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000636 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000637 ]
638 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000639 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000640 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000641 self.assertRaises(TypeError, Hashable)
642 # Check direct subclassing
643 class H(Hashable):
644 def __hash__(self):
645 return super().__hash__()
646 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000647 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000648 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000649 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000650
Yury Selivanove0104ae2015-05-14 12:19:16 -0400651 def test_AsyncIterable(self):
652 class AI:
653 async def __aiter__(self):
654 return self
655 self.assertTrue(isinstance(AI(), AsyncIterable))
656 self.assertTrue(issubclass(AI, AsyncIterable))
657 # Check some non-iterables
658 non_samples = [None, object, []]
659 for x in non_samples:
660 self.assertNotIsInstance(x, AsyncIterable)
661 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
662 self.validate_abstract_methods(AsyncIterable, '__aiter__')
663 self.validate_isinstance(AsyncIterable, '__aiter__')
664
665 def test_AsyncIterator(self):
666 class AI:
667 async def __aiter__(self):
668 return self
669 async def __anext__(self):
670 raise StopAsyncIteration
671 self.assertTrue(isinstance(AI(), AsyncIterator))
672 self.assertTrue(issubclass(AI, AsyncIterator))
673 non_samples = [None, object, []]
674 # Check some non-iterables
675 for x in non_samples:
676 self.assertNotIsInstance(x, AsyncIterator)
677 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
678 # Similarly to regular iterators (see issue 10565)
679 class AnextOnly:
680 async def __anext__(self):
681 raise StopAsyncIteration
682 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
683 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
684
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000685 def test_Iterable(self):
686 # Check some non-iterables
687 non_samples = [None, 42, 3.14, 1j]
688 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000689 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000690 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000691 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000692 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000693 tuple(), list(), set(), frozenset(), dict(),
694 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700695 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000696 (x for x in []),
697 ]
698 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000699 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000700 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000701 # Check direct subclassing
702 class I(Iterable):
703 def __iter__(self):
704 return super().__iter__()
705 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000706 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000707 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000708 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700709 # Check None blocking
710 class It:
711 def __iter__(self): return iter([])
712 class ItBlocked(It):
713 __iter__ = None
714 self.assertTrue(issubclass(It, Iterable))
715 self.assertTrue(isinstance(It(), Iterable))
716 self.assertFalse(issubclass(ItBlocked, Iterable))
717 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000718
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700719 def test_Reversible(self):
720 # Check some non-reversibles
721 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()]
722 for x in non_samples:
723 self.assertNotIsInstance(x, Reversible)
724 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700725 # Check some non-reversible iterables
726 non_reversibles = [dict().keys(), dict().items(), dict().values(),
727 Counter(), Counter().keys(), Counter().items(),
728 Counter().values(), _test_gen(),
729 (x for x in []), iter([]), reversed([])]
730 for x in non_reversibles:
731 self.assertNotIsInstance(x, Reversible)
732 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
733 # Check some reversible iterables
734 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
735 OrderedDict().keys(), OrderedDict().items(),
736 OrderedDict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700737 for x in samples:
738 self.assertIsInstance(x, Reversible)
739 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
740 # Check also Mapping, MutableMapping, and Sequence
741 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
742 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
743 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
744 # Check direct subclassing
745 class R(Reversible):
746 def __iter__(self):
747 return iter(list())
748 def __reversed__(self):
749 return iter(list())
750 self.assertEqual(list(reversed(R())), [])
751 self.assertFalse(issubclass(float, R))
752 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700753 # Check reversible non-iterable (which is not Reversible)
754 class RevNoIter:
755 def __reversed__(self): return reversed([])
756 class RevPlusIter(RevNoIter):
757 def __iter__(self): return iter([])
758 self.assertFalse(issubclass(RevNoIter, Reversible))
759 self.assertFalse(isinstance(RevNoIter(), Reversible))
760 self.assertTrue(issubclass(RevPlusIter, Reversible))
761 self.assertTrue(isinstance(RevPlusIter(), Reversible))
762 # Check None blocking
763 class Rev:
764 def __iter__(self): return iter([])
765 def __reversed__(self): return reversed([])
766 class RevItBlocked(Rev):
767 __iter__ = None
768 class RevRevBlocked(Rev):
769 __reversed__ = None
770 self.assertTrue(issubclass(Rev, Reversible))
771 self.assertTrue(isinstance(Rev(), Reversible))
772 self.assertFalse(issubclass(RevItBlocked, Reversible))
773 self.assertFalse(isinstance(RevItBlocked(), Reversible))
774 self.assertFalse(issubclass(RevRevBlocked, Reversible))
775 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700776
Guido van Rossumf0666942016-08-23 10:47:07 -0700777 def test_Collection(self):
778 # Check some non-collections
779 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
780 for x in non_collections:
781 self.assertNotIsInstance(x, Collection)
782 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
783 # Check some non-collection iterables
784 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
785 (x for x in []), dict().values()]
786 for x in non_col_iterables:
787 self.assertNotIsInstance(x, Collection)
788 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
789 # Check some collections
790 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
791 list(), dict().keys(), dict().items()]
792 for x in samples:
793 self.assertIsInstance(x, Collection)
794 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
795 # Check also Mapping, MutableMapping, etc.
796 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
797 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
798 self.assertTrue(issubclass(MutableMapping, Collection),
799 repr(MutableMapping))
800 self.assertTrue(issubclass(Set, Collection), repr(Set))
801 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
802 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
803 # Check direct subclassing
804 class Col(Collection):
805 def __iter__(self):
806 return iter(list())
807 def __len__(self):
808 return 0
809 def __contains__(self, item):
810 return False
811 class DerCol(Col): pass
812 self.assertEqual(list(iter(Col())), [])
813 self.assertFalse(issubclass(list, Col))
814 self.assertFalse(issubclass(set, Col))
815 self.assertFalse(issubclass(float, Col))
816 self.assertEqual(list(iter(DerCol())), [])
817 self.assertFalse(issubclass(list, DerCol))
818 self.assertFalse(issubclass(set, DerCol))
819 self.assertFalse(issubclass(float, DerCol))
820 self.validate_abstract_methods(Collection, '__len__', '__iter__',
821 '__contains__')
822 # Check sized container non-iterable (which is not Collection) etc.
823 class ColNoIter:
824 def __len__(self): return 0
825 def __contains__(self, item): return False
826 class ColNoSize:
827 def __iter__(self): return iter([])
828 def __contains__(self, item): return False
829 class ColNoCont:
830 def __iter__(self): return iter([])
831 def __len__(self): return 0
832 self.assertFalse(issubclass(ColNoIter, Collection))
833 self.assertFalse(isinstance(ColNoIter(), Collection))
834 self.assertFalse(issubclass(ColNoSize, Collection))
835 self.assertFalse(isinstance(ColNoSize(), Collection))
836 self.assertFalse(issubclass(ColNoCont, Collection))
837 self.assertFalse(isinstance(ColNoCont(), Collection))
838 # Check None blocking
839 class SizeBlock:
840 def __iter__(self): return iter([])
841 def __contains__(self): return False
842 __len__ = None
843 class IterBlock:
844 def __len__(self): return 0
845 def __contains__(self): return True
846 __iter__ = None
847 self.assertFalse(issubclass(SizeBlock, Collection))
848 self.assertFalse(isinstance(SizeBlock(), Collection))
849 self.assertFalse(issubclass(IterBlock, Collection))
850 self.assertFalse(isinstance(IterBlock(), Collection))
851 # Check None blocking in subclass
852 class ColImpl:
853 def __iter__(self):
854 return iter(list())
855 def __len__(self):
856 return 0
857 def __contains__(self, item):
858 return False
859 class NonCol(ColImpl):
860 __contains__ = None
861 self.assertFalse(issubclass(NonCol, Collection))
862 self.assertFalse(isinstance(NonCol(), Collection))
863
864
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000865 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000866 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000867 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000868 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000869 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000870 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000871 iter(tuple()), iter(list()), iter(dict()),
872 iter(set()), iter(frozenset()),
873 iter(dict().keys()), iter(dict().items()),
874 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700875 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000876 (x for x in []),
877 ]
878 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000879 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000880 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000881 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
882
883 # Issue 10565
884 class NextOnly:
885 def __next__(self):
886 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800887 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000888 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000889
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400890 def test_Generator(self):
891 class NonGen1:
892 def __iter__(self): return self
893 def __next__(self): return None
894 def close(self): pass
895 def throw(self, typ, val=None, tb=None): pass
896
897 class NonGen2:
898 def __iter__(self): return self
899 def __next__(self): return None
900 def close(self): pass
901 def send(self, value): return value
902
903 class NonGen3:
904 def close(self): pass
905 def send(self, value): return value
906 def throw(self, typ, val=None, tb=None): pass
907
908 non_samples = [
909 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
910 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
911 for x in non_samples:
912 self.assertNotIsInstance(x, Generator)
913 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
914
915 class Gen:
916 def __iter__(self): return self
917 def __next__(self): return None
918 def close(self): pass
919 def send(self, value): return value
920 def throw(self, typ, val=None, tb=None): pass
921
922 class MinimalGen(Generator):
923 def send(self, value):
924 return value
925 def throw(self, typ, val=None, tb=None):
926 super().throw(typ, val, tb)
927
928 def gen():
929 yield 1
930
931 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
932 for x in samples:
933 self.assertIsInstance(x, Iterator)
934 self.assertIsInstance(x, Generator)
935 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
936 self.validate_abstract_methods(Generator, 'send', 'throw')
937
938 # mixin tests
939 mgen = MinimalGen()
940 self.assertIs(mgen, iter(mgen))
941 self.assertIs(mgen.send(None), next(mgen))
942 self.assertEqual(2, mgen.send(2))
943 self.assertIsNone(mgen.close())
944 self.assertRaises(ValueError, mgen.throw, ValueError)
945 self.assertRaisesRegex(ValueError, "^huhu$",
946 mgen.throw, ValueError, ValueError("huhu"))
947 self.assertRaises(StopIteration, mgen.throw, StopIteration())
948
949 class FailOnClose(Generator):
950 def send(self, value): return value
951 def throw(self, *args): raise ValueError
952
953 self.assertRaises(ValueError, FailOnClose().close)
954
955 class IgnoreGeneratorExit(Generator):
956 def send(self, value): return value
957 def throw(self, *args): pass
958
959 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
960
Yury Selivanov22214ab2016-11-16 18:25:04 -0500961 def test_AsyncGenerator(self):
962 class NonAGen1:
963 def __aiter__(self): return self
964 def __anext__(self): return None
965 def aclose(self): pass
966 def athrow(self, typ, val=None, tb=None): pass
967
968 class NonAGen2:
969 def __aiter__(self): return self
970 def __anext__(self): return None
971 def aclose(self): pass
972 def asend(self, value): return value
973
974 class NonAGen3:
975 def aclose(self): pass
976 def asend(self, value): return value
977 def athrow(self, typ, val=None, tb=None): pass
978
979 non_samples = [
980 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
981 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
982 for x in non_samples:
983 self.assertNotIsInstance(x, AsyncGenerator)
984 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
985
986 class Gen:
987 def __aiter__(self): return self
988 async def __anext__(self): return None
989 async def aclose(self): pass
990 async def asend(self, value): return value
991 async def athrow(self, typ, val=None, tb=None): pass
992
993 class MinimalAGen(AsyncGenerator):
994 async def asend(self, value):
995 return value
996 async def athrow(self, typ, val=None, tb=None):
997 await super().athrow(typ, val, tb)
998
999 async def gen():
1000 yield 1
1001
1002 samples = [gen(), Gen(), MinimalAGen()]
1003 for x in samples:
1004 self.assertIsInstance(x, AsyncIterator)
1005 self.assertIsInstance(x, AsyncGenerator)
1006 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1007 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1008
1009 def run_async(coro):
1010 result = None
1011 while True:
1012 try:
1013 coro.send(None)
1014 except StopIteration as ex:
1015 result = ex.args[0] if ex.args else None
1016 break
1017 return result
1018
1019 # mixin tests
1020 mgen = MinimalAGen()
1021 self.assertIs(mgen, mgen.__aiter__())
1022 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1023 self.assertEqual(2, run_async(mgen.asend(2)))
1024 self.assertIsNone(run_async(mgen.aclose()))
1025 with self.assertRaises(ValueError):
1026 run_async(mgen.athrow(ValueError))
1027
1028 class FailOnClose(AsyncGenerator):
1029 async def asend(self, value): return value
1030 async def athrow(self, *args): raise ValueError
1031
1032 with self.assertRaises(ValueError):
1033 run_async(FailOnClose().aclose())
1034
1035 class IgnoreGeneratorExit(AsyncGenerator):
1036 async def asend(self, value): return value
1037 async def athrow(self, *args): pass
1038
1039 with self.assertRaises(RuntimeError):
1040 run_async(IgnoreGeneratorExit().aclose())
1041
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001042 def test_Sized(self):
1043 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001044 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001045 (x for x in []),
1046 ]
1047 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001048 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001049 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001050 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001051 tuple(), list(), set(), frozenset(), dict(),
1052 dict().keys(), dict().items(), dict().values(),
1053 ]
1054 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001055 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001056 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001057 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001058 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001059
1060 def test_Container(self):
1061 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001062 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001063 (x for x in []),
1064 ]
1065 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001066 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001067 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001068 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001069 tuple(), list(), set(), frozenset(), dict(),
1070 dict().keys(), dict().items(),
1071 ]
1072 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001073 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001074 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001075 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001076 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001077
1078 def test_Callable(self):
1079 non_samples = [None, 42, 3.14, 1j,
1080 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001081 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001082 (x for x in []),
1083 ]
1084 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001085 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001086 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001087 samples = [lambda: None,
1088 type, int, object,
1089 len,
1090 list.append, [].append,
1091 ]
1092 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001093 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001094 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001095 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001096 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001097
1098 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001099 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001100 class C(B):
1101 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001102 self.assertTrue(issubclass(C, B))
1103 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001104
1105 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001106 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001107 class C:
1108 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001109 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001110 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001111 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001112
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001113class WithSet(MutableSet):
1114
1115 def __init__(self, it=()):
1116 self.data = set(it)
1117
1118 def __len__(self):
1119 return len(self.data)
1120
1121 def __iter__(self):
1122 return iter(self.data)
1123
1124 def __contains__(self, item):
1125 return item in self.data
1126
1127 def add(self, item):
1128 self.data.add(item)
1129
1130 def discard(self, item):
1131 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001132
Raymond Hettingerae650182009-01-28 23:33:59 +00001133class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001134
1135 # XXX For now, we only test some virtual inheritance properties.
1136 # We should also test the proper behavior of the collection ABCs
1137 # as real base classes or mix-in classes.
1138
1139 def test_Set(self):
1140 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001141 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001142 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001143 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001144 class MySet(Set):
1145 def __contains__(self, x):
1146 return False
1147 def __len__(self):
1148 return 0
1149 def __iter__(self):
1150 return iter([])
1151 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001152
Benjamin Peterson41181742008-07-02 20:22:54 +00001153 def test_hash_Set(self):
1154 class OneTwoThreeSet(Set):
1155 def __init__(self):
1156 self.contents = [1, 2, 3]
1157 def __contains__(self, x):
1158 return x in self.contents
1159 def __len__(self):
1160 return len(self.contents)
1161 def __iter__(self):
1162 return iter(self.contents)
1163 def __hash__(self):
1164 return self._hash()
1165 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001166 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001167
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001168 def test_isdisjoint_Set(self):
1169 class MySet(Set):
1170 def __init__(self, itr):
1171 self.contents = itr
1172 def __contains__(self, x):
1173 return x in self.contents
1174 def __iter__(self):
1175 return iter(self.contents)
1176 def __len__(self):
1177 return len([x for x in self.contents])
1178 s1 = MySet((1, 2, 3))
1179 s2 = MySet((4, 5, 6))
1180 s3 = MySet((1, 5, 6))
1181 self.assertTrue(s1.isdisjoint(s2))
1182 self.assertFalse(s1.isdisjoint(s3))
1183
1184 def test_equality_Set(self):
1185 class MySet(Set):
1186 def __init__(self, itr):
1187 self.contents = itr
1188 def __contains__(self, x):
1189 return x in self.contents
1190 def __iter__(self):
1191 return iter(self.contents)
1192 def __len__(self):
1193 return len([x for x in self.contents])
1194 s1 = MySet((1,))
1195 s2 = MySet((1, 2))
1196 s3 = MySet((3, 4))
1197 s4 = MySet((3, 4))
1198 self.assertTrue(s2 > s1)
1199 self.assertTrue(s1 < s2)
1200 self.assertFalse(s2 <= s1)
1201 self.assertFalse(s2 <= s3)
1202 self.assertFalse(s1 >= s2)
1203 self.assertEqual(s3, s4)
1204 self.assertNotEqual(s2, s3)
1205
1206 def test_arithmetic_Set(self):
1207 class MySet(Set):
1208 def __init__(self, itr):
1209 self.contents = itr
1210 def __contains__(self, x):
1211 return x in self.contents
1212 def __iter__(self):
1213 return iter(self.contents)
1214 def __len__(self):
1215 return len([x for x in self.contents])
1216 s1 = MySet((1, 2, 3))
1217 s2 = MySet((3, 4, 5))
1218 s3 = s1 & s2
1219 self.assertEqual(s3, MySet((3,)))
1220
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001221 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001222 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001223 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001224 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001225 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001226 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1227 'add', 'discard')
1228
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001229 def test_issue_5647(self):
1230 # MutableSet.__iand__ mutated the set during iteration
1231 s = WithSet('abcd')
1232 s &= WithSet('cdef') # This used to fail
1233 self.assertEqual(set(s), set('cd'))
1234
Raymond Hettingerae650182009-01-28 23:33:59 +00001235 def test_issue_4920(self):
1236 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001237 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001238 __slots__=['__s']
1239 def __init__(self,items=None):
1240 if items is None:
1241 items=[]
1242 self.__s=set(items)
1243 def __contains__(self,v):
1244 return v in self.__s
1245 def __iter__(self):
1246 return iter(self.__s)
1247 def __len__(self):
1248 return len(self.__s)
1249 def add(self,v):
1250 result=v not in self.__s
1251 self.__s.add(v)
1252 return result
1253 def discard(self,v):
1254 result=v in self.__s
1255 self.__s.discard(v)
1256 return result
1257 def __repr__(self):
1258 return "MySet(%s)" % repr(list(self))
1259 s = MySet([5,43,2,1])
1260 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001261
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001262 def test_issue8750(self):
1263 empty = WithSet()
1264 full = WithSet(range(10))
1265 s = WithSet(full)
1266 s -= s
1267 self.assertEqual(s, empty)
1268 s = WithSet(full)
1269 s ^= s
1270 self.assertEqual(s, empty)
1271 s = WithSet(full)
1272 s &= s
1273 self.assertEqual(s, full)
1274 s |= s
1275 self.assertEqual(s, full)
1276
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001277 def test_issue16373(self):
1278 # Recursion error comparing comparable and noncomparable
1279 # Set instances
1280 class MyComparableSet(Set):
1281 def __contains__(self, x):
1282 return False
1283 def __len__(self):
1284 return 0
1285 def __iter__(self):
1286 return iter([])
1287 class MyNonComparableSet(Set):
1288 def __contains__(self, x):
1289 return False
1290 def __len__(self):
1291 return 0
1292 def __iter__(self):
1293 return iter([])
1294 def __le__(self, x):
1295 return NotImplemented
1296 def __lt__(self, x):
1297 return NotImplemented
1298
1299 cs = MyComparableSet()
1300 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001301 self.assertFalse(ncs < cs)
1302 self.assertTrue(ncs <= cs)
1303 self.assertFalse(ncs > cs)
1304 self.assertTrue(ncs >= cs)
1305
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001306 def test_issue26915(self):
1307 # Container membership test should check identity first
1308 class CustomEqualObject:
1309 def __eq__(self, other):
1310 return False
Xiang Zhangd5d32492017-03-08 11:04:24 +08001311 class CustomSequence(Sequence):
1312 def __init__(self, seq):
1313 self._seq = seq
1314 def __getitem__(self, index):
1315 return self._seq[index]
1316 def __len__(self):
1317 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001318
1319 nan = float('nan')
1320 obj = CustomEqualObject()
Xiang Zhangd5d32492017-03-08 11:04:24 +08001321 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001322 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001323 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001324 ItemsView({1: nan, 2: obj}),
1325 ValuesView({1: nan, 2: obj})
1326 ]
1327 for container in containers:
1328 for elem in container:
1329 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001330 self.assertEqual(seq.index(nan), 0)
1331 self.assertEqual(seq.index(obj), 1)
1332 self.assertEqual(seq.count(nan), 2)
1333 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001334
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001335 def assertSameSet(self, s1, s2):
1336 # coerce both to a real set then check equality
1337 self.assertSetEqual(set(s1), set(s2))
1338
1339 def test_Set_interoperability_with_real_sets(self):
1340 # Issue: 8743
1341 class ListSet(Set):
1342 def __init__(self, elements=()):
1343 self.data = []
1344 for elem in elements:
1345 if elem not in self.data:
1346 self.data.append(elem)
1347 def __contains__(self, elem):
1348 return elem in self.data
1349 def __iter__(self):
1350 return iter(self.data)
1351 def __len__(self):
1352 return len(self.data)
1353 def __repr__(self):
1354 return 'Set({!r})'.format(self.data)
1355
1356 r1 = set('abc')
1357 r2 = set('bcd')
1358 r3 = set('abcde')
1359 f1 = ListSet('abc')
1360 f2 = ListSet('bcd')
1361 f3 = ListSet('abcde')
1362 l1 = list('abccba')
1363 l2 = list('bcddcb')
1364 l3 = list('abcdeedcba')
1365
1366 target = r1 & r2
1367 self.assertSameSet(f1 & f2, target)
1368 self.assertSameSet(f1 & r2, target)
1369 self.assertSameSet(r2 & f1, target)
1370 self.assertSameSet(f1 & l2, target)
1371
1372 target = r1 | r2
1373 self.assertSameSet(f1 | f2, target)
1374 self.assertSameSet(f1 | r2, target)
1375 self.assertSameSet(r2 | f1, target)
1376 self.assertSameSet(f1 | l2, target)
1377
1378 fwd_target = r1 - r2
1379 rev_target = r2 - r1
1380 self.assertSameSet(f1 - f2, fwd_target)
1381 self.assertSameSet(f2 - f1, rev_target)
1382 self.assertSameSet(f1 - r2, fwd_target)
1383 self.assertSameSet(f2 - r1, rev_target)
1384 self.assertSameSet(r1 - f2, fwd_target)
1385 self.assertSameSet(r2 - f1, rev_target)
1386 self.assertSameSet(f1 - l2, fwd_target)
1387 self.assertSameSet(f2 - l1, rev_target)
1388
1389 target = r1 ^ r2
1390 self.assertSameSet(f1 ^ f2, target)
1391 self.assertSameSet(f1 ^ r2, target)
1392 self.assertSameSet(r2 ^ f1, target)
1393 self.assertSameSet(f1 ^ l2, target)
1394
1395 # Don't change the following to use assertLess or other
1396 # "more specific" unittest assertions. The current
1397 # assertTrue/assertFalse style makes the pattern of test
1398 # case combinations clear and allows us to know for sure
1399 # the exact operator being invoked.
1400
1401 # proper subset
1402 self.assertTrue(f1 < f3)
1403 self.assertFalse(f1 < f1)
1404 self.assertFalse(f1 < f2)
1405 self.assertTrue(r1 < f3)
1406 self.assertFalse(r1 < f1)
1407 self.assertFalse(r1 < f2)
1408 self.assertTrue(r1 < r3)
1409 self.assertFalse(r1 < r1)
1410 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001411 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001412 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001413 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001414 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001415 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001416 f1 < l2
1417
1418 # any subset
1419 self.assertTrue(f1 <= f3)
1420 self.assertTrue(f1 <= f1)
1421 self.assertFalse(f1 <= f2)
1422 self.assertTrue(r1 <= f3)
1423 self.assertTrue(r1 <= f1)
1424 self.assertFalse(r1 <= f2)
1425 self.assertTrue(r1 <= r3)
1426 self.assertTrue(r1 <= r1)
1427 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001428 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001429 f1 <= l3
1430 with self.assertRaises(TypeError):
1431 f1 <= l1
1432 with self.assertRaises(TypeError):
1433 f1 <= l2
1434
1435 # proper superset
1436 self.assertTrue(f3 > f1)
1437 self.assertFalse(f1 > f1)
1438 self.assertFalse(f2 > f1)
1439 self.assertTrue(r3 > r1)
1440 self.assertFalse(f1 > r1)
1441 self.assertFalse(f2 > r1)
1442 self.assertTrue(r3 > r1)
1443 self.assertFalse(r1 > r1)
1444 self.assertFalse(r2 > r1)
1445 with self.assertRaises(TypeError):
1446 f1 > l3
1447 with self.assertRaises(TypeError):
1448 f1 > l1
1449 with self.assertRaises(TypeError):
1450 f1 > l2
1451
1452 # any superset
1453 self.assertTrue(f3 >= f1)
1454 self.assertTrue(f1 >= f1)
1455 self.assertFalse(f2 >= f1)
1456 self.assertTrue(r3 >= r1)
1457 self.assertTrue(f1 >= r1)
1458 self.assertFalse(f2 >= r1)
1459 self.assertTrue(r3 >= r1)
1460 self.assertTrue(r1 >= r1)
1461 self.assertFalse(r2 >= r1)
1462 with self.assertRaises(TypeError):
1463 f1 >= l3
1464 with self.assertRaises(TypeError):
1465 f1 >=l1
1466 with self.assertRaises(TypeError):
1467 f1 >= l2
1468
1469 # equality
1470 self.assertTrue(f1 == f1)
1471 self.assertTrue(r1 == f1)
1472 self.assertTrue(f1 == r1)
1473 self.assertFalse(f1 == f3)
1474 self.assertFalse(r1 == f3)
1475 self.assertFalse(f1 == r3)
1476 self.assertFalse(f1 == l3)
1477 self.assertFalse(f1 == l1)
1478 self.assertFalse(f1 == l2)
1479
1480 # inequality
1481 self.assertFalse(f1 != f1)
1482 self.assertFalse(r1 != f1)
1483 self.assertFalse(f1 != r1)
1484 self.assertTrue(f1 != f3)
1485 self.assertTrue(r1 != f3)
1486 self.assertTrue(f1 != r3)
1487 self.assertTrue(f1 != l3)
1488 self.assertTrue(f1 != l1)
1489 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001490
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001491 def test_Mapping(self):
1492 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001493 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001494 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001495 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1496 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001497 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001498 def __len__(self):
1499 return 0
1500 def __getitem__(self, i):
1501 raise IndexError
1502 def __iter__(self):
1503 return iter(())
1504 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001505 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001506
1507 def test_MutableMapping(self):
1508 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001509 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001510 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001511 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1512 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001513
Raymond Hettinger9117c752010-08-22 07:44:24 +00001514 def test_MutableMapping_subclass(self):
1515 # Test issue 9214
1516 mymap = UserDict()
1517 mymap['red'] = 5
1518 self.assertIsInstance(mymap.keys(), Set)
1519 self.assertIsInstance(mymap.keys(), KeysView)
1520 self.assertIsInstance(mymap.items(), Set)
1521 self.assertIsInstance(mymap.items(), ItemsView)
1522
1523 mymap = UserDict()
1524 mymap['red'] = 5
1525 z = mymap.keys() | {'orange'}
1526 self.assertIsInstance(z, set)
1527 list(z)
1528 mymap['blue'] = 7 # Shouldn't affect 'z'
1529 self.assertEqual(sorted(z), ['orange', 'red'])
1530
1531 mymap = UserDict()
1532 mymap['red'] = 5
1533 z = mymap.items() | {('orange', 3)}
1534 self.assertIsInstance(z, set)
1535 list(z)
1536 mymap['blue'] = 7 # Shouldn't affect 'z'
1537 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1538
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001539 def test_Sequence(self):
1540 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001541 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001542 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001543 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001544 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001545 self.assertIsInstance(memoryview(b""), Sequence)
1546 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001547 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001548 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1549 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001550
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001551 def test_Sequence_mixins(self):
1552 class SequenceSubclass(Sequence):
1553 def __init__(self, seq=()):
1554 self.seq = seq
1555
1556 def __getitem__(self, index):
1557 return self.seq[index]
1558
1559 def __len__(self):
1560 return len(self.seq)
1561
1562 # Compare Sequence.index() behavior to (list|str).index() behavior
1563 def assert_index_same(seq1, seq2, index_args):
1564 try:
1565 expected = seq1.index(*index_args)
1566 except ValueError:
1567 with self.assertRaises(ValueError):
1568 seq2.index(*index_args)
1569 else:
1570 actual = seq2.index(*index_args)
1571 self.assertEqual(
1572 actual, expected, '%r.index%s' % (seq1, index_args))
1573
1574 for ty in list, str:
1575 nativeseq = ty('abracadabra')
1576 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1577 seqseq = SequenceSubclass(nativeseq)
1578 for letter in set(nativeseq) | {'z'}:
1579 assert_index_same(nativeseq, seqseq, (letter,))
1580 for start in range(-3, len(nativeseq) + 3):
1581 assert_index_same(nativeseq, seqseq, (letter, start))
1582 for stop in range(-3, len(nativeseq) + 3):
1583 assert_index_same(
1584 nativeseq, seqseq, (letter, start, stop))
1585
Guido van Rossumd05eb002007-11-21 22:26:24 +00001586 def test_ByteString(self):
1587 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001588 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001589 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001590 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001591 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001592 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001593 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001594 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001595
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001596 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001597 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001598 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001599 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001600 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001601 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001602 self.assertTrue(issubclass(sample, MutableSequence))
1603 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001604 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1605 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001606
Eli Bendersky0716a572011-03-04 10:38:14 +00001607 def test_MutableSequence_mixins(self):
1608 # Test the mixins of MutableSequence by creating a miminal concrete
1609 # class inherited from it.
1610 class MutableSequenceSubclass(MutableSequence):
1611 def __init__(self):
1612 self.lst = []
1613
1614 def __setitem__(self, index, value):
1615 self.lst[index] = value
1616
1617 def __getitem__(self, index):
1618 return self.lst[index]
1619
1620 def __len__(self):
1621 return len(self.lst)
1622
1623 def __delitem__(self, index):
1624 del self.lst[index]
1625
1626 def insert(self, index, value):
1627 self.lst.insert(index, value)
1628
1629 mss = MutableSequenceSubclass()
1630 mss.append(0)
1631 mss.extend((1, 2, 3, 4))
1632 self.assertEqual(len(mss), 5)
1633 self.assertEqual(mss[3], 3)
1634 mss.reverse()
1635 self.assertEqual(mss[3], 1)
1636 mss.pop()
1637 self.assertEqual(len(mss), 4)
1638 mss.remove(3)
1639 self.assertEqual(len(mss), 3)
1640 mss += (10, 20, 30)
1641 self.assertEqual(len(mss), 6)
1642 self.assertEqual(mss[-1], 30)
1643 mss.clear()
1644 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001645
1646################################################################################
1647### Counter
1648################################################################################
1649
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001650class CounterSubclassWithSetItem(Counter):
1651 # Test a counter subclass that overrides __setitem__
1652 def __init__(self, *args, **kwds):
1653 self.called = False
1654 Counter.__init__(self, *args, **kwds)
1655 def __setitem__(self, key, value):
1656 self.called = True
1657 Counter.__setitem__(self, key, value)
1658
1659class CounterSubclassWithGet(Counter):
1660 # Test a counter subclass that overrides get()
1661 def __init__(self, *args, **kwds):
1662 self.called = False
1663 Counter.__init__(self, *args, **kwds)
1664 def get(self, key, default):
1665 self.called = True
1666 return Counter.get(self, key, default)
1667
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001668class TestCounter(unittest.TestCase):
1669
1670 def test_basics(self):
1671 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001672 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1673 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001674 self.assertIsInstance(c, dict)
1675 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001676 self.assertTrue(issubclass(Counter, dict))
1677 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001678 self.assertEqual(len(c), 3)
1679 self.assertEqual(sum(c.values()), 6)
1680 self.assertEqual(sorted(c.values()), [1, 2, 3])
1681 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1682 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1683 self.assertEqual(sorted(c.items()),
1684 [('a', 3), ('b', 2), ('c', 1)])
1685 self.assertEqual(c['b'], 2)
1686 self.assertEqual(c['z'], 0)
1687 self.assertEqual(c.__contains__('c'), True)
1688 self.assertEqual(c.__contains__('z'), False)
1689 self.assertEqual(c.get('b', 10), 2)
1690 self.assertEqual(c.get('z', 10), 10)
1691 self.assertEqual(c, dict(a=3, b=2, c=1))
1692 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1693 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1694 for i in range(5):
1695 self.assertEqual(c.most_common(i),
1696 [('a', 3), ('b', 2), ('c', 1)][:i])
1697 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1698 c['a'] += 1 # increment an existing value
1699 c['b'] -= 2 # sub existing value to zero
1700 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001701 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001702 c['d'] -= 2 # sub from a missing value
1703 c['e'] = -5 # directly assign a missing value
1704 c['f'] += 4 # add to a missing value
1705 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1706 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1707 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001708 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001709 for i in range(3):
1710 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001711 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001712 c.clear()
1713 self.assertEqual(c, {})
1714 self.assertEqual(repr(c), 'Counter()')
1715 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1716 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001717 c.update(dict(a=5, b=3))
1718 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001719 c.update(Counter('a' * 50 + 'b' * 30))
1720 c.update() # test case with no args
1721 c.__init__('a' * 500 + 'b' * 300)
1722 c.__init__('cdc')
1723 c.__init__()
1724 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1725 self.assertEqual(c.setdefault('d', 5), 1)
1726 self.assertEqual(c['d'], 1)
1727 self.assertEqual(c.setdefault('e', 5), 5)
1728 self.assertEqual(c['e'], 5)
1729
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001730 def test_init(self):
1731 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1732 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1733 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1734 self.assertRaises(TypeError, Counter, 42)
1735 self.assertRaises(TypeError, Counter, (), ())
1736 self.assertRaises(TypeError, Counter.__init__)
1737
1738 def test_update(self):
1739 c = Counter()
1740 c.update(self=42)
1741 self.assertEqual(list(c.items()), [('self', 42)])
1742 c = Counter()
1743 c.update(iterable=42)
1744 self.assertEqual(list(c.items()), [('iterable', 42)])
1745 c = Counter()
1746 c.update(iterable=None)
1747 self.assertEqual(list(c.items()), [('iterable', None)])
1748 self.assertRaises(TypeError, Counter().update, 42)
1749 self.assertRaises(TypeError, Counter().update, {}, {})
1750 self.assertRaises(TypeError, Counter.update)
1751
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001752 def test_copying(self):
1753 # Check that counters are copyable, deepcopyable, picklable, and
1754 #have a repr/eval round-trip
1755 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001756 def check(dup):
1757 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1758 self.assertIsNot(dup, words, msg)
1759 self.assertEqual(dup, words)
1760 check(words.copy())
1761 check(copy.copy(words))
1762 check(copy.deepcopy(words))
1763 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1764 with self.subTest(proto=proto):
1765 check(pickle.loads(pickle.dumps(words, proto)))
1766 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001767 update_test = Counter()
1768 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001769 check(update_test)
1770 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001771
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001772 def test_copy_subclass(self):
1773 class MyCounter(Counter):
1774 pass
1775 c = MyCounter('slartibartfast')
1776 d = c.copy()
1777 self.assertEqual(d, c)
1778 self.assertEqual(len(d), len(c))
1779 self.assertEqual(type(d), type(c))
1780
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001781 def test_conversions(self):
1782 # Convert to: set, list, dict
1783 s = 'she sells sea shells by the sea shore'
1784 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1785 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1786 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1787 self.assertEqual(set(Counter(s)), set(s))
1788
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001789 def test_invariant_for_the_in_operator(self):
1790 c = Counter(a=10, b=-2, c=0)
1791 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001792 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001793 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001794
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001795 def test_multiset_operations(self):
1796 # Verify that adding a zero counter will strip zeros and negatives
1797 c = Counter(a=10, b=-2, c=0) + Counter()
1798 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001799
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001800 elements = 'abcd'
1801 for i in range(1000):
1802 # test random pairs of multisets
1803 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001804 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001805 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001806 q.update(h=1, i=-1, j=0)
1807 for counterop, numberop in [
1808 (Counter.__add__, lambda x, y: max(0, x+y)),
1809 (Counter.__sub__, lambda x, y: max(0, x-y)),
1810 (Counter.__or__, lambda x, y: max(0,x,y)),
1811 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001812 ]:
1813 result = counterop(p, q)
1814 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001815 self.assertEqual(numberop(p[x], q[x]), result[x],
1816 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001817 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001818 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001819
1820 elements = 'abcdef'
1821 for i in range(100):
1822 # verify that random multisets with no repeats are exactly like sets
1823 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1824 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1825 for counterop, setop in [
1826 (Counter.__sub__, set.__sub__),
1827 (Counter.__or__, set.__or__),
1828 (Counter.__and__, set.__and__),
1829 ]:
1830 counter_result = counterop(p, q)
1831 set_result = setop(set(p.elements()), set(q.elements()))
1832 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001833
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001834 def test_inplace_operations(self):
1835 elements = 'abcd'
1836 for i in range(1000):
1837 # test random pairs of multisets
1838 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1839 p.update(e=1, f=-1, g=0)
1840 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1841 q.update(h=1, i=-1, j=0)
1842 for inplace_op, regular_op in [
1843 (Counter.__iadd__, Counter.__add__),
1844 (Counter.__isub__, Counter.__sub__),
1845 (Counter.__ior__, Counter.__or__),
1846 (Counter.__iand__, Counter.__and__),
1847 ]:
1848 c = p.copy()
1849 c_id = id(c)
1850 regular_result = regular_op(c, q)
1851 inplace_result = inplace_op(c, q)
1852 self.assertEqual(inplace_result, regular_result)
1853 self.assertEqual(id(inplace_result), c_id)
1854
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001855 def test_subtract(self):
1856 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1857 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1858 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1859 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1860 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1861 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1862 c = Counter('aaabbcd')
1863 c.subtract('aaaabbcce')
1864 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001865
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001866 c = Counter()
1867 c.subtract(self=42)
1868 self.assertEqual(list(c.items()), [('self', -42)])
1869 c = Counter()
1870 c.subtract(iterable=42)
1871 self.assertEqual(list(c.items()), [('iterable', -42)])
1872 self.assertRaises(TypeError, Counter().subtract, 42)
1873 self.assertRaises(TypeError, Counter().subtract, {}, {})
1874 self.assertRaises(TypeError, Counter.subtract)
1875
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001876 def test_unary(self):
1877 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1878 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1879 self.assertEqual(dict(-c), dict(a=5))
1880
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001881 def test_repr_nonsortable(self):
1882 c = Counter(a=2, b=None)
1883 r = repr(c)
1884 self.assertIn("'a': 2", r)
1885 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001886
Raymond Hettinger426e0522011-01-03 02:12:02 +00001887 def test_helper_function(self):
1888 # two paths, one for real dicts and one for other mappings
1889 elems = list('abracadabra')
1890
1891 d = dict()
1892 _count_elements(d, elems)
1893 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1894
1895 m = OrderedDict()
1896 _count_elements(m, elems)
1897 self.assertEqual(m,
1898 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1899
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001900 # test fidelity to the pure python version
1901 c = CounterSubclassWithSetItem('abracadabra')
1902 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001903 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001904 c = CounterSubclassWithGet('abracadabra')
1905 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001906 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001907
Raymond Hettinger499e1932011-02-23 07:56:53 +00001908
1909################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001910### Run tests
1911################################################################################
1912
Guido van Rossumd8faa362007-04-27 19:54:29 +00001913def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001914 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001915 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001916 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06001917 TestUserObjects,
1918 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001919 support.run_unittest(*test_classes)
1920 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001921
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001922
Guido van Rossumd8faa362007-04-27 19:54:29 +00001923if __name__ == "__main__":
1924 test_main(verbose=True)