blob: 7e106affbe032a809949ccf1266e2523a7e3fccd [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001"""Unit tests for collections.py."""
2
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02003import collections
4import copy
5import doctest
Raymond Hettinger499b2ee2009-05-27 01:53:46 +00006import keyword
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02007import operator
8import pickle
9from random import choice, randrange
Raymond Hettinger499b2ee2009-05-27 01:53:46 +000010import re
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020011import string
R. David Murray378c0cf2010-02-24 01:46:21 +000012import sys
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020013from test import support
Yury Selivanov75445082015-05-11 22:57:16 -040014import types
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020015import unittest
16
17from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger573b44c2015-05-22 16:56:32 -070018from collections import UserDict, UserString, UserList
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000019from collections import ChainMap
Raymond Hettinger32ea1652015-03-21 01:37:37 -070020from collections import deque
Yury Selivanov22214ab2016-11-16 18:25:04 -050021from collections.abc import Awaitable, Coroutine
22from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator
Guido van Rossum16ca06b2016-04-04 10:59:29 -070023from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
Guido van Rossumf0666942016-08-23 10:47:07 -070024from collections.abc import Sized, Container, Callable, Collection
Raymond Hettinger57d1a882011-02-23 00:46:28 +000025from collections.abc import Set, MutableSet
Raymond Hettinger584e8ae2016-05-05 11:14:06 +030026from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
Raymond Hettinger57d1a882011-02-23 00:46:28 +000027from collections.abc import Sequence, MutableSequence
28from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000029
Raymond Hettinger499e1932011-02-23 07:56:53 +000030
Raymond Hettinger573b44c2015-05-22 16:56:32 -070031class TestUserObjects(unittest.TestCase):
32 def _superset_test(self, a, b):
33 self.assertGreaterEqual(
34 set(dir(a)),
35 set(dir(b)),
36 '{a} should have all the methods of {b}'.format(
37 a=a.__name__,
38 b=b.__name__,
39 ),
40 )
41 def test_str_protocol(self):
42 self._superset_test(UserString, str)
43
44 def test_list_protocol(self):
45 self._superset_test(UserList, list)
46
47 def test_dict_protocol(self):
48 self._superset_test(UserDict, dict)
49
50
Raymond Hettinger499e1932011-02-23 07:56:53 +000051################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000052### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000053################################################################################
54
55class TestChainMap(unittest.TestCase):
56
57 def test_basics(self):
58 c = ChainMap()
59 c['a'] = 1
60 c['b'] = 2
61 d = c.new_child()
62 d['b'] = 20
63 d['c'] = 30
64 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
65 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
66 self.assertEqual(len(d), 3) # check len
67 for key in 'abc': # check contains
68 self.assertIn(key, d)
69 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
70 self.assertEqual(d.get(k, 100), v)
71
72 del d['b'] # unmask a value
73 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
74 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
75 self.assertEqual(len(d), 3) # check len
76 for key in 'abc': # check contains
77 self.assertIn(key, d)
78 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
79 self.assertEqual(d.get(k, 100), v)
80 self.assertIn(repr(d), [ # check repr
81 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
82 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
83 ])
84
85 for e in d.copy(), copy.copy(d): # check shallow copies
86 self.assertEqual(d, e)
87 self.assertEqual(d.maps, e.maps)
88 self.assertIsNot(d, e)
89 self.assertIsNot(d.maps[0], e.maps[0])
90 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
91 self.assertIs(m1, m2)
92
Serhiy Storchakabad12572014-12-15 14:03:42 +020093 # check deep copies
94 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
95 e = pickle.loads(pickle.dumps(d, proto))
96 self.assertEqual(d, e)
97 self.assertEqual(d.maps, e.maps)
98 self.assertIsNot(d, e)
99 for m1, m2 in zip(d.maps, e.maps):
100 self.assertIsNot(m1, m2, e)
101 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +0000102 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200103 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000104 self.assertEqual(d, e)
105 self.assertEqual(d.maps, e.maps)
106 self.assertIsNot(d, e)
107 for m1, m2 in zip(d.maps, e.maps):
108 self.assertIsNot(m1, m2, e)
109
Raymond Hettingerd0321312011-02-26 06:53:58 +0000110 f = d.new_child()
111 f['b'] = 5
112 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
113 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
114 self.assertEqual(f['b'], 5) # find first in chain
115 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000116
Martin Pantereb995702016-07-28 01:11:04 +0000117 def test_constructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000118 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000119 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
120
Raymond Hettingerd0321312011-02-26 06:53:58 +0000121 def test_bool(self):
122 self.assertFalse(ChainMap())
123 self.assertFalse(ChainMap({}, {}))
124 self.assertTrue(ChainMap({1:2}, {}))
125 self.assertTrue(ChainMap({}, {1:2}))
126
Raymond Hettinger499e1932011-02-23 07:56:53 +0000127 def test_missing(self):
128 class DefaultChainMap(ChainMap):
129 def __missing__(self, key):
130 return 999
131 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
132 for k, v in dict(a=1, b=2, c=30, d=999).items():
133 self.assertEqual(d[k], v) # check __getitem__ w/missing
134 for k, v in dict(a=1, b=2, c=30, d=77).items():
135 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
136 for k, v in dict(a=True, b=True, c=True, d=False).items():
137 self.assertEqual(k in d, v) # check __contains__ w/missing
138 self.assertEqual(d.pop('a', 1001), 1, d)
139 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
140 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
141 with self.assertRaises(KeyError):
142 d.popitem()
143
144 def test_dict_coercion(self):
145 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
146 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
147 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
148
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000149 def test_new_child(self):
150 'Tests for changes for issue #16613.'
151 c = ChainMap()
152 c['a'] = 1
153 c['b'] = 2
154 m = {'b':20, 'c': 30}
155 d = c.new_child(m)
156 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
157 self.assertIs(m, d.maps[0])
158
159 # Use a different map than a dict
160 class lowerdict(dict):
161 def __getitem__(self, key):
162 if isinstance(key, str):
163 key = key.lower()
164 return dict.__getitem__(self, key)
165 def __contains__(self, key):
166 if isinstance(key, str):
167 key = key.lower()
168 return dict.__contains__(self, key)
169
170 c = ChainMap()
171 c['a'] = 1
172 c['b'] = 2
173 m = lowerdict(b=20, c=30)
174 d = c.new_child(m)
175 self.assertIs(m, d.maps[0])
176 for key in 'abc': # check contains
177 self.assertIn(key, d)
178 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
179 self.assertEqual(d.get(k, 100), v)
180
Raymond Hettinger499e1932011-02-23 07:56:53 +0000181
182################################################################################
183### Named Tuples
184################################################################################
185
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000186TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000187
188class TestNamedTuple(unittest.TestCase):
189
190 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000191 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000192 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000193 self.assertEqual(Point.__slots__, ())
194 self.assertEqual(Point.__module__, __name__)
195 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000196 self.assertEqual(Point._fields, ('x', 'y'))
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000197
198 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
199 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
200 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
201
202 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
203 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
204 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000205 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000206 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
207
208 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000209 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000210
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000211 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000212 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000213 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000214 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000215
Christian Heimesfaf2f632008-01-06 16:59:19 +0000216 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
217 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
218
R. David Murray378c0cf2010-02-24 01:46:21 +0000219 @unittest.skipIf(sys.flags.optimize >= 2,
220 "Docstrings are omitted with -O2 and above")
221 def test_factory_doc_attr(self):
222 Point = namedtuple('Point', 'x y')
223 self.assertEqual(Point.__doc__, 'Point(x, y)')
224
Raymond Hettingereac503a2015-05-13 01:09:59 -0700225 @unittest.skipIf(sys.flags.optimize >= 2,
226 "Docstrings are omitted with -O2 and above")
227 def test_doc_writable(self):
228 Point = namedtuple('Point', 'x y')
229 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
230 Point.x.__doc__ = 'docstring for Point.x'
231 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
232
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000233 def test_name_fixer(self):
234 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000235 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
236 [('abc', 'class'), ('abc', '_1')], # field has keyword
237 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
238 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
239 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
240 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000241 ]:
242 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
243
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700244 def test_module_parameter(self):
245 NT = namedtuple('NT', ['x', 'y'], module=collections)
246 self.assertEqual(NT.__module__, collections)
247
Guido van Rossumd8faa362007-04-27 19:54:29 +0000248 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000249 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000250 p = Point(11, 22)
251 self.assertEqual(p, Point(x=11, y=22))
252 self.assertEqual(p, Point(11, y=22))
253 self.assertEqual(p, Point(y=22, x=11))
254 self.assertEqual(p, Point(*(11, 22)))
255 self.assertEqual(p, Point(**dict(x=11, y=22)))
256 self.assertRaises(TypeError, Point, 1) # too few args
257 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
258 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
259 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
260 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000261 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000262 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000263 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
264 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700265 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000266
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000267 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000268 p._replace(x=1, error=2)
269 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000270 pass
271 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000272 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000273
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000274 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000275 Point = namedtuple('Point', 'x, y')
276 p = Point(x=11, y=22)
277 self.assertEqual(repr(p), 'Point(x=11, y=22)')
278
279 # verify that fieldspec can be a non-string sequence
280 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000281 p = Point(x=11, y=22)
282 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000283
284 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000285 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000286 p = Point(11, 22)
287
Ezio Melottie9615932010-01-24 19:26:24 +0000288 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000289 self.assertEqual(p, (11, 22)) # matches a real tuple
290 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
291 self.assertEqual(list(p), [11, 22]) # coercable to a list
292 self.assertEqual(max(p), 22) # iterable
293 self.assertEqual(max(*p), 22) # star-able
294 x, y = p
295 self.assertEqual(p, (x, y)) # unpacks like a tuple
296 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
297 self.assertRaises(IndexError, p.__getitem__, 3)
298
299 self.assertEqual(p.x, x)
300 self.assertEqual(p.y, y)
301 self.assertRaises(AttributeError, eval, 'p.z', locals())
302
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000303 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000304 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000305 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000306 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000307 self.assertEqual(repr(Zero()), 'Zero()')
308 self.assertEqual(Zero()._asdict(), {})
309 self.assertEqual(Zero()._fields, ())
310
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000311 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000312 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000313 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000314 self.assertEqual(Dot(1).d, 1)
315 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
316 self.assertEqual(Dot(1)._asdict(), {'d':1})
317 self.assertEqual(Dot(1)._replace(d=999), (999,))
318 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000319
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200320 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200321 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000322 for j in range(10)]) for i in range(n)))
323 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000324 Big = namedtuple('Big', names)
325 b = Big(*range(n))
326 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000327 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000328 for pos, name in enumerate(names):
329 self.assertEqual(getattr(b, name), pos)
330 repr(b) # make sure repr() doesn't blow-up
331 d = b._asdict()
332 d_expected = dict(zip(names, range(n)))
333 self.assertEqual(d, d_expected)
334 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
335 b2_expected = list(range(n))
336 b2_expected[1] = 999
337 b2_expected[-5] = 42
338 self.assertEqual(b2, tuple(b2_expected))
339 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000340
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000341 def test_pickle(self):
342 p = TestNT(x=10, y=20, z=30)
343 for module in (pickle,):
344 loads = getattr(module, 'loads')
345 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500346 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000347 q = loads(dumps(p, protocol))
348 self.assertEqual(p, q)
349 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700350 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000351
352 def test_copy(self):
353 p = TestNT(x=10, y=20, z=30)
354 for copier in copy.copy, copy.deepcopy:
355 q = copier(p)
356 self.assertEqual(p, q)
357 self.assertEqual(p._fields, q._fields)
358
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000359 def test_name_conflicts(self):
360 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
361 # failed when used as field names. Test to make sure these now work.
362 T = namedtuple('T', 'itemgetter property self cls tuple')
363 t = T(1, 2, 3, 4, 5)
364 self.assertEqual(t, (1,2,3,4,5))
365 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
366 self.assertEqual(newt, (10,20,30,40,50))
367
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700368 # Broader test of all interesting names taken from the code, old
369 # template, and an example
370 words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create',
371 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper',
372 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note',
373 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError',
374 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add',
375 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments',
376 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot',
377 'class_namespace', 'classmethod', 'cls', 'collections', 'convert',
378 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict',
379 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect',
380 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f',
381 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame',
382 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater',
383 'has', 'help', 'identifiers', 'index', 'indexable', 'instance',
384 'instantiate', 'interning', 'introspection', 'isidentifier',
385 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords',
386 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata',
387 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named',
388 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new',
389 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option',
390 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional',
391 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr',
392 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen',
393 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start',
394 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys',
395 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new',
396 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use',
397 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where',
398 'which', 'work', 'x', 'y', 'z', 'zip'}
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000399 T = namedtuple('T', words)
400 # test __new__
401 values = tuple(range(len(words)))
402 t = T(*values)
403 self.assertEqual(t, values)
404 t = T(**dict(zip(T._fields, values)))
405 self.assertEqual(t, values)
406 # test _make
407 t = T._make(values)
408 self.assertEqual(t, values)
409 # exercise __repr__
410 repr(t)
411 # test _asdict
412 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
413 # test _replace
414 t = T._make(values)
415 newvalues = tuple(v*10 for v in values)
416 newt = t._replace(**dict(zip(T._fields, newvalues)))
417 self.assertEqual(newt, newvalues)
418 # test _fields
419 self.assertEqual(T._fields, tuple(words))
420 # test __getnewargs__
421 self.assertEqual(t.__getnewargs__(), values)
422
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000423 def test_repr(self):
Raymond Hettinger8b57d732017-09-10 10:23:36 -0700424 A = namedtuple('A', 'x')
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000425 self.assertEqual(repr(A(1)), 'A(x=1)')
426 # repr should show the name of the subclass
427 class B(A):
428 pass
429 self.assertEqual(repr(B(1)), 'B(x=1)')
430
Raymond Hettinger6538b432016-08-16 10:55:43 -0700431 def test_keyword_only_arguments(self):
432 # See issue 25628
Raymond Hettinger6538b432016-08-16 10:55:43 -0700433 with self.assertRaises(TypeError):
434 NT = namedtuple('NT', ['x', 'y'], True)
435
436 NT = namedtuple('NT', ['abc', 'def'], rename=True)
437 self.assertEqual(NT._fields, ('abc', '_1'))
438 with self.assertRaises(TypeError):
439 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000440
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700441 def test_namedtuple_subclass_issue_24931(self):
442 class Point(namedtuple('_Point', ['x', 'y'])):
443 pass
444
445 a = Point(3, 4)
446 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
447
448 a.w = 5
449 self.assertEqual(a.__dict__, {'w': 5})
450
451
Raymond Hettinger499e1932011-02-23 07:56:53 +0000452################################################################################
453### Abstract Base Classes
454################################################################################
455
Raymond Hettingerae650182009-01-28 23:33:59 +0000456class ABCTestCase(unittest.TestCase):
457
458 def validate_abstract_methods(self, abc, *names):
459 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
460
461 # everything should work will all required methods are present
462 C = type('C', (abc,), methodstubs)
463 C()
464
465 # instantiation should fail if a required method is missing
466 for name in names:
467 stubs = methodstubs.copy()
468 del stubs[name]
469 C = type('C', (abc,), stubs)
470 self.assertRaises(TypeError, C, name)
471
Florent Xiclunace153f62010-03-08 15:34:35 +0000472 def validate_isinstance(self, abc, name):
473 stub = lambda s, *args: 0
474
475 C = type('C', (object,), {'__hash__': None})
476 setattr(C, name, stub)
477 self.assertIsInstance(C(), abc)
478 self.assertTrue(issubclass(C, abc))
479
480 C = type('C', (object,), {'__hash__': None})
481 self.assertNotIsInstance(C(), abc)
482 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000483
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000484 def validate_comparison(self, instance):
485 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
486 operators = {}
487 for op in ops:
488 name = '__' + op + '__'
489 operators[name] = getattr(operator, name)
490
491 class Other:
492 def __init__(self):
493 self.right_side = False
494 def __eq__(self, other):
495 self.right_side = True
496 return True
497 __lt__ = __eq__
498 __gt__ = __eq__
499 __le__ = __eq__
500 __ge__ = __eq__
501 __ne__ = __eq__
502 __ror__ = __eq__
503 __rand__ = __eq__
504 __rxor__ = __eq__
505 __rsub__ = __eq__
506
507 for name, op in operators.items():
508 if not hasattr(instance, name):
509 continue
510 other = Other()
511 op(instance, other)
512 self.assertTrue(other.right_side,'Right side not called for %s.%s'
513 % (type(instance), name))
514
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700515def _test_gen():
516 yield
517
Raymond Hettingerae650182009-01-28 23:33:59 +0000518class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000519
Yury Selivanov75445082015-05-11 22:57:16 -0400520 def test_Awaitable(self):
521 def gen():
522 yield
523
524 @types.coroutine
525 def coro():
526 yield
527
528 async def new_coro():
529 pass
530
531 class Bar:
532 def __await__(self):
533 yield
534
535 class MinimalCoro(Coroutine):
536 def send(self, value):
537 return value
538 def throw(self, typ, val=None, tb=None):
539 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400540 def __await__(self):
541 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400542
543 non_samples = [None, int(), gen(), object()]
544 for x in non_samples:
545 self.assertNotIsInstance(x, Awaitable)
546 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
547
548 samples = [Bar(), MinimalCoro()]
549 for x in samples:
550 self.assertIsInstance(x, Awaitable)
551 self.assertTrue(issubclass(type(x), Awaitable))
552
553 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400554 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
555 # flag don't have '__await__' method, hence can't be instances
556 # of Awaitable. Use inspect.isawaitable to detect them.
557 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400558
559 c = new_coro()
560 self.assertIsInstance(c, Awaitable)
561 c.close() # awoid RuntimeWarning that coro() was not awaited
562
Yury Selivanov56fc6142015-05-29 09:01:29 -0400563 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400564 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400565 self.assertTrue(isinstance(CoroLike(), Awaitable))
566 self.assertTrue(issubclass(CoroLike, Awaitable))
567 CoroLike = None
568 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400569
Yury Selivanov75445082015-05-11 22:57:16 -0400570 def test_Coroutine(self):
571 def gen():
572 yield
573
574 @types.coroutine
575 def coro():
576 yield
577
578 async def new_coro():
579 pass
580
581 class Bar:
582 def __await__(self):
583 yield
584
585 class MinimalCoro(Coroutine):
586 def send(self, value):
587 return value
588 def throw(self, typ, val=None, tb=None):
589 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400590 def __await__(self):
591 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400592
593 non_samples = [None, int(), gen(), object(), Bar()]
594 for x in non_samples:
595 self.assertNotIsInstance(x, Coroutine)
596 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
597
598 samples = [MinimalCoro()]
599 for x in samples:
600 self.assertIsInstance(x, Awaitable)
601 self.assertTrue(issubclass(type(x), Awaitable))
602
603 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400604 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
605 # flag don't have '__await__' method, hence can't be instances
606 # of Coroutine. Use inspect.isawaitable to detect them.
607 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400608
609 c = new_coro()
610 self.assertIsInstance(c, Coroutine)
611 c.close() # awoid RuntimeWarning that coro() was not awaited
612
Yury Selivanov56fc6142015-05-29 09:01:29 -0400613 class CoroLike:
614 def send(self, value):
615 pass
616 def throw(self, typ, val=None, tb=None):
617 pass
618 def close(self):
619 pass
620 def __await__(self):
621 pass
622 self.assertTrue(isinstance(CoroLike(), Coroutine))
623 self.assertTrue(issubclass(CoroLike, Coroutine))
624
625 class CoroLike:
626 def send(self, value):
627 pass
628 def close(self):
629 pass
630 def __await__(self):
631 pass
632 self.assertFalse(isinstance(CoroLike(), Coroutine))
633 self.assertFalse(issubclass(CoroLike, Coroutine))
634
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000635 def test_Hashable(self):
636 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000637 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000638 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000639 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000640 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000641 # Check some hashables
642 samples = [None,
643 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000644 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000645 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000646 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000647 ]
648 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000649 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000650 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000651 self.assertRaises(TypeError, Hashable)
652 # Check direct subclassing
653 class H(Hashable):
654 def __hash__(self):
655 return super().__hash__()
656 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000657 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000658 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000659 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000660
Yury Selivanove0104ae2015-05-14 12:19:16 -0400661 def test_AsyncIterable(self):
662 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400663 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400664 return self
665 self.assertTrue(isinstance(AI(), AsyncIterable))
666 self.assertTrue(issubclass(AI, AsyncIterable))
667 # Check some non-iterables
668 non_samples = [None, object, []]
669 for x in non_samples:
670 self.assertNotIsInstance(x, AsyncIterable)
671 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
672 self.validate_abstract_methods(AsyncIterable, '__aiter__')
673 self.validate_isinstance(AsyncIterable, '__aiter__')
674
675 def test_AsyncIterator(self):
676 class AI:
Yury Selivanovfaa135a2017-10-06 02:08:57 -0400677 def __aiter__(self):
Yury Selivanove0104ae2015-05-14 12:19:16 -0400678 return self
679 async def __anext__(self):
680 raise StopAsyncIteration
681 self.assertTrue(isinstance(AI(), AsyncIterator))
682 self.assertTrue(issubclass(AI, AsyncIterator))
683 non_samples = [None, object, []]
684 # Check some non-iterables
685 for x in non_samples:
686 self.assertNotIsInstance(x, AsyncIterator)
687 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
688 # Similarly to regular iterators (see issue 10565)
689 class AnextOnly:
690 async def __anext__(self):
691 raise StopAsyncIteration
692 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
693 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
694
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000695 def test_Iterable(self):
696 # Check some non-iterables
697 non_samples = [None, 42, 3.14, 1j]
698 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000699 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000700 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000701 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000702 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000703 tuple(), list(), set(), frozenset(), dict(),
704 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700705 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000706 (x for x in []),
707 ]
708 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000709 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000710 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000711 # Check direct subclassing
712 class I(Iterable):
713 def __iter__(self):
714 return super().__iter__()
715 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000716 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000717 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000718 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700719 # Check None blocking
720 class It:
721 def __iter__(self): return iter([])
722 class ItBlocked(It):
723 __iter__ = None
724 self.assertTrue(issubclass(It, Iterable))
725 self.assertTrue(isinstance(It(), Iterable))
726 self.assertFalse(issubclass(ItBlocked, Iterable))
727 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000728
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700729 def test_Reversible(self):
730 # Check some non-reversibles
731 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()]
732 for x in non_samples:
733 self.assertNotIsInstance(x, Reversible)
734 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700735 # Check some non-reversible iterables
736 non_reversibles = [dict().keys(), dict().items(), dict().values(),
737 Counter(), Counter().keys(), Counter().items(),
738 Counter().values(), _test_gen(),
739 (x for x in []), iter([]), reversed([])]
740 for x in non_reversibles:
741 self.assertNotIsInstance(x, Reversible)
742 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
743 # Check some reversible iterables
744 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
745 OrderedDict().keys(), OrderedDict().items(),
746 OrderedDict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700747 for x in samples:
748 self.assertIsInstance(x, Reversible)
749 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
750 # Check also Mapping, MutableMapping, and Sequence
751 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
752 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
753 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
754 # Check direct subclassing
755 class R(Reversible):
756 def __iter__(self):
757 return iter(list())
758 def __reversed__(self):
759 return iter(list())
760 self.assertEqual(list(reversed(R())), [])
761 self.assertFalse(issubclass(float, R))
762 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700763 # Check reversible non-iterable (which is not Reversible)
764 class RevNoIter:
765 def __reversed__(self): return reversed([])
766 class RevPlusIter(RevNoIter):
767 def __iter__(self): return iter([])
768 self.assertFalse(issubclass(RevNoIter, Reversible))
769 self.assertFalse(isinstance(RevNoIter(), Reversible))
770 self.assertTrue(issubclass(RevPlusIter, Reversible))
771 self.assertTrue(isinstance(RevPlusIter(), Reversible))
772 # Check None blocking
773 class Rev:
774 def __iter__(self): return iter([])
775 def __reversed__(self): return reversed([])
776 class RevItBlocked(Rev):
777 __iter__ = None
778 class RevRevBlocked(Rev):
779 __reversed__ = None
780 self.assertTrue(issubclass(Rev, Reversible))
781 self.assertTrue(isinstance(Rev(), Reversible))
782 self.assertFalse(issubclass(RevItBlocked, Reversible))
783 self.assertFalse(isinstance(RevItBlocked(), Reversible))
784 self.assertFalse(issubclass(RevRevBlocked, Reversible))
785 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700786
Guido van Rossumf0666942016-08-23 10:47:07 -0700787 def test_Collection(self):
788 # Check some non-collections
789 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
790 for x in non_collections:
791 self.assertNotIsInstance(x, Collection)
792 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
793 # Check some non-collection iterables
794 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
795 (x for x in []), dict().values()]
796 for x in non_col_iterables:
797 self.assertNotIsInstance(x, Collection)
798 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
799 # Check some collections
800 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
801 list(), dict().keys(), dict().items()]
802 for x in samples:
803 self.assertIsInstance(x, Collection)
804 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
805 # Check also Mapping, MutableMapping, etc.
806 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
807 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
808 self.assertTrue(issubclass(MutableMapping, Collection),
809 repr(MutableMapping))
810 self.assertTrue(issubclass(Set, Collection), repr(Set))
811 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
812 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
813 # Check direct subclassing
814 class Col(Collection):
815 def __iter__(self):
816 return iter(list())
817 def __len__(self):
818 return 0
819 def __contains__(self, item):
820 return False
821 class DerCol(Col): pass
822 self.assertEqual(list(iter(Col())), [])
823 self.assertFalse(issubclass(list, Col))
824 self.assertFalse(issubclass(set, Col))
825 self.assertFalse(issubclass(float, Col))
826 self.assertEqual(list(iter(DerCol())), [])
827 self.assertFalse(issubclass(list, DerCol))
828 self.assertFalse(issubclass(set, DerCol))
829 self.assertFalse(issubclass(float, DerCol))
830 self.validate_abstract_methods(Collection, '__len__', '__iter__',
831 '__contains__')
832 # Check sized container non-iterable (which is not Collection) etc.
833 class ColNoIter:
834 def __len__(self): return 0
835 def __contains__(self, item): return False
836 class ColNoSize:
837 def __iter__(self): return iter([])
838 def __contains__(self, item): return False
839 class ColNoCont:
840 def __iter__(self): return iter([])
841 def __len__(self): return 0
842 self.assertFalse(issubclass(ColNoIter, Collection))
843 self.assertFalse(isinstance(ColNoIter(), Collection))
844 self.assertFalse(issubclass(ColNoSize, Collection))
845 self.assertFalse(isinstance(ColNoSize(), Collection))
846 self.assertFalse(issubclass(ColNoCont, Collection))
847 self.assertFalse(isinstance(ColNoCont(), Collection))
848 # Check None blocking
849 class SizeBlock:
850 def __iter__(self): return iter([])
851 def __contains__(self): return False
852 __len__ = None
853 class IterBlock:
854 def __len__(self): return 0
855 def __contains__(self): return True
856 __iter__ = None
857 self.assertFalse(issubclass(SizeBlock, Collection))
858 self.assertFalse(isinstance(SizeBlock(), Collection))
859 self.assertFalse(issubclass(IterBlock, Collection))
860 self.assertFalse(isinstance(IterBlock(), Collection))
861 # Check None blocking in subclass
862 class ColImpl:
863 def __iter__(self):
864 return iter(list())
865 def __len__(self):
866 return 0
867 def __contains__(self, item):
868 return False
869 class NonCol(ColImpl):
870 __contains__ = None
871 self.assertFalse(issubclass(NonCol, Collection))
872 self.assertFalse(isinstance(NonCol(), Collection))
873
874
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000875 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000876 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000877 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000878 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000879 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000880 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000881 iter(tuple()), iter(list()), iter(dict()),
882 iter(set()), iter(frozenset()),
883 iter(dict().keys()), iter(dict().items()),
884 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700885 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000886 (x for x in []),
887 ]
888 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000889 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000890 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000891 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
892
893 # Issue 10565
894 class NextOnly:
895 def __next__(self):
896 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800897 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000898 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000899
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400900 def test_Generator(self):
901 class NonGen1:
902 def __iter__(self): return self
903 def __next__(self): return None
904 def close(self): pass
905 def throw(self, typ, val=None, tb=None): pass
906
907 class NonGen2:
908 def __iter__(self): return self
909 def __next__(self): return None
910 def close(self): pass
911 def send(self, value): return value
912
913 class NonGen3:
914 def close(self): pass
915 def send(self, value): return value
916 def throw(self, typ, val=None, tb=None): pass
917
918 non_samples = [
919 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
920 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
921 for x in non_samples:
922 self.assertNotIsInstance(x, Generator)
923 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
924
925 class Gen:
926 def __iter__(self): return self
927 def __next__(self): return None
928 def close(self): pass
929 def send(self, value): return value
930 def throw(self, typ, val=None, tb=None): pass
931
932 class MinimalGen(Generator):
933 def send(self, value):
934 return value
935 def throw(self, typ, val=None, tb=None):
936 super().throw(typ, val, tb)
937
938 def gen():
939 yield 1
940
941 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
942 for x in samples:
943 self.assertIsInstance(x, Iterator)
944 self.assertIsInstance(x, Generator)
945 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
946 self.validate_abstract_methods(Generator, 'send', 'throw')
947
948 # mixin tests
949 mgen = MinimalGen()
950 self.assertIs(mgen, iter(mgen))
951 self.assertIs(mgen.send(None), next(mgen))
952 self.assertEqual(2, mgen.send(2))
953 self.assertIsNone(mgen.close())
954 self.assertRaises(ValueError, mgen.throw, ValueError)
955 self.assertRaisesRegex(ValueError, "^huhu$",
956 mgen.throw, ValueError, ValueError("huhu"))
957 self.assertRaises(StopIteration, mgen.throw, StopIteration())
958
959 class FailOnClose(Generator):
960 def send(self, value): return value
961 def throw(self, *args): raise ValueError
962
963 self.assertRaises(ValueError, FailOnClose().close)
964
965 class IgnoreGeneratorExit(Generator):
966 def send(self, value): return value
967 def throw(self, *args): pass
968
969 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
970
Yury Selivanov22214ab2016-11-16 18:25:04 -0500971 def test_AsyncGenerator(self):
972 class NonAGen1:
973 def __aiter__(self): return self
974 def __anext__(self): return None
975 def aclose(self): pass
976 def athrow(self, typ, val=None, tb=None): pass
977
978 class NonAGen2:
979 def __aiter__(self): return self
980 def __anext__(self): return None
981 def aclose(self): pass
982 def asend(self, value): return value
983
984 class NonAGen3:
985 def aclose(self): pass
986 def asend(self, value): return value
987 def athrow(self, typ, val=None, tb=None): pass
988
989 non_samples = [
990 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
991 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
992 for x in non_samples:
993 self.assertNotIsInstance(x, AsyncGenerator)
994 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
995
996 class Gen:
997 def __aiter__(self): return self
998 async def __anext__(self): return None
999 async def aclose(self): pass
1000 async def asend(self, value): return value
1001 async def athrow(self, typ, val=None, tb=None): pass
1002
1003 class MinimalAGen(AsyncGenerator):
1004 async def asend(self, value):
1005 return value
1006 async def athrow(self, typ, val=None, tb=None):
1007 await super().athrow(typ, val, tb)
1008
1009 async def gen():
1010 yield 1
1011
1012 samples = [gen(), Gen(), MinimalAGen()]
1013 for x in samples:
1014 self.assertIsInstance(x, AsyncIterator)
1015 self.assertIsInstance(x, AsyncGenerator)
1016 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1017 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1018
1019 def run_async(coro):
1020 result = None
1021 while True:
1022 try:
1023 coro.send(None)
1024 except StopIteration as ex:
1025 result = ex.args[0] if ex.args else None
1026 break
1027 return result
1028
1029 # mixin tests
1030 mgen = MinimalAGen()
1031 self.assertIs(mgen, mgen.__aiter__())
1032 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1033 self.assertEqual(2, run_async(mgen.asend(2)))
1034 self.assertIsNone(run_async(mgen.aclose()))
1035 with self.assertRaises(ValueError):
1036 run_async(mgen.athrow(ValueError))
1037
1038 class FailOnClose(AsyncGenerator):
1039 async def asend(self, value): return value
1040 async def athrow(self, *args): raise ValueError
1041
1042 with self.assertRaises(ValueError):
1043 run_async(FailOnClose().aclose())
1044
1045 class IgnoreGeneratorExit(AsyncGenerator):
1046 async def asend(self, value): return value
1047 async def athrow(self, *args): pass
1048
1049 with self.assertRaises(RuntimeError):
1050 run_async(IgnoreGeneratorExit().aclose())
1051
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001052 def test_Sized(self):
1053 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001054 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001055 (x for x in []),
1056 ]
1057 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001058 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001059 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001060 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001061 tuple(), list(), set(), frozenset(), dict(),
1062 dict().keys(), dict().items(), dict().values(),
1063 ]
1064 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001065 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001066 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001067 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001068 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001069
1070 def test_Container(self):
1071 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001072 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001073 (x for x in []),
1074 ]
1075 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001076 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001077 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001078 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001079 tuple(), list(), set(), frozenset(), dict(),
1080 dict().keys(), dict().items(),
1081 ]
1082 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001083 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001084 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001085 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001086 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001087
1088 def test_Callable(self):
1089 non_samples = [None, 42, 3.14, 1j,
1090 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001091 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001092 (x for x in []),
1093 ]
1094 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001095 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001096 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001097 samples = [lambda: None,
1098 type, int, object,
1099 len,
1100 list.append, [].append,
1101 ]
1102 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001103 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001104 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001105 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001106 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001107
1108 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001109 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001110 class C(B):
1111 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001112 self.assertTrue(issubclass(C, B))
1113 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001114
1115 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001116 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001117 class C:
1118 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001119 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001120 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001121 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001122
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001123class WithSet(MutableSet):
1124
1125 def __init__(self, it=()):
1126 self.data = set(it)
1127
1128 def __len__(self):
1129 return len(self.data)
1130
1131 def __iter__(self):
1132 return iter(self.data)
1133
1134 def __contains__(self, item):
1135 return item in self.data
1136
1137 def add(self, item):
1138 self.data.add(item)
1139
1140 def discard(self, item):
1141 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001142
Raymond Hettingerae650182009-01-28 23:33:59 +00001143class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001144
1145 # XXX For now, we only test some virtual inheritance properties.
1146 # We should also test the proper behavior of the collection ABCs
1147 # as real base classes or mix-in classes.
1148
1149 def test_Set(self):
1150 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001151 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001152 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001153 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001154 class MySet(Set):
1155 def __contains__(self, x):
1156 return False
1157 def __len__(self):
1158 return 0
1159 def __iter__(self):
1160 return iter([])
1161 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001162
Benjamin Peterson41181742008-07-02 20:22:54 +00001163 def test_hash_Set(self):
1164 class OneTwoThreeSet(Set):
1165 def __init__(self):
1166 self.contents = [1, 2, 3]
1167 def __contains__(self, x):
1168 return x in self.contents
1169 def __len__(self):
1170 return len(self.contents)
1171 def __iter__(self):
1172 return iter(self.contents)
1173 def __hash__(self):
1174 return self._hash()
1175 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001176 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001177
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001178 def test_isdisjoint_Set(self):
1179 class MySet(Set):
1180 def __init__(self, itr):
1181 self.contents = itr
1182 def __contains__(self, x):
1183 return x in self.contents
1184 def __iter__(self):
1185 return iter(self.contents)
1186 def __len__(self):
1187 return len([x for x in self.contents])
1188 s1 = MySet((1, 2, 3))
1189 s2 = MySet((4, 5, 6))
1190 s3 = MySet((1, 5, 6))
1191 self.assertTrue(s1.isdisjoint(s2))
1192 self.assertFalse(s1.isdisjoint(s3))
1193
1194 def test_equality_Set(self):
1195 class MySet(Set):
1196 def __init__(self, itr):
1197 self.contents = itr
1198 def __contains__(self, x):
1199 return x in self.contents
1200 def __iter__(self):
1201 return iter(self.contents)
1202 def __len__(self):
1203 return len([x for x in self.contents])
1204 s1 = MySet((1,))
1205 s2 = MySet((1, 2))
1206 s3 = MySet((3, 4))
1207 s4 = MySet((3, 4))
1208 self.assertTrue(s2 > s1)
1209 self.assertTrue(s1 < s2)
1210 self.assertFalse(s2 <= s1)
1211 self.assertFalse(s2 <= s3)
1212 self.assertFalse(s1 >= s2)
1213 self.assertEqual(s3, s4)
1214 self.assertNotEqual(s2, s3)
1215
1216 def test_arithmetic_Set(self):
1217 class MySet(Set):
1218 def __init__(self, itr):
1219 self.contents = itr
1220 def __contains__(self, x):
1221 return x in self.contents
1222 def __iter__(self):
1223 return iter(self.contents)
1224 def __len__(self):
1225 return len([x for x in self.contents])
1226 s1 = MySet((1, 2, 3))
1227 s2 = MySet((3, 4, 5))
1228 s3 = s1 & s2
1229 self.assertEqual(s3, MySet((3,)))
1230
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001231 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001232 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001233 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001234 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001235 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001236 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1237 'add', 'discard')
1238
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001239 def test_issue_5647(self):
1240 # MutableSet.__iand__ mutated the set during iteration
1241 s = WithSet('abcd')
1242 s &= WithSet('cdef') # This used to fail
1243 self.assertEqual(set(s), set('cd'))
1244
Raymond Hettingerae650182009-01-28 23:33:59 +00001245 def test_issue_4920(self):
1246 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001247 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001248 __slots__=['__s']
1249 def __init__(self,items=None):
1250 if items is None:
1251 items=[]
1252 self.__s=set(items)
1253 def __contains__(self,v):
1254 return v in self.__s
1255 def __iter__(self):
1256 return iter(self.__s)
1257 def __len__(self):
1258 return len(self.__s)
1259 def add(self,v):
1260 result=v not in self.__s
1261 self.__s.add(v)
1262 return result
1263 def discard(self,v):
1264 result=v in self.__s
1265 self.__s.discard(v)
1266 return result
1267 def __repr__(self):
1268 return "MySet(%s)" % repr(list(self))
1269 s = MySet([5,43,2,1])
1270 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001271
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001272 def test_issue8750(self):
1273 empty = WithSet()
1274 full = WithSet(range(10))
1275 s = WithSet(full)
1276 s -= s
1277 self.assertEqual(s, empty)
1278 s = WithSet(full)
1279 s ^= s
1280 self.assertEqual(s, empty)
1281 s = WithSet(full)
1282 s &= s
1283 self.assertEqual(s, full)
1284 s |= s
1285 self.assertEqual(s, full)
1286
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001287 def test_issue16373(self):
1288 # Recursion error comparing comparable and noncomparable
1289 # Set instances
1290 class MyComparableSet(Set):
1291 def __contains__(self, x):
1292 return False
1293 def __len__(self):
1294 return 0
1295 def __iter__(self):
1296 return iter([])
1297 class MyNonComparableSet(Set):
1298 def __contains__(self, x):
1299 return False
1300 def __len__(self):
1301 return 0
1302 def __iter__(self):
1303 return iter([])
1304 def __le__(self, x):
1305 return NotImplemented
1306 def __lt__(self, x):
1307 return NotImplemented
1308
1309 cs = MyComparableSet()
1310 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001311 self.assertFalse(ncs < cs)
1312 self.assertTrue(ncs <= cs)
1313 self.assertFalse(ncs > cs)
1314 self.assertTrue(ncs >= cs)
1315
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001316 def test_issue26915(self):
1317 # Container membership test should check identity first
1318 class CustomEqualObject:
1319 def __eq__(self, other):
1320 return False
Xiang Zhangd5d32492017-03-08 11:04:24 +08001321 class CustomSequence(Sequence):
1322 def __init__(self, seq):
1323 self._seq = seq
1324 def __getitem__(self, index):
1325 return self._seq[index]
1326 def __len__(self):
1327 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001328
1329 nan = float('nan')
1330 obj = CustomEqualObject()
Xiang Zhangd5d32492017-03-08 11:04:24 +08001331 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001332 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001333 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001334 ItemsView({1: nan, 2: obj}),
1335 ValuesView({1: nan, 2: obj})
1336 ]
1337 for container in containers:
1338 for elem in container:
1339 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001340 self.assertEqual(seq.index(nan), 0)
1341 self.assertEqual(seq.index(obj), 1)
1342 self.assertEqual(seq.count(nan), 2)
1343 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001344
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001345 def assertSameSet(self, s1, s2):
1346 # coerce both to a real set then check equality
1347 self.assertSetEqual(set(s1), set(s2))
1348
1349 def test_Set_interoperability_with_real_sets(self):
1350 # Issue: 8743
1351 class ListSet(Set):
1352 def __init__(self, elements=()):
1353 self.data = []
1354 for elem in elements:
1355 if elem not in self.data:
1356 self.data.append(elem)
1357 def __contains__(self, elem):
1358 return elem in self.data
1359 def __iter__(self):
1360 return iter(self.data)
1361 def __len__(self):
1362 return len(self.data)
1363 def __repr__(self):
1364 return 'Set({!r})'.format(self.data)
1365
1366 r1 = set('abc')
1367 r2 = set('bcd')
1368 r3 = set('abcde')
1369 f1 = ListSet('abc')
1370 f2 = ListSet('bcd')
1371 f3 = ListSet('abcde')
1372 l1 = list('abccba')
1373 l2 = list('bcddcb')
1374 l3 = list('abcdeedcba')
1375
1376 target = r1 & r2
1377 self.assertSameSet(f1 & f2, target)
1378 self.assertSameSet(f1 & r2, target)
1379 self.assertSameSet(r2 & f1, target)
1380 self.assertSameSet(f1 & l2, target)
1381
1382 target = r1 | r2
1383 self.assertSameSet(f1 | f2, target)
1384 self.assertSameSet(f1 | r2, target)
1385 self.assertSameSet(r2 | f1, target)
1386 self.assertSameSet(f1 | l2, target)
1387
1388 fwd_target = r1 - r2
1389 rev_target = r2 - r1
1390 self.assertSameSet(f1 - f2, fwd_target)
1391 self.assertSameSet(f2 - f1, rev_target)
1392 self.assertSameSet(f1 - r2, fwd_target)
1393 self.assertSameSet(f2 - r1, rev_target)
1394 self.assertSameSet(r1 - f2, fwd_target)
1395 self.assertSameSet(r2 - f1, rev_target)
1396 self.assertSameSet(f1 - l2, fwd_target)
1397 self.assertSameSet(f2 - l1, rev_target)
1398
1399 target = r1 ^ r2
1400 self.assertSameSet(f1 ^ f2, target)
1401 self.assertSameSet(f1 ^ r2, target)
1402 self.assertSameSet(r2 ^ f1, target)
1403 self.assertSameSet(f1 ^ l2, target)
1404
1405 # Don't change the following to use assertLess or other
1406 # "more specific" unittest assertions. The current
1407 # assertTrue/assertFalse style makes the pattern of test
1408 # case combinations clear and allows us to know for sure
1409 # the exact operator being invoked.
1410
1411 # proper subset
1412 self.assertTrue(f1 < f3)
1413 self.assertFalse(f1 < f1)
1414 self.assertFalse(f1 < f2)
1415 self.assertTrue(r1 < f3)
1416 self.assertFalse(r1 < f1)
1417 self.assertFalse(r1 < f2)
1418 self.assertTrue(r1 < r3)
1419 self.assertFalse(r1 < r1)
1420 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001421 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001422 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001423 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001424 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001425 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001426 f1 < l2
1427
1428 # any subset
1429 self.assertTrue(f1 <= f3)
1430 self.assertTrue(f1 <= f1)
1431 self.assertFalse(f1 <= f2)
1432 self.assertTrue(r1 <= f3)
1433 self.assertTrue(r1 <= f1)
1434 self.assertFalse(r1 <= f2)
1435 self.assertTrue(r1 <= r3)
1436 self.assertTrue(r1 <= r1)
1437 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001438 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001439 f1 <= l3
1440 with self.assertRaises(TypeError):
1441 f1 <= l1
1442 with self.assertRaises(TypeError):
1443 f1 <= l2
1444
1445 # proper superset
1446 self.assertTrue(f3 > f1)
1447 self.assertFalse(f1 > f1)
1448 self.assertFalse(f2 > f1)
1449 self.assertTrue(r3 > r1)
1450 self.assertFalse(f1 > r1)
1451 self.assertFalse(f2 > r1)
1452 self.assertTrue(r3 > r1)
1453 self.assertFalse(r1 > r1)
1454 self.assertFalse(r2 > r1)
1455 with self.assertRaises(TypeError):
1456 f1 > l3
1457 with self.assertRaises(TypeError):
1458 f1 > l1
1459 with self.assertRaises(TypeError):
1460 f1 > l2
1461
1462 # any superset
1463 self.assertTrue(f3 >= f1)
1464 self.assertTrue(f1 >= f1)
1465 self.assertFalse(f2 >= f1)
1466 self.assertTrue(r3 >= r1)
1467 self.assertTrue(f1 >= r1)
1468 self.assertFalse(f2 >= r1)
1469 self.assertTrue(r3 >= r1)
1470 self.assertTrue(r1 >= r1)
1471 self.assertFalse(r2 >= r1)
1472 with self.assertRaises(TypeError):
1473 f1 >= l3
1474 with self.assertRaises(TypeError):
1475 f1 >=l1
1476 with self.assertRaises(TypeError):
1477 f1 >= l2
1478
1479 # equality
1480 self.assertTrue(f1 == f1)
1481 self.assertTrue(r1 == f1)
1482 self.assertTrue(f1 == r1)
1483 self.assertFalse(f1 == f3)
1484 self.assertFalse(r1 == f3)
1485 self.assertFalse(f1 == r3)
1486 self.assertFalse(f1 == l3)
1487 self.assertFalse(f1 == l1)
1488 self.assertFalse(f1 == l2)
1489
1490 # inequality
1491 self.assertFalse(f1 != f1)
1492 self.assertFalse(r1 != f1)
1493 self.assertFalse(f1 != r1)
1494 self.assertTrue(f1 != f3)
1495 self.assertTrue(r1 != f3)
1496 self.assertTrue(f1 != r3)
1497 self.assertTrue(f1 != l3)
1498 self.assertTrue(f1 != l1)
1499 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001500
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001501 def test_Mapping(self):
1502 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001503 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001504 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001505 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1506 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001507 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001508 def __len__(self):
1509 return 0
1510 def __getitem__(self, i):
1511 raise IndexError
1512 def __iter__(self):
1513 return iter(())
1514 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001515 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001516
1517 def test_MutableMapping(self):
1518 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001519 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001520 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001521 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1522 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001523
Raymond Hettinger9117c752010-08-22 07:44:24 +00001524 def test_MutableMapping_subclass(self):
1525 # Test issue 9214
1526 mymap = UserDict()
1527 mymap['red'] = 5
1528 self.assertIsInstance(mymap.keys(), Set)
1529 self.assertIsInstance(mymap.keys(), KeysView)
1530 self.assertIsInstance(mymap.items(), Set)
1531 self.assertIsInstance(mymap.items(), ItemsView)
1532
1533 mymap = UserDict()
1534 mymap['red'] = 5
1535 z = mymap.keys() | {'orange'}
1536 self.assertIsInstance(z, set)
1537 list(z)
1538 mymap['blue'] = 7 # Shouldn't affect 'z'
1539 self.assertEqual(sorted(z), ['orange', 'red'])
1540
1541 mymap = UserDict()
1542 mymap['red'] = 5
1543 z = mymap.items() | {('orange', 3)}
1544 self.assertIsInstance(z, set)
1545 list(z)
1546 mymap['blue'] = 7 # Shouldn't affect 'z'
1547 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1548
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001549 def test_Sequence(self):
1550 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001551 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001552 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001553 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001554 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001555 self.assertIsInstance(memoryview(b""), Sequence)
1556 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001557 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001558 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1559 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001560
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001561 def test_Sequence_mixins(self):
1562 class SequenceSubclass(Sequence):
1563 def __init__(self, seq=()):
1564 self.seq = seq
1565
1566 def __getitem__(self, index):
1567 return self.seq[index]
1568
1569 def __len__(self):
1570 return len(self.seq)
1571
1572 # Compare Sequence.index() behavior to (list|str).index() behavior
1573 def assert_index_same(seq1, seq2, index_args):
1574 try:
1575 expected = seq1.index(*index_args)
1576 except ValueError:
1577 with self.assertRaises(ValueError):
1578 seq2.index(*index_args)
1579 else:
1580 actual = seq2.index(*index_args)
1581 self.assertEqual(
1582 actual, expected, '%r.index%s' % (seq1, index_args))
1583
1584 for ty in list, str:
1585 nativeseq = ty('abracadabra')
1586 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1587 seqseq = SequenceSubclass(nativeseq)
1588 for letter in set(nativeseq) | {'z'}:
1589 assert_index_same(nativeseq, seqseq, (letter,))
1590 for start in range(-3, len(nativeseq) + 3):
1591 assert_index_same(nativeseq, seqseq, (letter, start))
1592 for stop in range(-3, len(nativeseq) + 3):
1593 assert_index_same(
1594 nativeseq, seqseq, (letter, start, stop))
1595
Guido van Rossumd05eb002007-11-21 22:26:24 +00001596 def test_ByteString(self):
1597 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001598 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001599 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001600 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001601 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001602 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001603 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001604 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001605
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001606 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001607 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001608 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001609 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001610 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001611 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001612 self.assertTrue(issubclass(sample, MutableSequence))
1613 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001614 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1615 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001616
Eli Bendersky0716a572011-03-04 10:38:14 +00001617 def test_MutableSequence_mixins(self):
1618 # Test the mixins of MutableSequence by creating a miminal concrete
1619 # class inherited from it.
1620 class MutableSequenceSubclass(MutableSequence):
1621 def __init__(self):
1622 self.lst = []
1623
1624 def __setitem__(self, index, value):
1625 self.lst[index] = value
1626
1627 def __getitem__(self, index):
1628 return self.lst[index]
1629
1630 def __len__(self):
1631 return len(self.lst)
1632
1633 def __delitem__(self, index):
1634 del self.lst[index]
1635
1636 def insert(self, index, value):
1637 self.lst.insert(index, value)
1638
1639 mss = MutableSequenceSubclass()
1640 mss.append(0)
1641 mss.extend((1, 2, 3, 4))
1642 self.assertEqual(len(mss), 5)
1643 self.assertEqual(mss[3], 3)
1644 mss.reverse()
1645 self.assertEqual(mss[3], 1)
1646 mss.pop()
1647 self.assertEqual(len(mss), 4)
1648 mss.remove(3)
1649 self.assertEqual(len(mss), 3)
1650 mss += (10, 20, 30)
1651 self.assertEqual(len(mss), 6)
1652 self.assertEqual(mss[-1], 30)
1653 mss.clear()
1654 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001655
1656################################################################################
1657### Counter
1658################################################################################
1659
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001660class CounterSubclassWithSetItem(Counter):
1661 # Test a counter subclass that overrides __setitem__
1662 def __init__(self, *args, **kwds):
1663 self.called = False
1664 Counter.__init__(self, *args, **kwds)
1665 def __setitem__(self, key, value):
1666 self.called = True
1667 Counter.__setitem__(self, key, value)
1668
1669class CounterSubclassWithGet(Counter):
1670 # Test a counter subclass that overrides get()
1671 def __init__(self, *args, **kwds):
1672 self.called = False
1673 Counter.__init__(self, *args, **kwds)
1674 def get(self, key, default):
1675 self.called = True
1676 return Counter.get(self, key, default)
1677
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001678class TestCounter(unittest.TestCase):
1679
1680 def test_basics(self):
1681 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001682 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1683 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001684 self.assertIsInstance(c, dict)
1685 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001686 self.assertTrue(issubclass(Counter, dict))
1687 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001688 self.assertEqual(len(c), 3)
1689 self.assertEqual(sum(c.values()), 6)
1690 self.assertEqual(sorted(c.values()), [1, 2, 3])
1691 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1692 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1693 self.assertEqual(sorted(c.items()),
1694 [('a', 3), ('b', 2), ('c', 1)])
1695 self.assertEqual(c['b'], 2)
1696 self.assertEqual(c['z'], 0)
1697 self.assertEqual(c.__contains__('c'), True)
1698 self.assertEqual(c.__contains__('z'), False)
1699 self.assertEqual(c.get('b', 10), 2)
1700 self.assertEqual(c.get('z', 10), 10)
1701 self.assertEqual(c, dict(a=3, b=2, c=1))
1702 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1703 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1704 for i in range(5):
1705 self.assertEqual(c.most_common(i),
1706 [('a', 3), ('b', 2), ('c', 1)][:i])
1707 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1708 c['a'] += 1 # increment an existing value
1709 c['b'] -= 2 # sub existing value to zero
1710 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001711 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001712 c['d'] -= 2 # sub from a missing value
1713 c['e'] = -5 # directly assign a missing value
1714 c['f'] += 4 # add to a missing value
1715 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1716 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1717 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001718 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001719 for i in range(3):
1720 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001721 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001722 c.clear()
1723 self.assertEqual(c, {})
1724 self.assertEqual(repr(c), 'Counter()')
1725 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1726 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001727 c.update(dict(a=5, b=3))
1728 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001729 c.update(Counter('a' * 50 + 'b' * 30))
1730 c.update() # test case with no args
1731 c.__init__('a' * 500 + 'b' * 300)
1732 c.__init__('cdc')
1733 c.__init__()
1734 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1735 self.assertEqual(c.setdefault('d', 5), 1)
1736 self.assertEqual(c['d'], 1)
1737 self.assertEqual(c.setdefault('e', 5), 5)
1738 self.assertEqual(c['e'], 5)
1739
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001740 def test_init(self):
1741 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1742 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1743 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1744 self.assertRaises(TypeError, Counter, 42)
1745 self.assertRaises(TypeError, Counter, (), ())
1746 self.assertRaises(TypeError, Counter.__init__)
1747
1748 def test_update(self):
1749 c = Counter()
1750 c.update(self=42)
1751 self.assertEqual(list(c.items()), [('self', 42)])
1752 c = Counter()
1753 c.update(iterable=42)
1754 self.assertEqual(list(c.items()), [('iterable', 42)])
1755 c = Counter()
1756 c.update(iterable=None)
1757 self.assertEqual(list(c.items()), [('iterable', None)])
1758 self.assertRaises(TypeError, Counter().update, 42)
1759 self.assertRaises(TypeError, Counter().update, {}, {})
1760 self.assertRaises(TypeError, Counter.update)
1761
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001762 def test_copying(self):
1763 # Check that counters are copyable, deepcopyable, picklable, and
1764 #have a repr/eval round-trip
1765 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001766 def check(dup):
1767 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1768 self.assertIsNot(dup, words, msg)
1769 self.assertEqual(dup, words)
1770 check(words.copy())
1771 check(copy.copy(words))
1772 check(copy.deepcopy(words))
1773 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1774 with self.subTest(proto=proto):
1775 check(pickle.loads(pickle.dumps(words, proto)))
1776 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001777 update_test = Counter()
1778 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001779 check(update_test)
1780 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001781
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001782 def test_copy_subclass(self):
1783 class MyCounter(Counter):
1784 pass
1785 c = MyCounter('slartibartfast')
1786 d = c.copy()
1787 self.assertEqual(d, c)
1788 self.assertEqual(len(d), len(c))
1789 self.assertEqual(type(d), type(c))
1790
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001791 def test_conversions(self):
1792 # Convert to: set, list, dict
1793 s = 'she sells sea shells by the sea shore'
1794 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1795 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1796 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1797 self.assertEqual(set(Counter(s)), set(s))
1798
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001799 def test_invariant_for_the_in_operator(self):
1800 c = Counter(a=10, b=-2, c=0)
1801 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001802 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001803 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001804
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001805 def test_multiset_operations(self):
1806 # Verify that adding a zero counter will strip zeros and negatives
1807 c = Counter(a=10, b=-2, c=0) + Counter()
1808 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001809
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001810 elements = 'abcd'
1811 for i in range(1000):
1812 # test random pairs of multisets
1813 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001814 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001815 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001816 q.update(h=1, i=-1, j=0)
1817 for counterop, numberop in [
1818 (Counter.__add__, lambda x, y: max(0, x+y)),
1819 (Counter.__sub__, lambda x, y: max(0, x-y)),
1820 (Counter.__or__, lambda x, y: max(0,x,y)),
1821 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001822 ]:
1823 result = counterop(p, q)
1824 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001825 self.assertEqual(numberop(p[x], q[x]), result[x],
1826 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001827 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001828 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001829
1830 elements = 'abcdef'
1831 for i in range(100):
1832 # verify that random multisets with no repeats are exactly like sets
1833 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1834 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1835 for counterop, setop in [
1836 (Counter.__sub__, set.__sub__),
1837 (Counter.__or__, set.__or__),
1838 (Counter.__and__, set.__and__),
1839 ]:
1840 counter_result = counterop(p, q)
1841 set_result = setop(set(p.elements()), set(q.elements()))
1842 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001843
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001844 def test_inplace_operations(self):
1845 elements = 'abcd'
1846 for i in range(1000):
1847 # test random pairs of multisets
1848 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1849 p.update(e=1, f=-1, g=0)
1850 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1851 q.update(h=1, i=-1, j=0)
1852 for inplace_op, regular_op in [
1853 (Counter.__iadd__, Counter.__add__),
1854 (Counter.__isub__, Counter.__sub__),
1855 (Counter.__ior__, Counter.__or__),
1856 (Counter.__iand__, Counter.__and__),
1857 ]:
1858 c = p.copy()
1859 c_id = id(c)
1860 regular_result = regular_op(c, q)
1861 inplace_result = inplace_op(c, q)
1862 self.assertEqual(inplace_result, regular_result)
1863 self.assertEqual(id(inplace_result), c_id)
1864
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001865 def test_subtract(self):
1866 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1867 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1868 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1869 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1870 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1871 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1872 c = Counter('aaabbcd')
1873 c.subtract('aaaabbcce')
1874 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001875
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001876 c = Counter()
1877 c.subtract(self=42)
1878 self.assertEqual(list(c.items()), [('self', -42)])
1879 c = Counter()
1880 c.subtract(iterable=42)
1881 self.assertEqual(list(c.items()), [('iterable', -42)])
1882 self.assertRaises(TypeError, Counter().subtract, 42)
1883 self.assertRaises(TypeError, Counter().subtract, {}, {})
1884 self.assertRaises(TypeError, Counter.subtract)
1885
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001886 def test_unary(self):
1887 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1888 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1889 self.assertEqual(dict(-c), dict(a=5))
1890
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001891 def test_repr_nonsortable(self):
1892 c = Counter(a=2, b=None)
1893 r = repr(c)
1894 self.assertIn("'a': 2", r)
1895 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001896
Raymond Hettinger426e0522011-01-03 02:12:02 +00001897 def test_helper_function(self):
1898 # two paths, one for real dicts and one for other mappings
1899 elems = list('abracadabra')
1900
1901 d = dict()
1902 _count_elements(d, elems)
1903 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1904
1905 m = OrderedDict()
1906 _count_elements(m, elems)
1907 self.assertEqual(m,
1908 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1909
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001910 # test fidelity to the pure python version
1911 c = CounterSubclassWithSetItem('abracadabra')
1912 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001913 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001914 c = CounterSubclassWithGet('abracadabra')
1915 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001916 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001917
Raymond Hettinger499e1932011-02-23 07:56:53 +00001918
1919################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001920### Run tests
1921################################################################################
1922
Guido van Rossumd8faa362007-04-27 19:54:29 +00001923def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001924 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001925 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001926 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06001927 TestUserObjects,
1928 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001929 support.run_unittest(*test_classes)
1930 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001931
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001932
Guido van Rossumd8faa362007-04-27 19:54:29 +00001933if __name__ == "__main__":
1934 test_main(verbose=True)