blob: 87c697863ed94ef2812b8bcab8b982972ac431a2 [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 Hettinger2d32f632009-03-02 21:24:57 +00006import inspect
Raymond Hettinger499b2ee2009-05-27 01:53:46 +00007import keyword
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +02008import operator
9import pickle
10from random import choice, randrange
Raymond Hettinger499b2ee2009-05-27 01:53:46 +000011import re
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020012import string
R. David Murray378c0cf2010-02-24 01:46:21 +000013import sys
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020014from test import support
Yury Selivanov75445082015-05-11 22:57:16 -040015import types
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +020016import unittest
17
18from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger573b44c2015-05-22 16:56:32 -070019from collections import UserDict, UserString, UserList
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000020from collections import ChainMap
Raymond Hettinger32ea1652015-03-21 01:37:37 -070021from collections import deque
Yury Selivanov22214ab2016-11-16 18:25:04 -050022from collections.abc import Awaitable, Coroutine
23from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator
Guido van Rossum16ca06b2016-04-04 10:59:29 -070024from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
Guido van Rossumf0666942016-08-23 10:47:07 -070025from collections.abc import Sized, Container, Callable, Collection
Raymond Hettinger57d1a882011-02-23 00:46:28 +000026from collections.abc import Set, MutableSet
Raymond Hettinger584e8ae2016-05-05 11:14:06 +030027from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
Raymond Hettinger57d1a882011-02-23 00:46:28 +000028from collections.abc import Sequence, MutableSequence
29from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000030
Raymond Hettinger499e1932011-02-23 07:56:53 +000031
Raymond Hettinger573b44c2015-05-22 16:56:32 -070032class TestUserObjects(unittest.TestCase):
33 def _superset_test(self, a, b):
34 self.assertGreaterEqual(
35 set(dir(a)),
36 set(dir(b)),
37 '{a} should have all the methods of {b}'.format(
38 a=a.__name__,
39 b=b.__name__,
40 ),
41 )
42 def test_str_protocol(self):
43 self._superset_test(UserString, str)
44
45 def test_list_protocol(self):
46 self._superset_test(UserList, list)
47
48 def test_dict_protocol(self):
49 self._superset_test(UserDict, dict)
50
51
Raymond Hettinger499e1932011-02-23 07:56:53 +000052################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000053### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000054################################################################################
55
56class TestChainMap(unittest.TestCase):
57
58 def test_basics(self):
59 c = ChainMap()
60 c['a'] = 1
61 c['b'] = 2
62 d = c.new_child()
63 d['b'] = 20
64 d['c'] = 30
65 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
66 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
67 self.assertEqual(len(d), 3) # check len
68 for key in 'abc': # check contains
69 self.assertIn(key, d)
70 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
71 self.assertEqual(d.get(k, 100), v)
72
73 del d['b'] # unmask a value
74 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
75 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
76 self.assertEqual(len(d), 3) # check len
77 for key in 'abc': # check contains
78 self.assertIn(key, d)
79 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
80 self.assertEqual(d.get(k, 100), v)
81 self.assertIn(repr(d), [ # check repr
82 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
83 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
84 ])
85
86 for e in d.copy(), copy.copy(d): # check shallow copies
87 self.assertEqual(d, e)
88 self.assertEqual(d.maps, e.maps)
89 self.assertIsNot(d, e)
90 self.assertIsNot(d.maps[0], e.maps[0])
91 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
92 self.assertIs(m1, m2)
93
Serhiy Storchakabad12572014-12-15 14:03:42 +020094 # check deep copies
95 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
96 e = pickle.loads(pickle.dumps(d, proto))
97 self.assertEqual(d, e)
98 self.assertEqual(d.maps, e.maps)
99 self.assertIsNot(d, e)
100 for m1, m2 in zip(d.maps, e.maps):
101 self.assertIsNot(m1, m2, e)
102 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +0000103 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200104 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000105 self.assertEqual(d, e)
106 self.assertEqual(d.maps, e.maps)
107 self.assertIsNot(d, e)
108 for m1, m2 in zip(d.maps, e.maps):
109 self.assertIsNot(m1, m2, e)
110
Raymond Hettingerd0321312011-02-26 06:53:58 +0000111 f = d.new_child()
112 f['b'] = 5
113 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
114 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
115 self.assertEqual(f['b'], 5) # find first in chain
116 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000117
Martin Pantereb995702016-07-28 01:11:04 +0000118 def test_constructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000119 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000120 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
121
Raymond Hettingerd0321312011-02-26 06:53:58 +0000122 def test_bool(self):
123 self.assertFalse(ChainMap())
124 self.assertFalse(ChainMap({}, {}))
125 self.assertTrue(ChainMap({1:2}, {}))
126 self.assertTrue(ChainMap({}, {1:2}))
127
Raymond Hettinger499e1932011-02-23 07:56:53 +0000128 def test_missing(self):
129 class DefaultChainMap(ChainMap):
130 def __missing__(self, key):
131 return 999
132 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
133 for k, v in dict(a=1, b=2, c=30, d=999).items():
134 self.assertEqual(d[k], v) # check __getitem__ w/missing
135 for k, v in dict(a=1, b=2, c=30, d=77).items():
136 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
137 for k, v in dict(a=True, b=True, c=True, d=False).items():
138 self.assertEqual(k in d, v) # check __contains__ w/missing
139 self.assertEqual(d.pop('a', 1001), 1, d)
140 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
141 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
142 with self.assertRaises(KeyError):
143 d.popitem()
144
145 def test_dict_coercion(self):
146 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
147 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
148 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
149
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000150 def test_new_child(self):
151 'Tests for changes for issue #16613.'
152 c = ChainMap()
153 c['a'] = 1
154 c['b'] = 2
155 m = {'b':20, 'c': 30}
156 d = c.new_child(m)
157 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
158 self.assertIs(m, d.maps[0])
159
160 # Use a different map than a dict
161 class lowerdict(dict):
162 def __getitem__(self, key):
163 if isinstance(key, str):
164 key = key.lower()
165 return dict.__getitem__(self, key)
166 def __contains__(self, key):
167 if isinstance(key, str):
168 key = key.lower()
169 return dict.__contains__(self, key)
170
171 c = ChainMap()
172 c['a'] = 1
173 c['b'] = 2
174 m = lowerdict(b=20, c=30)
175 d = c.new_child(m)
176 self.assertIs(m, d.maps[0])
177 for key in 'abc': # check contains
178 self.assertIn(key, d)
179 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
180 self.assertEqual(d.get(k, 100), v)
181
Raymond Hettinger499e1932011-02-23 07:56:53 +0000182
183################################################################################
184### Named Tuples
185################################################################################
186
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000187TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000188
189class TestNamedTuple(unittest.TestCase):
190
191 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000192 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000193 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000194 self.assertEqual(Point.__slots__, ())
195 self.assertEqual(Point.__module__, __name__)
196 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000197 self.assertEqual(Point._fields, ('x', 'y'))
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700198 self.assertIn('class Point(tuple)', Point._source)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000199
200 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
201 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
202 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
203
204 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
205 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
206 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000207 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000208 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
209
210 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000211 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000212
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000213 nt = namedtuple('nt', 'the quick brown fox') # 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 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000216 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000217
Christian Heimesfaf2f632008-01-06 16:59:19 +0000218 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
219 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
220
R. David Murray378c0cf2010-02-24 01:46:21 +0000221 @unittest.skipIf(sys.flags.optimize >= 2,
222 "Docstrings are omitted with -O2 and above")
223 def test_factory_doc_attr(self):
224 Point = namedtuple('Point', 'x y')
225 self.assertEqual(Point.__doc__, 'Point(x, y)')
226
Raymond Hettingereac503a2015-05-13 01:09:59 -0700227 @unittest.skipIf(sys.flags.optimize >= 2,
228 "Docstrings are omitted with -O2 and above")
229 def test_doc_writable(self):
230 Point = namedtuple('Point', 'x y')
231 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
232 Point.x.__doc__ = 'docstring for Point.x'
233 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
234
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000235 def test_name_fixer(self):
236 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000237 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
238 [('abc', 'class'), ('abc', '_1')], # field has keyword
239 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
240 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
241 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
242 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000243 ]:
244 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
245
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700246 def test_module_parameter(self):
247 NT = namedtuple('NT', ['x', 'y'], module=collections)
248 self.assertEqual(NT.__module__, collections)
249
Guido van Rossumd8faa362007-04-27 19:54:29 +0000250 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000251 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000252 p = Point(11, 22)
253 self.assertEqual(p, Point(x=11, y=22))
254 self.assertEqual(p, Point(11, y=22))
255 self.assertEqual(p, Point(y=22, x=11))
256 self.assertEqual(p, Point(*(11, 22)))
257 self.assertEqual(p, Point(**dict(x=11, y=22)))
258 self.assertRaises(TypeError, Point, 1) # too few args
259 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
260 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
261 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
262 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000263 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000264 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000265 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
266 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700267 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000268
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000269 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000270 p._replace(x=1, error=2)
271 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000272 pass
273 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000274 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000275
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000276 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000277 Point = namedtuple('Point', 'x, y')
278 p = Point(x=11, y=22)
279 self.assertEqual(repr(p), 'Point(x=11, y=22)')
280
281 # verify that fieldspec can be a non-string sequence
282 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000283 p = Point(x=11, y=22)
284 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000285
286 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000287 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000288 p = Point(11, 22)
289
Ezio Melottie9615932010-01-24 19:26:24 +0000290 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000291 self.assertEqual(p, (11, 22)) # matches a real tuple
292 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
293 self.assertEqual(list(p), [11, 22]) # coercable to a list
294 self.assertEqual(max(p), 22) # iterable
295 self.assertEqual(max(*p), 22) # star-able
296 x, y = p
297 self.assertEqual(p, (x, y)) # unpacks like a tuple
298 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
299 self.assertRaises(IndexError, p.__getitem__, 3)
300
301 self.assertEqual(p.x, x)
302 self.assertEqual(p.y, y)
303 self.assertRaises(AttributeError, eval, 'p.z', locals())
304
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000305 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000306 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000307 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000308 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000309 self.assertEqual(repr(Zero()), 'Zero()')
310 self.assertEqual(Zero()._asdict(), {})
311 self.assertEqual(Zero()._fields, ())
312
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000313 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000314 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000315 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000316 self.assertEqual(Dot(1).d, 1)
317 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
318 self.assertEqual(Dot(1)._asdict(), {'d':1})
319 self.assertEqual(Dot(1)._replace(d=999), (999,))
320 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000321
Serhiy Storchaka5bb8b912016-12-16 19:19:02 +0200322 n = 5000
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200323 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000324 for j in range(10)]) for i in range(n)))
325 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000326 Big = namedtuple('Big', names)
327 b = Big(*range(n))
328 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000329 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000330 for pos, name in enumerate(names):
331 self.assertEqual(getattr(b, name), pos)
332 repr(b) # make sure repr() doesn't blow-up
333 d = b._asdict()
334 d_expected = dict(zip(names, range(n)))
335 self.assertEqual(d, d_expected)
336 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
337 b2_expected = list(range(n))
338 b2_expected[1] = 999
339 b2_expected[-5] = 42
340 self.assertEqual(b2, tuple(b2_expected))
341 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000342
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000343 def test_pickle(self):
344 p = TestNT(x=10, y=20, z=30)
345 for module in (pickle,):
346 loads = getattr(module, 'loads')
347 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500348 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000349 q = loads(dumps(p, protocol))
350 self.assertEqual(p, q)
351 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700352 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000353
354 def test_copy(self):
355 p = TestNT(x=10, y=20, z=30)
356 for copier in copy.copy, copy.deepcopy:
357 q = copier(p)
358 self.assertEqual(p, q)
359 self.assertEqual(p._fields, q._fields)
360
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000361 def test_name_conflicts(self):
362 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
363 # failed when used as field names. Test to make sure these now work.
364 T = namedtuple('T', 'itemgetter property self cls tuple')
365 t = T(1, 2, 3, 4, 5)
366 self.assertEqual(t, (1,2,3,4,5))
367 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
368 self.assertEqual(newt, (10,20,30,40,50))
369
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000370 # Broader test of all interesting names in a template
371 with support.captured_stdout() as template:
372 T = namedtuple('T', 'x', verbose=True)
373 words = set(re.findall('[A-Za-z]+', template.getvalue()))
374 words -= set(keyword.kwlist)
375 T = namedtuple('T', words)
376 # test __new__
377 values = tuple(range(len(words)))
378 t = T(*values)
379 self.assertEqual(t, values)
380 t = T(**dict(zip(T._fields, values)))
381 self.assertEqual(t, values)
382 # test _make
383 t = T._make(values)
384 self.assertEqual(t, values)
385 # exercise __repr__
386 repr(t)
387 # test _asdict
388 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
389 # test _replace
390 t = T._make(values)
391 newvalues = tuple(v*10 for v in values)
392 newt = t._replace(**dict(zip(T._fields, newvalues)))
393 self.assertEqual(newt, newvalues)
394 # test _fields
395 self.assertEqual(T._fields, tuple(words))
396 # test __getnewargs__
397 self.assertEqual(t.__getnewargs__(), values)
398
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000399 def test_repr(self):
400 with support.captured_stdout() as template:
401 A = namedtuple('A', 'x', verbose=True)
402 self.assertEqual(repr(A(1)), 'A(x=1)')
403 # repr should show the name of the subclass
404 class B(A):
405 pass
406 self.assertEqual(repr(B(1)), 'B(x=1)')
407
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700408 def test_source(self):
409 # verify that _source can be run through exec()
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700410 tmp = namedtuple('NTColor', 'red green blue')
411 globals().pop('NTColor', None) # remove artifacts from other tests
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700412 exec(tmp._source, globals())
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700413 self.assertIn('NTColor', globals())
414 c = NTColor(10, 20, 30)
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700415 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700416 self.assertEqual(NTColor._fields, ('red', 'green', 'blue'))
417 globals().pop('NTColor', None) # clean-up after this test
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700418
Raymond Hettinger6538b432016-08-16 10:55:43 -0700419 def test_keyword_only_arguments(self):
420 # See issue 25628
421 with support.captured_stdout() as template:
422 NT = namedtuple('NT', ['x', 'y'], verbose=True)
423 self.assertIn('class NT', NT._source)
424 with self.assertRaises(TypeError):
425 NT = namedtuple('NT', ['x', 'y'], True)
426
427 NT = namedtuple('NT', ['abc', 'def'], rename=True)
428 self.assertEqual(NT._fields, ('abc', '_1'))
429 with self.assertRaises(TypeError):
430 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000431
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700432 def test_namedtuple_subclass_issue_24931(self):
433 class Point(namedtuple('_Point', ['x', 'y'])):
434 pass
435
436 a = Point(3, 4)
437 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
438
439 a.w = 5
440 self.assertEqual(a.__dict__, {'w': 5})
441
442
Raymond Hettinger499e1932011-02-23 07:56:53 +0000443################################################################################
444### Abstract Base Classes
445################################################################################
446
Raymond Hettingerae650182009-01-28 23:33:59 +0000447class ABCTestCase(unittest.TestCase):
448
449 def validate_abstract_methods(self, abc, *names):
450 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
451
452 # everything should work will all required methods are present
453 C = type('C', (abc,), methodstubs)
454 C()
455
456 # instantiation should fail if a required method is missing
457 for name in names:
458 stubs = methodstubs.copy()
459 del stubs[name]
460 C = type('C', (abc,), stubs)
461 self.assertRaises(TypeError, C, name)
462
Florent Xiclunace153f62010-03-08 15:34:35 +0000463 def validate_isinstance(self, abc, name):
464 stub = lambda s, *args: 0
465
466 C = type('C', (object,), {'__hash__': None})
467 setattr(C, name, stub)
468 self.assertIsInstance(C(), abc)
469 self.assertTrue(issubclass(C, abc))
470
471 C = type('C', (object,), {'__hash__': None})
472 self.assertNotIsInstance(C(), abc)
473 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000474
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000475 def validate_comparison(self, instance):
476 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
477 operators = {}
478 for op in ops:
479 name = '__' + op + '__'
480 operators[name] = getattr(operator, name)
481
482 class Other:
483 def __init__(self):
484 self.right_side = False
485 def __eq__(self, other):
486 self.right_side = True
487 return True
488 __lt__ = __eq__
489 __gt__ = __eq__
490 __le__ = __eq__
491 __ge__ = __eq__
492 __ne__ = __eq__
493 __ror__ = __eq__
494 __rand__ = __eq__
495 __rxor__ = __eq__
496 __rsub__ = __eq__
497
498 for name, op in operators.items():
499 if not hasattr(instance, name):
500 continue
501 other = Other()
502 op(instance, other)
503 self.assertTrue(other.right_side,'Right side not called for %s.%s'
504 % (type(instance), name))
505
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700506def _test_gen():
507 yield
508
Raymond Hettingerae650182009-01-28 23:33:59 +0000509class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000510
Yury Selivanov75445082015-05-11 22:57:16 -0400511 def test_Awaitable(self):
512 def gen():
513 yield
514
515 @types.coroutine
516 def coro():
517 yield
518
519 async def new_coro():
520 pass
521
522 class Bar:
523 def __await__(self):
524 yield
525
526 class MinimalCoro(Coroutine):
527 def send(self, value):
528 return value
529 def throw(self, typ, val=None, tb=None):
530 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400531 def __await__(self):
532 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400533
534 non_samples = [None, int(), gen(), object()]
535 for x in non_samples:
536 self.assertNotIsInstance(x, Awaitable)
537 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
538
539 samples = [Bar(), MinimalCoro()]
540 for x in samples:
541 self.assertIsInstance(x, Awaitable)
542 self.assertTrue(issubclass(type(x), Awaitable))
543
544 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400545 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
546 # flag don't have '__await__' method, hence can't be instances
547 # of Awaitable. Use inspect.isawaitable to detect them.
548 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400549
550 c = new_coro()
551 self.assertIsInstance(c, Awaitable)
552 c.close() # awoid RuntimeWarning that coro() was not awaited
553
Yury Selivanov56fc6142015-05-29 09:01:29 -0400554 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400555 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400556 self.assertTrue(isinstance(CoroLike(), Awaitable))
557 self.assertTrue(issubclass(CoroLike, Awaitable))
558 CoroLike = None
559 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400560
Yury Selivanov75445082015-05-11 22:57:16 -0400561 def test_Coroutine(self):
562 def gen():
563 yield
564
565 @types.coroutine
566 def coro():
567 yield
568
569 async def new_coro():
570 pass
571
572 class Bar:
573 def __await__(self):
574 yield
575
576 class MinimalCoro(Coroutine):
577 def send(self, value):
578 return value
579 def throw(self, typ, val=None, tb=None):
580 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400581 def __await__(self):
582 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400583
584 non_samples = [None, int(), gen(), object(), Bar()]
585 for x in non_samples:
586 self.assertNotIsInstance(x, Coroutine)
587 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
588
589 samples = [MinimalCoro()]
590 for x in samples:
591 self.assertIsInstance(x, Awaitable)
592 self.assertTrue(issubclass(type(x), Awaitable))
593
594 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400595 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
596 # flag don't have '__await__' method, hence can't be instances
597 # of Coroutine. Use inspect.isawaitable to detect them.
598 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400599
600 c = new_coro()
601 self.assertIsInstance(c, Coroutine)
602 c.close() # awoid RuntimeWarning that coro() was not awaited
603
Yury Selivanov56fc6142015-05-29 09:01:29 -0400604 class CoroLike:
605 def send(self, value):
606 pass
607 def throw(self, typ, val=None, tb=None):
608 pass
609 def close(self):
610 pass
611 def __await__(self):
612 pass
613 self.assertTrue(isinstance(CoroLike(), Coroutine))
614 self.assertTrue(issubclass(CoroLike, Coroutine))
615
616 class CoroLike:
617 def send(self, value):
618 pass
619 def close(self):
620 pass
621 def __await__(self):
622 pass
623 self.assertFalse(isinstance(CoroLike(), Coroutine))
624 self.assertFalse(issubclass(CoroLike, Coroutine))
625
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000626 def test_Hashable(self):
627 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000628 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000629 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000630 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000631 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000632 # Check some hashables
633 samples = [None,
634 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000635 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000636 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000637 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000638 ]
639 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000640 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000641 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000642 self.assertRaises(TypeError, Hashable)
643 # Check direct subclassing
644 class H(Hashable):
645 def __hash__(self):
646 return super().__hash__()
647 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000648 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000649 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000650 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000651
Yury Selivanove0104ae2015-05-14 12:19:16 -0400652 def test_AsyncIterable(self):
653 class AI:
654 async def __aiter__(self):
655 return self
656 self.assertTrue(isinstance(AI(), AsyncIterable))
657 self.assertTrue(issubclass(AI, AsyncIterable))
658 # Check some non-iterables
659 non_samples = [None, object, []]
660 for x in non_samples:
661 self.assertNotIsInstance(x, AsyncIterable)
662 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
663 self.validate_abstract_methods(AsyncIterable, '__aiter__')
664 self.validate_isinstance(AsyncIterable, '__aiter__')
665
666 def test_AsyncIterator(self):
667 class AI:
668 async def __aiter__(self):
669 return self
670 async def __anext__(self):
671 raise StopAsyncIteration
672 self.assertTrue(isinstance(AI(), AsyncIterator))
673 self.assertTrue(issubclass(AI, AsyncIterator))
674 non_samples = [None, object, []]
675 # Check some non-iterables
676 for x in non_samples:
677 self.assertNotIsInstance(x, AsyncIterator)
678 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
679 # Similarly to regular iterators (see issue 10565)
680 class AnextOnly:
681 async def __anext__(self):
682 raise StopAsyncIteration
683 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
684 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
685
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000686 def test_Iterable(self):
687 # Check some non-iterables
688 non_samples = [None, 42, 3.14, 1j]
689 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000690 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000691 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000692 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000693 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000694 tuple(), list(), set(), frozenset(), dict(),
695 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700696 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000697 (x for x in []),
698 ]
699 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000700 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000701 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000702 # Check direct subclassing
703 class I(Iterable):
704 def __iter__(self):
705 return super().__iter__()
706 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000707 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000708 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000709 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700710 # Check None blocking
711 class It:
712 def __iter__(self): return iter([])
713 class ItBlocked(It):
714 __iter__ = None
715 self.assertTrue(issubclass(It, Iterable))
716 self.assertTrue(isinstance(It(), Iterable))
717 self.assertFalse(issubclass(ItBlocked, Iterable))
718 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000719
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700720 def test_Reversible(self):
721 # Check some non-reversibles
722 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()]
723 for x in non_samples:
724 self.assertNotIsInstance(x, Reversible)
725 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700726 # Check some non-reversible iterables
727 non_reversibles = [dict().keys(), dict().items(), dict().values(),
728 Counter(), Counter().keys(), Counter().items(),
729 Counter().values(), _test_gen(),
730 (x for x in []), iter([]), reversed([])]
731 for x in non_reversibles:
732 self.assertNotIsInstance(x, Reversible)
733 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
734 # Check some reversible iterables
735 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
736 OrderedDict().keys(), OrderedDict().items(),
737 OrderedDict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700738 for x in samples:
739 self.assertIsInstance(x, Reversible)
740 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
741 # Check also Mapping, MutableMapping, and Sequence
742 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
743 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
744 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
745 # Check direct subclassing
746 class R(Reversible):
747 def __iter__(self):
748 return iter(list())
749 def __reversed__(self):
750 return iter(list())
751 self.assertEqual(list(reversed(R())), [])
752 self.assertFalse(issubclass(float, R))
753 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700754 # Check reversible non-iterable (which is not Reversible)
755 class RevNoIter:
756 def __reversed__(self): return reversed([])
757 class RevPlusIter(RevNoIter):
758 def __iter__(self): return iter([])
759 self.assertFalse(issubclass(RevNoIter, Reversible))
760 self.assertFalse(isinstance(RevNoIter(), Reversible))
761 self.assertTrue(issubclass(RevPlusIter, Reversible))
762 self.assertTrue(isinstance(RevPlusIter(), Reversible))
763 # Check None blocking
764 class Rev:
765 def __iter__(self): return iter([])
766 def __reversed__(self): return reversed([])
767 class RevItBlocked(Rev):
768 __iter__ = None
769 class RevRevBlocked(Rev):
770 __reversed__ = None
771 self.assertTrue(issubclass(Rev, Reversible))
772 self.assertTrue(isinstance(Rev(), Reversible))
773 self.assertFalse(issubclass(RevItBlocked, Reversible))
774 self.assertFalse(isinstance(RevItBlocked(), Reversible))
775 self.assertFalse(issubclass(RevRevBlocked, Reversible))
776 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700777
Guido van Rossumf0666942016-08-23 10:47:07 -0700778 def test_Collection(self):
779 # Check some non-collections
780 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
781 for x in non_collections:
782 self.assertNotIsInstance(x, Collection)
783 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
784 # Check some non-collection iterables
785 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
786 (x for x in []), dict().values()]
787 for x in non_col_iterables:
788 self.assertNotIsInstance(x, Collection)
789 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
790 # Check some collections
791 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
792 list(), dict().keys(), dict().items()]
793 for x in samples:
794 self.assertIsInstance(x, Collection)
795 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
796 # Check also Mapping, MutableMapping, etc.
797 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
798 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
799 self.assertTrue(issubclass(MutableMapping, Collection),
800 repr(MutableMapping))
801 self.assertTrue(issubclass(Set, Collection), repr(Set))
802 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
803 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
804 # Check direct subclassing
805 class Col(Collection):
806 def __iter__(self):
807 return iter(list())
808 def __len__(self):
809 return 0
810 def __contains__(self, item):
811 return False
812 class DerCol(Col): pass
813 self.assertEqual(list(iter(Col())), [])
814 self.assertFalse(issubclass(list, Col))
815 self.assertFalse(issubclass(set, Col))
816 self.assertFalse(issubclass(float, Col))
817 self.assertEqual(list(iter(DerCol())), [])
818 self.assertFalse(issubclass(list, DerCol))
819 self.assertFalse(issubclass(set, DerCol))
820 self.assertFalse(issubclass(float, DerCol))
821 self.validate_abstract_methods(Collection, '__len__', '__iter__',
822 '__contains__')
823 # Check sized container non-iterable (which is not Collection) etc.
824 class ColNoIter:
825 def __len__(self): return 0
826 def __contains__(self, item): return False
827 class ColNoSize:
828 def __iter__(self): return iter([])
829 def __contains__(self, item): return False
830 class ColNoCont:
831 def __iter__(self): return iter([])
832 def __len__(self): return 0
833 self.assertFalse(issubclass(ColNoIter, Collection))
834 self.assertFalse(isinstance(ColNoIter(), Collection))
835 self.assertFalse(issubclass(ColNoSize, Collection))
836 self.assertFalse(isinstance(ColNoSize(), Collection))
837 self.assertFalse(issubclass(ColNoCont, Collection))
838 self.assertFalse(isinstance(ColNoCont(), Collection))
839 # Check None blocking
840 class SizeBlock:
841 def __iter__(self): return iter([])
842 def __contains__(self): return False
843 __len__ = None
844 class IterBlock:
845 def __len__(self): return 0
846 def __contains__(self): return True
847 __iter__ = None
848 self.assertFalse(issubclass(SizeBlock, Collection))
849 self.assertFalse(isinstance(SizeBlock(), Collection))
850 self.assertFalse(issubclass(IterBlock, Collection))
851 self.assertFalse(isinstance(IterBlock(), Collection))
852 # Check None blocking in subclass
853 class ColImpl:
854 def __iter__(self):
855 return iter(list())
856 def __len__(self):
857 return 0
858 def __contains__(self, item):
859 return False
860 class NonCol(ColImpl):
861 __contains__ = None
862 self.assertFalse(issubclass(NonCol, Collection))
863 self.assertFalse(isinstance(NonCol(), Collection))
864
865
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000866 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000867 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000868 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000869 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000870 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000871 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000872 iter(tuple()), iter(list()), iter(dict()),
873 iter(set()), iter(frozenset()),
874 iter(dict().keys()), iter(dict().items()),
875 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700876 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000877 (x for x in []),
878 ]
879 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000880 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000881 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000882 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
883
884 # Issue 10565
885 class NextOnly:
886 def __next__(self):
887 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800888 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000889 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000890
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400891 def test_Generator(self):
892 class NonGen1:
893 def __iter__(self): return self
894 def __next__(self): return None
895 def close(self): pass
896 def throw(self, typ, val=None, tb=None): pass
897
898 class NonGen2:
899 def __iter__(self): return self
900 def __next__(self): return None
901 def close(self): pass
902 def send(self, value): return value
903
904 class NonGen3:
905 def close(self): pass
906 def send(self, value): return value
907 def throw(self, typ, val=None, tb=None): pass
908
909 non_samples = [
910 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
911 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
912 for x in non_samples:
913 self.assertNotIsInstance(x, Generator)
914 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
915
916 class Gen:
917 def __iter__(self): return self
918 def __next__(self): return None
919 def close(self): pass
920 def send(self, value): return value
921 def throw(self, typ, val=None, tb=None): pass
922
923 class MinimalGen(Generator):
924 def send(self, value):
925 return value
926 def throw(self, typ, val=None, tb=None):
927 super().throw(typ, val, tb)
928
929 def gen():
930 yield 1
931
932 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
933 for x in samples:
934 self.assertIsInstance(x, Iterator)
935 self.assertIsInstance(x, Generator)
936 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
937 self.validate_abstract_methods(Generator, 'send', 'throw')
938
939 # mixin tests
940 mgen = MinimalGen()
941 self.assertIs(mgen, iter(mgen))
942 self.assertIs(mgen.send(None), next(mgen))
943 self.assertEqual(2, mgen.send(2))
944 self.assertIsNone(mgen.close())
945 self.assertRaises(ValueError, mgen.throw, ValueError)
946 self.assertRaisesRegex(ValueError, "^huhu$",
947 mgen.throw, ValueError, ValueError("huhu"))
948 self.assertRaises(StopIteration, mgen.throw, StopIteration())
949
950 class FailOnClose(Generator):
951 def send(self, value): return value
952 def throw(self, *args): raise ValueError
953
954 self.assertRaises(ValueError, FailOnClose().close)
955
956 class IgnoreGeneratorExit(Generator):
957 def send(self, value): return value
958 def throw(self, *args): pass
959
960 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
961
Yury Selivanov22214ab2016-11-16 18:25:04 -0500962 def test_AsyncGenerator(self):
963 class NonAGen1:
964 def __aiter__(self): return self
965 def __anext__(self): return None
966 def aclose(self): pass
967 def athrow(self, typ, val=None, tb=None): pass
968
969 class NonAGen2:
970 def __aiter__(self): return self
971 def __anext__(self): return None
972 def aclose(self): pass
973 def asend(self, value): return value
974
975 class NonAGen3:
976 def aclose(self): pass
977 def asend(self, value): return value
978 def athrow(self, typ, val=None, tb=None): pass
979
980 non_samples = [
981 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
982 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
983 for x in non_samples:
984 self.assertNotIsInstance(x, AsyncGenerator)
985 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
986
987 class Gen:
988 def __aiter__(self): return self
989 async def __anext__(self): return None
990 async def aclose(self): pass
991 async def asend(self, value): return value
992 async def athrow(self, typ, val=None, tb=None): pass
993
994 class MinimalAGen(AsyncGenerator):
995 async def asend(self, value):
996 return value
997 async def athrow(self, typ, val=None, tb=None):
998 await super().athrow(typ, val, tb)
999
1000 async def gen():
1001 yield 1
1002
1003 samples = [gen(), Gen(), MinimalAGen()]
1004 for x in samples:
1005 self.assertIsInstance(x, AsyncIterator)
1006 self.assertIsInstance(x, AsyncGenerator)
1007 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1008 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1009
1010 def run_async(coro):
1011 result = None
1012 while True:
1013 try:
1014 coro.send(None)
1015 except StopIteration as ex:
1016 result = ex.args[0] if ex.args else None
1017 break
1018 return result
1019
1020 # mixin tests
1021 mgen = MinimalAGen()
1022 self.assertIs(mgen, mgen.__aiter__())
1023 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1024 self.assertEqual(2, run_async(mgen.asend(2)))
1025 self.assertIsNone(run_async(mgen.aclose()))
1026 with self.assertRaises(ValueError):
1027 run_async(mgen.athrow(ValueError))
1028
1029 class FailOnClose(AsyncGenerator):
1030 async def asend(self, value): return value
1031 async def athrow(self, *args): raise ValueError
1032
1033 with self.assertRaises(ValueError):
1034 run_async(FailOnClose().aclose())
1035
1036 class IgnoreGeneratorExit(AsyncGenerator):
1037 async def asend(self, value): return value
1038 async def athrow(self, *args): pass
1039
1040 with self.assertRaises(RuntimeError):
1041 run_async(IgnoreGeneratorExit().aclose())
1042
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001043 def test_Sized(self):
1044 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001045 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001046 (x for x in []),
1047 ]
1048 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001049 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001050 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001051 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001052 tuple(), list(), set(), frozenset(), dict(),
1053 dict().keys(), dict().items(), dict().values(),
1054 ]
1055 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001056 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001057 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001058 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001059 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001060
1061 def test_Container(self):
1062 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001063 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001064 (x for x in []),
1065 ]
1066 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001067 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001068 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001069 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001070 tuple(), list(), set(), frozenset(), dict(),
1071 dict().keys(), dict().items(),
1072 ]
1073 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001074 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001075 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001076 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001077 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001078
1079 def test_Callable(self):
1080 non_samples = [None, 42, 3.14, 1j,
1081 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001082 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001083 (x for x in []),
1084 ]
1085 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001086 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001087 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001088 samples = [lambda: None,
1089 type, int, object,
1090 len,
1091 list.append, [].append,
1092 ]
1093 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001094 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001095 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001096 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001097 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001098
1099 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001100 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001101 class C(B):
1102 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001103 self.assertTrue(issubclass(C, B))
1104 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001105
1106 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001107 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001108 class C:
1109 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001110 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001111 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001112 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001113
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001114class WithSet(MutableSet):
1115
1116 def __init__(self, it=()):
1117 self.data = set(it)
1118
1119 def __len__(self):
1120 return len(self.data)
1121
1122 def __iter__(self):
1123 return iter(self.data)
1124
1125 def __contains__(self, item):
1126 return item in self.data
1127
1128 def add(self, item):
1129 self.data.add(item)
1130
1131 def discard(self, item):
1132 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001133
Raymond Hettingerae650182009-01-28 23:33:59 +00001134class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001135
1136 # XXX For now, we only test some virtual inheritance properties.
1137 # We should also test the proper behavior of the collection ABCs
1138 # as real base classes or mix-in classes.
1139
1140 def test_Set(self):
1141 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001142 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001143 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001144 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001145 class MySet(Set):
1146 def __contains__(self, x):
1147 return False
1148 def __len__(self):
1149 return 0
1150 def __iter__(self):
1151 return iter([])
1152 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001153
Benjamin Peterson41181742008-07-02 20:22:54 +00001154 def test_hash_Set(self):
1155 class OneTwoThreeSet(Set):
1156 def __init__(self):
1157 self.contents = [1, 2, 3]
1158 def __contains__(self, x):
1159 return x in self.contents
1160 def __len__(self):
1161 return len(self.contents)
1162 def __iter__(self):
1163 return iter(self.contents)
1164 def __hash__(self):
1165 return self._hash()
1166 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001167 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001168
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001169 def test_isdisjoint_Set(self):
1170 class MySet(Set):
1171 def __init__(self, itr):
1172 self.contents = itr
1173 def __contains__(self, x):
1174 return x in self.contents
1175 def __iter__(self):
1176 return iter(self.contents)
1177 def __len__(self):
1178 return len([x for x in self.contents])
1179 s1 = MySet((1, 2, 3))
1180 s2 = MySet((4, 5, 6))
1181 s3 = MySet((1, 5, 6))
1182 self.assertTrue(s1.isdisjoint(s2))
1183 self.assertFalse(s1.isdisjoint(s3))
1184
1185 def test_equality_Set(self):
1186 class MySet(Set):
1187 def __init__(self, itr):
1188 self.contents = itr
1189 def __contains__(self, x):
1190 return x in self.contents
1191 def __iter__(self):
1192 return iter(self.contents)
1193 def __len__(self):
1194 return len([x for x in self.contents])
1195 s1 = MySet((1,))
1196 s2 = MySet((1, 2))
1197 s3 = MySet((3, 4))
1198 s4 = MySet((3, 4))
1199 self.assertTrue(s2 > s1)
1200 self.assertTrue(s1 < s2)
1201 self.assertFalse(s2 <= s1)
1202 self.assertFalse(s2 <= s3)
1203 self.assertFalse(s1 >= s2)
1204 self.assertEqual(s3, s4)
1205 self.assertNotEqual(s2, s3)
1206
1207 def test_arithmetic_Set(self):
1208 class MySet(Set):
1209 def __init__(self, itr):
1210 self.contents = itr
1211 def __contains__(self, x):
1212 return x in self.contents
1213 def __iter__(self):
1214 return iter(self.contents)
1215 def __len__(self):
1216 return len([x for x in self.contents])
1217 s1 = MySet((1, 2, 3))
1218 s2 = MySet((3, 4, 5))
1219 s3 = s1 & s2
1220 self.assertEqual(s3, MySet((3,)))
1221
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001222 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001223 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001224 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001225 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001226 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001227 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1228 'add', 'discard')
1229
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001230 def test_issue_5647(self):
1231 # MutableSet.__iand__ mutated the set during iteration
1232 s = WithSet('abcd')
1233 s &= WithSet('cdef') # This used to fail
1234 self.assertEqual(set(s), set('cd'))
1235
Raymond Hettingerae650182009-01-28 23:33:59 +00001236 def test_issue_4920(self):
1237 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001238 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001239 __slots__=['__s']
1240 def __init__(self,items=None):
1241 if items is None:
1242 items=[]
1243 self.__s=set(items)
1244 def __contains__(self,v):
1245 return v in self.__s
1246 def __iter__(self):
1247 return iter(self.__s)
1248 def __len__(self):
1249 return len(self.__s)
1250 def add(self,v):
1251 result=v not in self.__s
1252 self.__s.add(v)
1253 return result
1254 def discard(self,v):
1255 result=v in self.__s
1256 self.__s.discard(v)
1257 return result
1258 def __repr__(self):
1259 return "MySet(%s)" % repr(list(self))
1260 s = MySet([5,43,2,1])
1261 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001262
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001263 def test_issue8750(self):
1264 empty = WithSet()
1265 full = WithSet(range(10))
1266 s = WithSet(full)
1267 s -= s
1268 self.assertEqual(s, empty)
1269 s = WithSet(full)
1270 s ^= s
1271 self.assertEqual(s, empty)
1272 s = WithSet(full)
1273 s &= s
1274 self.assertEqual(s, full)
1275 s |= s
1276 self.assertEqual(s, full)
1277
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001278 def test_issue16373(self):
1279 # Recursion error comparing comparable and noncomparable
1280 # Set instances
1281 class MyComparableSet(Set):
1282 def __contains__(self, x):
1283 return False
1284 def __len__(self):
1285 return 0
1286 def __iter__(self):
1287 return iter([])
1288 class MyNonComparableSet(Set):
1289 def __contains__(self, x):
1290 return False
1291 def __len__(self):
1292 return 0
1293 def __iter__(self):
1294 return iter([])
1295 def __le__(self, x):
1296 return NotImplemented
1297 def __lt__(self, x):
1298 return NotImplemented
1299
1300 cs = MyComparableSet()
1301 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001302 self.assertFalse(ncs < cs)
1303 self.assertTrue(ncs <= cs)
1304 self.assertFalse(ncs > cs)
1305 self.assertTrue(ncs >= cs)
1306
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001307 def test_issue26915(self):
1308 # Container membership test should check identity first
1309 class CustomEqualObject:
1310 def __eq__(self, other):
1311 return False
Xiang Zhangd5d32492017-03-08 11:04:24 +08001312 class CustomSequence(Sequence):
1313 def __init__(self, seq):
1314 self._seq = seq
1315 def __getitem__(self, index):
1316 return self._seq[index]
1317 def __len__(self):
1318 return len(self._seq)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001319
1320 nan = float('nan')
1321 obj = CustomEqualObject()
Xiang Zhangd5d32492017-03-08 11:04:24 +08001322 seq = CustomSequence([nan, obj, nan])
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001323 containers = [
Xiang Zhangd5d32492017-03-08 11:04:24 +08001324 seq,
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001325 ItemsView({1: nan, 2: obj}),
1326 ValuesView({1: nan, 2: obj})
1327 ]
1328 for container in containers:
1329 for elem in container:
1330 self.assertIn(elem, container)
Xiang Zhangd5d32492017-03-08 11:04:24 +08001331 self.assertEqual(seq.index(nan), 0)
1332 self.assertEqual(seq.index(obj), 1)
1333 self.assertEqual(seq.count(nan), 2)
1334 self.assertEqual(seq.count(obj), 1)
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001335
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001336 def assertSameSet(self, s1, s2):
1337 # coerce both to a real set then check equality
1338 self.assertSetEqual(set(s1), set(s2))
1339
1340 def test_Set_interoperability_with_real_sets(self):
1341 # Issue: 8743
1342 class ListSet(Set):
1343 def __init__(self, elements=()):
1344 self.data = []
1345 for elem in elements:
1346 if elem not in self.data:
1347 self.data.append(elem)
1348 def __contains__(self, elem):
1349 return elem in self.data
1350 def __iter__(self):
1351 return iter(self.data)
1352 def __len__(self):
1353 return len(self.data)
1354 def __repr__(self):
1355 return 'Set({!r})'.format(self.data)
1356
1357 r1 = set('abc')
1358 r2 = set('bcd')
1359 r3 = set('abcde')
1360 f1 = ListSet('abc')
1361 f2 = ListSet('bcd')
1362 f3 = ListSet('abcde')
1363 l1 = list('abccba')
1364 l2 = list('bcddcb')
1365 l3 = list('abcdeedcba')
1366
1367 target = r1 & r2
1368 self.assertSameSet(f1 & f2, target)
1369 self.assertSameSet(f1 & r2, target)
1370 self.assertSameSet(r2 & f1, target)
1371 self.assertSameSet(f1 & l2, target)
1372
1373 target = r1 | r2
1374 self.assertSameSet(f1 | f2, target)
1375 self.assertSameSet(f1 | r2, target)
1376 self.assertSameSet(r2 | f1, target)
1377 self.assertSameSet(f1 | l2, target)
1378
1379 fwd_target = r1 - r2
1380 rev_target = r2 - r1
1381 self.assertSameSet(f1 - f2, fwd_target)
1382 self.assertSameSet(f2 - f1, rev_target)
1383 self.assertSameSet(f1 - r2, fwd_target)
1384 self.assertSameSet(f2 - r1, rev_target)
1385 self.assertSameSet(r1 - f2, fwd_target)
1386 self.assertSameSet(r2 - f1, rev_target)
1387 self.assertSameSet(f1 - l2, fwd_target)
1388 self.assertSameSet(f2 - l1, rev_target)
1389
1390 target = r1 ^ r2
1391 self.assertSameSet(f1 ^ f2, target)
1392 self.assertSameSet(f1 ^ r2, target)
1393 self.assertSameSet(r2 ^ f1, target)
1394 self.assertSameSet(f1 ^ l2, target)
1395
1396 # Don't change the following to use assertLess or other
1397 # "more specific" unittest assertions. The current
1398 # assertTrue/assertFalse style makes the pattern of test
1399 # case combinations clear and allows us to know for sure
1400 # the exact operator being invoked.
1401
1402 # proper subset
1403 self.assertTrue(f1 < f3)
1404 self.assertFalse(f1 < f1)
1405 self.assertFalse(f1 < f2)
1406 self.assertTrue(r1 < f3)
1407 self.assertFalse(r1 < f1)
1408 self.assertFalse(r1 < f2)
1409 self.assertTrue(r1 < r3)
1410 self.assertFalse(r1 < r1)
1411 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001412 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001413 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001414 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001415 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001416 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001417 f1 < l2
1418
1419 # any subset
1420 self.assertTrue(f1 <= f3)
1421 self.assertTrue(f1 <= f1)
1422 self.assertFalse(f1 <= f2)
1423 self.assertTrue(r1 <= f3)
1424 self.assertTrue(r1 <= f1)
1425 self.assertFalse(r1 <= f2)
1426 self.assertTrue(r1 <= r3)
1427 self.assertTrue(r1 <= r1)
1428 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001429 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001430 f1 <= l3
1431 with self.assertRaises(TypeError):
1432 f1 <= l1
1433 with self.assertRaises(TypeError):
1434 f1 <= l2
1435
1436 # proper superset
1437 self.assertTrue(f3 > f1)
1438 self.assertFalse(f1 > f1)
1439 self.assertFalse(f2 > f1)
1440 self.assertTrue(r3 > r1)
1441 self.assertFalse(f1 > r1)
1442 self.assertFalse(f2 > r1)
1443 self.assertTrue(r3 > r1)
1444 self.assertFalse(r1 > r1)
1445 self.assertFalse(r2 > r1)
1446 with self.assertRaises(TypeError):
1447 f1 > l3
1448 with self.assertRaises(TypeError):
1449 f1 > l1
1450 with self.assertRaises(TypeError):
1451 f1 > l2
1452
1453 # any superset
1454 self.assertTrue(f3 >= f1)
1455 self.assertTrue(f1 >= f1)
1456 self.assertFalse(f2 >= f1)
1457 self.assertTrue(r3 >= r1)
1458 self.assertTrue(f1 >= r1)
1459 self.assertFalse(f2 >= r1)
1460 self.assertTrue(r3 >= r1)
1461 self.assertTrue(r1 >= r1)
1462 self.assertFalse(r2 >= r1)
1463 with self.assertRaises(TypeError):
1464 f1 >= l3
1465 with self.assertRaises(TypeError):
1466 f1 >=l1
1467 with self.assertRaises(TypeError):
1468 f1 >= l2
1469
1470 # equality
1471 self.assertTrue(f1 == f1)
1472 self.assertTrue(r1 == f1)
1473 self.assertTrue(f1 == r1)
1474 self.assertFalse(f1 == f3)
1475 self.assertFalse(r1 == f3)
1476 self.assertFalse(f1 == r3)
1477 self.assertFalse(f1 == l3)
1478 self.assertFalse(f1 == l1)
1479 self.assertFalse(f1 == l2)
1480
1481 # inequality
1482 self.assertFalse(f1 != f1)
1483 self.assertFalse(r1 != f1)
1484 self.assertFalse(f1 != r1)
1485 self.assertTrue(f1 != f3)
1486 self.assertTrue(r1 != f3)
1487 self.assertTrue(f1 != r3)
1488 self.assertTrue(f1 != l3)
1489 self.assertTrue(f1 != l1)
1490 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001491
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001492 def test_Mapping(self):
1493 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001494 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001495 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001496 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1497 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001498 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001499 def __len__(self):
1500 return 0
1501 def __getitem__(self, i):
1502 raise IndexError
1503 def __iter__(self):
1504 return iter(())
1505 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001506 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001507
1508 def test_MutableMapping(self):
1509 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001510 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001511 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001512 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1513 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001514
Raymond Hettinger9117c752010-08-22 07:44:24 +00001515 def test_MutableMapping_subclass(self):
1516 # Test issue 9214
1517 mymap = UserDict()
1518 mymap['red'] = 5
1519 self.assertIsInstance(mymap.keys(), Set)
1520 self.assertIsInstance(mymap.keys(), KeysView)
1521 self.assertIsInstance(mymap.items(), Set)
1522 self.assertIsInstance(mymap.items(), ItemsView)
1523
1524 mymap = UserDict()
1525 mymap['red'] = 5
1526 z = mymap.keys() | {'orange'}
1527 self.assertIsInstance(z, set)
1528 list(z)
1529 mymap['blue'] = 7 # Shouldn't affect 'z'
1530 self.assertEqual(sorted(z), ['orange', 'red'])
1531
1532 mymap = UserDict()
1533 mymap['red'] = 5
1534 z = mymap.items() | {('orange', 3)}
1535 self.assertIsInstance(z, set)
1536 list(z)
1537 mymap['blue'] = 7 # Shouldn't affect 'z'
1538 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1539
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001540 def test_Sequence(self):
1541 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001542 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001543 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001544 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001545 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001546 self.assertIsInstance(memoryview(b""), Sequence)
1547 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001548 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001549 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1550 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001551
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001552 def test_Sequence_mixins(self):
1553 class SequenceSubclass(Sequence):
1554 def __init__(self, seq=()):
1555 self.seq = seq
1556
1557 def __getitem__(self, index):
1558 return self.seq[index]
1559
1560 def __len__(self):
1561 return len(self.seq)
1562
1563 # Compare Sequence.index() behavior to (list|str).index() behavior
1564 def assert_index_same(seq1, seq2, index_args):
1565 try:
1566 expected = seq1.index(*index_args)
1567 except ValueError:
1568 with self.assertRaises(ValueError):
1569 seq2.index(*index_args)
1570 else:
1571 actual = seq2.index(*index_args)
1572 self.assertEqual(
1573 actual, expected, '%r.index%s' % (seq1, index_args))
1574
1575 for ty in list, str:
1576 nativeseq = ty('abracadabra')
1577 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1578 seqseq = SequenceSubclass(nativeseq)
1579 for letter in set(nativeseq) | {'z'}:
1580 assert_index_same(nativeseq, seqseq, (letter,))
1581 for start in range(-3, len(nativeseq) + 3):
1582 assert_index_same(nativeseq, seqseq, (letter, start))
1583 for stop in range(-3, len(nativeseq) + 3):
1584 assert_index_same(
1585 nativeseq, seqseq, (letter, start, stop))
1586
Guido van Rossumd05eb002007-11-21 22:26:24 +00001587 def test_ByteString(self):
1588 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001589 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001590 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001591 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001592 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001593 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001594 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001595 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001596
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001597 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001598 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001599 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001600 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001601 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001602 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001603 self.assertTrue(issubclass(sample, MutableSequence))
1604 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001605 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1606 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001607
Eli Bendersky0716a572011-03-04 10:38:14 +00001608 def test_MutableSequence_mixins(self):
1609 # Test the mixins of MutableSequence by creating a miminal concrete
1610 # class inherited from it.
1611 class MutableSequenceSubclass(MutableSequence):
1612 def __init__(self):
1613 self.lst = []
1614
1615 def __setitem__(self, index, value):
1616 self.lst[index] = value
1617
1618 def __getitem__(self, index):
1619 return self.lst[index]
1620
1621 def __len__(self):
1622 return len(self.lst)
1623
1624 def __delitem__(self, index):
1625 del self.lst[index]
1626
1627 def insert(self, index, value):
1628 self.lst.insert(index, value)
1629
1630 mss = MutableSequenceSubclass()
1631 mss.append(0)
1632 mss.extend((1, 2, 3, 4))
1633 self.assertEqual(len(mss), 5)
1634 self.assertEqual(mss[3], 3)
1635 mss.reverse()
1636 self.assertEqual(mss[3], 1)
1637 mss.pop()
1638 self.assertEqual(len(mss), 4)
1639 mss.remove(3)
1640 self.assertEqual(len(mss), 3)
1641 mss += (10, 20, 30)
1642 self.assertEqual(len(mss), 6)
1643 self.assertEqual(mss[-1], 30)
1644 mss.clear()
1645 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001646
1647################################################################################
1648### Counter
1649################################################################################
1650
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001651class CounterSubclassWithSetItem(Counter):
1652 # Test a counter subclass that overrides __setitem__
1653 def __init__(self, *args, **kwds):
1654 self.called = False
1655 Counter.__init__(self, *args, **kwds)
1656 def __setitem__(self, key, value):
1657 self.called = True
1658 Counter.__setitem__(self, key, value)
1659
1660class CounterSubclassWithGet(Counter):
1661 # Test a counter subclass that overrides get()
1662 def __init__(self, *args, **kwds):
1663 self.called = False
1664 Counter.__init__(self, *args, **kwds)
1665 def get(self, key, default):
1666 self.called = True
1667 return Counter.get(self, key, default)
1668
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001669class TestCounter(unittest.TestCase):
1670
1671 def test_basics(self):
1672 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001673 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1674 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001675 self.assertIsInstance(c, dict)
1676 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001677 self.assertTrue(issubclass(Counter, dict))
1678 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001679 self.assertEqual(len(c), 3)
1680 self.assertEqual(sum(c.values()), 6)
1681 self.assertEqual(sorted(c.values()), [1, 2, 3])
1682 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1683 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1684 self.assertEqual(sorted(c.items()),
1685 [('a', 3), ('b', 2), ('c', 1)])
1686 self.assertEqual(c['b'], 2)
1687 self.assertEqual(c['z'], 0)
1688 self.assertEqual(c.__contains__('c'), True)
1689 self.assertEqual(c.__contains__('z'), False)
1690 self.assertEqual(c.get('b', 10), 2)
1691 self.assertEqual(c.get('z', 10), 10)
1692 self.assertEqual(c, dict(a=3, b=2, c=1))
1693 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1694 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1695 for i in range(5):
1696 self.assertEqual(c.most_common(i),
1697 [('a', 3), ('b', 2), ('c', 1)][:i])
1698 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1699 c['a'] += 1 # increment an existing value
1700 c['b'] -= 2 # sub existing value to zero
1701 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001702 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001703 c['d'] -= 2 # sub from a missing value
1704 c['e'] = -5 # directly assign a missing value
1705 c['f'] += 4 # add to a missing value
1706 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1707 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1708 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001709 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001710 for i in range(3):
1711 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001712 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001713 c.clear()
1714 self.assertEqual(c, {})
1715 self.assertEqual(repr(c), 'Counter()')
1716 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1717 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001718 c.update(dict(a=5, b=3))
1719 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001720 c.update(Counter('a' * 50 + 'b' * 30))
1721 c.update() # test case with no args
1722 c.__init__('a' * 500 + 'b' * 300)
1723 c.__init__('cdc')
1724 c.__init__()
1725 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1726 self.assertEqual(c.setdefault('d', 5), 1)
1727 self.assertEqual(c['d'], 1)
1728 self.assertEqual(c.setdefault('e', 5), 5)
1729 self.assertEqual(c['e'], 5)
1730
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001731 def test_init(self):
1732 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1733 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1734 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1735 self.assertRaises(TypeError, Counter, 42)
1736 self.assertRaises(TypeError, Counter, (), ())
1737 self.assertRaises(TypeError, Counter.__init__)
1738
1739 def test_update(self):
1740 c = Counter()
1741 c.update(self=42)
1742 self.assertEqual(list(c.items()), [('self', 42)])
1743 c = Counter()
1744 c.update(iterable=42)
1745 self.assertEqual(list(c.items()), [('iterable', 42)])
1746 c = Counter()
1747 c.update(iterable=None)
1748 self.assertEqual(list(c.items()), [('iterable', None)])
1749 self.assertRaises(TypeError, Counter().update, 42)
1750 self.assertRaises(TypeError, Counter().update, {}, {})
1751 self.assertRaises(TypeError, Counter.update)
1752
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001753 def test_copying(self):
1754 # Check that counters are copyable, deepcopyable, picklable, and
1755 #have a repr/eval round-trip
1756 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001757 def check(dup):
1758 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1759 self.assertIsNot(dup, words, msg)
1760 self.assertEqual(dup, words)
1761 check(words.copy())
1762 check(copy.copy(words))
1763 check(copy.deepcopy(words))
1764 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1765 with self.subTest(proto=proto):
1766 check(pickle.loads(pickle.dumps(words, proto)))
1767 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001768 update_test = Counter()
1769 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001770 check(update_test)
1771 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001772
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001773 def test_copy_subclass(self):
1774 class MyCounter(Counter):
1775 pass
1776 c = MyCounter('slartibartfast')
1777 d = c.copy()
1778 self.assertEqual(d, c)
1779 self.assertEqual(len(d), len(c))
1780 self.assertEqual(type(d), type(c))
1781
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001782 def test_conversions(self):
1783 # Convert to: set, list, dict
1784 s = 'she sells sea shells by the sea shore'
1785 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1786 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1787 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1788 self.assertEqual(set(Counter(s)), set(s))
1789
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001790 def test_invariant_for_the_in_operator(self):
1791 c = Counter(a=10, b=-2, c=0)
1792 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001793 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001794 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001795
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001796 def test_multiset_operations(self):
1797 # Verify that adding a zero counter will strip zeros and negatives
1798 c = Counter(a=10, b=-2, c=0) + Counter()
1799 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001800
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001801 elements = 'abcd'
1802 for i in range(1000):
1803 # test random pairs of multisets
1804 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001805 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001806 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001807 q.update(h=1, i=-1, j=0)
1808 for counterop, numberop in [
1809 (Counter.__add__, lambda x, y: max(0, x+y)),
1810 (Counter.__sub__, lambda x, y: max(0, x-y)),
1811 (Counter.__or__, lambda x, y: max(0,x,y)),
1812 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001813 ]:
1814 result = counterop(p, q)
1815 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001816 self.assertEqual(numberop(p[x], q[x]), result[x],
1817 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001818 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001819 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001820
1821 elements = 'abcdef'
1822 for i in range(100):
1823 # verify that random multisets with no repeats are exactly like sets
1824 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1825 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1826 for counterop, setop in [
1827 (Counter.__sub__, set.__sub__),
1828 (Counter.__or__, set.__or__),
1829 (Counter.__and__, set.__and__),
1830 ]:
1831 counter_result = counterop(p, q)
1832 set_result = setop(set(p.elements()), set(q.elements()))
1833 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001834
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001835 def test_inplace_operations(self):
1836 elements = 'abcd'
1837 for i in range(1000):
1838 # test random pairs of multisets
1839 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1840 p.update(e=1, f=-1, g=0)
1841 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1842 q.update(h=1, i=-1, j=0)
1843 for inplace_op, regular_op in [
1844 (Counter.__iadd__, Counter.__add__),
1845 (Counter.__isub__, Counter.__sub__),
1846 (Counter.__ior__, Counter.__or__),
1847 (Counter.__iand__, Counter.__and__),
1848 ]:
1849 c = p.copy()
1850 c_id = id(c)
1851 regular_result = regular_op(c, q)
1852 inplace_result = inplace_op(c, q)
1853 self.assertEqual(inplace_result, regular_result)
1854 self.assertEqual(id(inplace_result), c_id)
1855
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001856 def test_subtract(self):
1857 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1858 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1859 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1860 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1861 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1862 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1863 c = Counter('aaabbcd')
1864 c.subtract('aaaabbcce')
1865 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001866
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001867 c = Counter()
1868 c.subtract(self=42)
1869 self.assertEqual(list(c.items()), [('self', -42)])
1870 c = Counter()
1871 c.subtract(iterable=42)
1872 self.assertEqual(list(c.items()), [('iterable', -42)])
1873 self.assertRaises(TypeError, Counter().subtract, 42)
1874 self.assertRaises(TypeError, Counter().subtract, {}, {})
1875 self.assertRaises(TypeError, Counter.subtract)
1876
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001877 def test_unary(self):
1878 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1879 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1880 self.assertEqual(dict(-c), dict(a=5))
1881
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001882 def test_repr_nonsortable(self):
1883 c = Counter(a=2, b=None)
1884 r = repr(c)
1885 self.assertIn("'a': 2", r)
1886 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001887
Raymond Hettinger426e0522011-01-03 02:12:02 +00001888 def test_helper_function(self):
1889 # two paths, one for real dicts and one for other mappings
1890 elems = list('abracadabra')
1891
1892 d = dict()
1893 _count_elements(d, elems)
1894 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1895
1896 m = OrderedDict()
1897 _count_elements(m, elems)
1898 self.assertEqual(m,
1899 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1900
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001901 # test fidelity to the pure python version
1902 c = CounterSubclassWithSetItem('abracadabra')
1903 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001904 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001905 c = CounterSubclassWithGet('abracadabra')
1906 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001907 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001908
Raymond Hettinger499e1932011-02-23 07:56:53 +00001909
1910################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001911### Run tests
1912################################################################################
1913
Guido van Rossumd8faa362007-04-27 19:54:29 +00001914def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001915 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001916 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001917 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06001918 TestUserObjects,
1919 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001920 support.run_unittest(*test_classes)
1921 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001922
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001923
Guido van Rossumd8faa362007-04-27 19:54:29 +00001924if __name__ == "__main__":
1925 test_main(verbose=True)