blob: 76c71392dd372af154fbba3acb9870be9f19fb8b [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
1312 class CustomSequence(list):
1313 def __contains__(self, value):
1314 return Sequence.__contains__(self, value)
1315
1316 nan = float('nan')
1317 obj = CustomEqualObject()
1318 containers = [
1319 CustomSequence([nan, obj]),
1320 ItemsView({1: nan, 2: obj}),
1321 ValuesView({1: nan, 2: obj})
1322 ]
1323 for container in containers:
1324 for elem in container:
1325 self.assertIn(elem, container)
1326
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001327 def assertSameSet(self, s1, s2):
1328 # coerce both to a real set then check equality
1329 self.assertSetEqual(set(s1), set(s2))
1330
1331 def test_Set_interoperability_with_real_sets(self):
1332 # Issue: 8743
1333 class ListSet(Set):
1334 def __init__(self, elements=()):
1335 self.data = []
1336 for elem in elements:
1337 if elem not in self.data:
1338 self.data.append(elem)
1339 def __contains__(self, elem):
1340 return elem in self.data
1341 def __iter__(self):
1342 return iter(self.data)
1343 def __len__(self):
1344 return len(self.data)
1345 def __repr__(self):
1346 return 'Set({!r})'.format(self.data)
1347
1348 r1 = set('abc')
1349 r2 = set('bcd')
1350 r3 = set('abcde')
1351 f1 = ListSet('abc')
1352 f2 = ListSet('bcd')
1353 f3 = ListSet('abcde')
1354 l1 = list('abccba')
1355 l2 = list('bcddcb')
1356 l3 = list('abcdeedcba')
1357
1358 target = r1 & r2
1359 self.assertSameSet(f1 & f2, target)
1360 self.assertSameSet(f1 & r2, target)
1361 self.assertSameSet(r2 & f1, target)
1362 self.assertSameSet(f1 & l2, target)
1363
1364 target = r1 | r2
1365 self.assertSameSet(f1 | f2, target)
1366 self.assertSameSet(f1 | r2, target)
1367 self.assertSameSet(r2 | f1, target)
1368 self.assertSameSet(f1 | l2, target)
1369
1370 fwd_target = r1 - r2
1371 rev_target = r2 - r1
1372 self.assertSameSet(f1 - f2, fwd_target)
1373 self.assertSameSet(f2 - f1, rev_target)
1374 self.assertSameSet(f1 - r2, fwd_target)
1375 self.assertSameSet(f2 - r1, rev_target)
1376 self.assertSameSet(r1 - f2, fwd_target)
1377 self.assertSameSet(r2 - f1, rev_target)
1378 self.assertSameSet(f1 - l2, fwd_target)
1379 self.assertSameSet(f2 - l1, rev_target)
1380
1381 target = r1 ^ r2
1382 self.assertSameSet(f1 ^ f2, target)
1383 self.assertSameSet(f1 ^ r2, target)
1384 self.assertSameSet(r2 ^ f1, target)
1385 self.assertSameSet(f1 ^ l2, target)
1386
1387 # Don't change the following to use assertLess or other
1388 # "more specific" unittest assertions. The current
1389 # assertTrue/assertFalse style makes the pattern of test
1390 # case combinations clear and allows us to know for sure
1391 # the exact operator being invoked.
1392
1393 # proper subset
1394 self.assertTrue(f1 < f3)
1395 self.assertFalse(f1 < f1)
1396 self.assertFalse(f1 < f2)
1397 self.assertTrue(r1 < f3)
1398 self.assertFalse(r1 < f1)
1399 self.assertFalse(r1 < f2)
1400 self.assertTrue(r1 < r3)
1401 self.assertFalse(r1 < r1)
1402 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001403 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001404 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001405 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001406 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001407 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001408 f1 < l2
1409
1410 # any subset
1411 self.assertTrue(f1 <= f3)
1412 self.assertTrue(f1 <= f1)
1413 self.assertFalse(f1 <= f2)
1414 self.assertTrue(r1 <= f3)
1415 self.assertTrue(r1 <= f1)
1416 self.assertFalse(r1 <= f2)
1417 self.assertTrue(r1 <= r3)
1418 self.assertTrue(r1 <= r1)
1419 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001420 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001421 f1 <= l3
1422 with self.assertRaises(TypeError):
1423 f1 <= l1
1424 with self.assertRaises(TypeError):
1425 f1 <= l2
1426
1427 # proper superset
1428 self.assertTrue(f3 > f1)
1429 self.assertFalse(f1 > f1)
1430 self.assertFalse(f2 > f1)
1431 self.assertTrue(r3 > r1)
1432 self.assertFalse(f1 > r1)
1433 self.assertFalse(f2 > r1)
1434 self.assertTrue(r3 > r1)
1435 self.assertFalse(r1 > r1)
1436 self.assertFalse(r2 > r1)
1437 with self.assertRaises(TypeError):
1438 f1 > l3
1439 with self.assertRaises(TypeError):
1440 f1 > l1
1441 with self.assertRaises(TypeError):
1442 f1 > l2
1443
1444 # any superset
1445 self.assertTrue(f3 >= f1)
1446 self.assertTrue(f1 >= f1)
1447 self.assertFalse(f2 >= f1)
1448 self.assertTrue(r3 >= r1)
1449 self.assertTrue(f1 >= r1)
1450 self.assertFalse(f2 >= r1)
1451 self.assertTrue(r3 >= r1)
1452 self.assertTrue(r1 >= r1)
1453 self.assertFalse(r2 >= r1)
1454 with self.assertRaises(TypeError):
1455 f1 >= l3
1456 with self.assertRaises(TypeError):
1457 f1 >=l1
1458 with self.assertRaises(TypeError):
1459 f1 >= l2
1460
1461 # equality
1462 self.assertTrue(f1 == f1)
1463 self.assertTrue(r1 == f1)
1464 self.assertTrue(f1 == r1)
1465 self.assertFalse(f1 == f3)
1466 self.assertFalse(r1 == f3)
1467 self.assertFalse(f1 == r3)
1468 self.assertFalse(f1 == l3)
1469 self.assertFalse(f1 == l1)
1470 self.assertFalse(f1 == l2)
1471
1472 # inequality
1473 self.assertFalse(f1 != f1)
1474 self.assertFalse(r1 != f1)
1475 self.assertFalse(f1 != r1)
1476 self.assertTrue(f1 != f3)
1477 self.assertTrue(r1 != f3)
1478 self.assertTrue(f1 != r3)
1479 self.assertTrue(f1 != l3)
1480 self.assertTrue(f1 != l1)
1481 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001482
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001483 def test_Mapping(self):
1484 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001485 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001486 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001487 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1488 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001489 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001490 def __len__(self):
1491 return 0
1492 def __getitem__(self, i):
1493 raise IndexError
1494 def __iter__(self):
1495 return iter(())
1496 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001497 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001498
1499 def test_MutableMapping(self):
1500 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001501 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001502 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001503 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1504 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001505
Raymond Hettinger9117c752010-08-22 07:44:24 +00001506 def test_MutableMapping_subclass(self):
1507 # Test issue 9214
1508 mymap = UserDict()
1509 mymap['red'] = 5
1510 self.assertIsInstance(mymap.keys(), Set)
1511 self.assertIsInstance(mymap.keys(), KeysView)
1512 self.assertIsInstance(mymap.items(), Set)
1513 self.assertIsInstance(mymap.items(), ItemsView)
1514
1515 mymap = UserDict()
1516 mymap['red'] = 5
1517 z = mymap.keys() | {'orange'}
1518 self.assertIsInstance(z, set)
1519 list(z)
1520 mymap['blue'] = 7 # Shouldn't affect 'z'
1521 self.assertEqual(sorted(z), ['orange', 'red'])
1522
1523 mymap = UserDict()
1524 mymap['red'] = 5
1525 z = mymap.items() | {('orange', 3)}
1526 self.assertIsInstance(z, set)
1527 list(z)
1528 mymap['blue'] = 7 # Shouldn't affect 'z'
1529 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1530
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001531 def test_Sequence(self):
1532 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001533 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001534 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001535 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001536 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001537 self.assertIsInstance(memoryview(b""), Sequence)
1538 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001539 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001540 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1541 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001542
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001543 def test_Sequence_mixins(self):
1544 class SequenceSubclass(Sequence):
1545 def __init__(self, seq=()):
1546 self.seq = seq
1547
1548 def __getitem__(self, index):
1549 return self.seq[index]
1550
1551 def __len__(self):
1552 return len(self.seq)
1553
1554 # Compare Sequence.index() behavior to (list|str).index() behavior
1555 def assert_index_same(seq1, seq2, index_args):
1556 try:
1557 expected = seq1.index(*index_args)
1558 except ValueError:
1559 with self.assertRaises(ValueError):
1560 seq2.index(*index_args)
1561 else:
1562 actual = seq2.index(*index_args)
1563 self.assertEqual(
1564 actual, expected, '%r.index%s' % (seq1, index_args))
1565
1566 for ty in list, str:
1567 nativeseq = ty('abracadabra')
1568 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1569 seqseq = SequenceSubclass(nativeseq)
1570 for letter in set(nativeseq) | {'z'}:
1571 assert_index_same(nativeseq, seqseq, (letter,))
1572 for start in range(-3, len(nativeseq) + 3):
1573 assert_index_same(nativeseq, seqseq, (letter, start))
1574 for stop in range(-3, len(nativeseq) + 3):
1575 assert_index_same(
1576 nativeseq, seqseq, (letter, start, stop))
1577
Guido van Rossumd05eb002007-11-21 22:26:24 +00001578 def test_ByteString(self):
1579 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001580 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001581 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001582 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001583 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001584 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001585 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001586 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001587
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001588 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001589 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001590 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001591 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001592 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001593 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001594 self.assertTrue(issubclass(sample, MutableSequence))
1595 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001596 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1597 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001598
Eli Bendersky0716a572011-03-04 10:38:14 +00001599 def test_MutableSequence_mixins(self):
1600 # Test the mixins of MutableSequence by creating a miminal concrete
1601 # class inherited from it.
1602 class MutableSequenceSubclass(MutableSequence):
1603 def __init__(self):
1604 self.lst = []
1605
1606 def __setitem__(self, index, value):
1607 self.lst[index] = value
1608
1609 def __getitem__(self, index):
1610 return self.lst[index]
1611
1612 def __len__(self):
1613 return len(self.lst)
1614
1615 def __delitem__(self, index):
1616 del self.lst[index]
1617
1618 def insert(self, index, value):
1619 self.lst.insert(index, value)
1620
1621 mss = MutableSequenceSubclass()
1622 mss.append(0)
1623 mss.extend((1, 2, 3, 4))
1624 self.assertEqual(len(mss), 5)
1625 self.assertEqual(mss[3], 3)
1626 mss.reverse()
1627 self.assertEqual(mss[3], 1)
1628 mss.pop()
1629 self.assertEqual(len(mss), 4)
1630 mss.remove(3)
1631 self.assertEqual(len(mss), 3)
1632 mss += (10, 20, 30)
1633 self.assertEqual(len(mss), 6)
1634 self.assertEqual(mss[-1], 30)
1635 mss.clear()
1636 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001637
1638################################################################################
1639### Counter
1640################################################################################
1641
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001642class CounterSubclassWithSetItem(Counter):
1643 # Test a counter subclass that overrides __setitem__
1644 def __init__(self, *args, **kwds):
1645 self.called = False
1646 Counter.__init__(self, *args, **kwds)
1647 def __setitem__(self, key, value):
1648 self.called = True
1649 Counter.__setitem__(self, key, value)
1650
1651class CounterSubclassWithGet(Counter):
1652 # Test a counter subclass that overrides get()
1653 def __init__(self, *args, **kwds):
1654 self.called = False
1655 Counter.__init__(self, *args, **kwds)
1656 def get(self, key, default):
1657 self.called = True
1658 return Counter.get(self, key, default)
1659
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001660class TestCounter(unittest.TestCase):
1661
1662 def test_basics(self):
1663 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001664 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1665 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001666 self.assertIsInstance(c, dict)
1667 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001668 self.assertTrue(issubclass(Counter, dict))
1669 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001670 self.assertEqual(len(c), 3)
1671 self.assertEqual(sum(c.values()), 6)
1672 self.assertEqual(sorted(c.values()), [1, 2, 3])
1673 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1674 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1675 self.assertEqual(sorted(c.items()),
1676 [('a', 3), ('b', 2), ('c', 1)])
1677 self.assertEqual(c['b'], 2)
1678 self.assertEqual(c['z'], 0)
1679 self.assertEqual(c.__contains__('c'), True)
1680 self.assertEqual(c.__contains__('z'), False)
1681 self.assertEqual(c.get('b', 10), 2)
1682 self.assertEqual(c.get('z', 10), 10)
1683 self.assertEqual(c, dict(a=3, b=2, c=1))
1684 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1685 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1686 for i in range(5):
1687 self.assertEqual(c.most_common(i),
1688 [('a', 3), ('b', 2), ('c', 1)][:i])
1689 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1690 c['a'] += 1 # increment an existing value
1691 c['b'] -= 2 # sub existing value to zero
1692 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001693 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001694 c['d'] -= 2 # sub from a missing value
1695 c['e'] = -5 # directly assign a missing value
1696 c['f'] += 4 # add to a missing value
1697 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1698 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1699 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001700 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001701 for i in range(3):
1702 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001703 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001704 c.clear()
1705 self.assertEqual(c, {})
1706 self.assertEqual(repr(c), 'Counter()')
1707 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1708 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001709 c.update(dict(a=5, b=3))
1710 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001711 c.update(Counter('a' * 50 + 'b' * 30))
1712 c.update() # test case with no args
1713 c.__init__('a' * 500 + 'b' * 300)
1714 c.__init__('cdc')
1715 c.__init__()
1716 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1717 self.assertEqual(c.setdefault('d', 5), 1)
1718 self.assertEqual(c['d'], 1)
1719 self.assertEqual(c.setdefault('e', 5), 5)
1720 self.assertEqual(c['e'], 5)
1721
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001722 def test_init(self):
1723 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1724 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1725 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1726 self.assertRaises(TypeError, Counter, 42)
1727 self.assertRaises(TypeError, Counter, (), ())
1728 self.assertRaises(TypeError, Counter.__init__)
1729
1730 def test_update(self):
1731 c = Counter()
1732 c.update(self=42)
1733 self.assertEqual(list(c.items()), [('self', 42)])
1734 c = Counter()
1735 c.update(iterable=42)
1736 self.assertEqual(list(c.items()), [('iterable', 42)])
1737 c = Counter()
1738 c.update(iterable=None)
1739 self.assertEqual(list(c.items()), [('iterable', None)])
1740 self.assertRaises(TypeError, Counter().update, 42)
1741 self.assertRaises(TypeError, Counter().update, {}, {})
1742 self.assertRaises(TypeError, Counter.update)
1743
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001744 def test_copying(self):
1745 # Check that counters are copyable, deepcopyable, picklable, and
1746 #have a repr/eval round-trip
1747 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001748 def check(dup):
1749 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1750 self.assertIsNot(dup, words, msg)
1751 self.assertEqual(dup, words)
1752 check(words.copy())
1753 check(copy.copy(words))
1754 check(copy.deepcopy(words))
1755 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1756 with self.subTest(proto=proto):
1757 check(pickle.loads(pickle.dumps(words, proto)))
1758 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001759 update_test = Counter()
1760 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001761 check(update_test)
1762 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001763
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001764 def test_copy_subclass(self):
1765 class MyCounter(Counter):
1766 pass
1767 c = MyCounter('slartibartfast')
1768 d = c.copy()
1769 self.assertEqual(d, c)
1770 self.assertEqual(len(d), len(c))
1771 self.assertEqual(type(d), type(c))
1772
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001773 def test_conversions(self):
1774 # Convert to: set, list, dict
1775 s = 'she sells sea shells by the sea shore'
1776 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1777 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1778 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1779 self.assertEqual(set(Counter(s)), set(s))
1780
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001781 def test_invariant_for_the_in_operator(self):
1782 c = Counter(a=10, b=-2, c=0)
1783 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001784 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001785 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001786
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001787 def test_multiset_operations(self):
1788 # Verify that adding a zero counter will strip zeros and negatives
1789 c = Counter(a=10, b=-2, c=0) + Counter()
1790 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001791
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001792 elements = 'abcd'
1793 for i in range(1000):
1794 # test random pairs of multisets
1795 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001796 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001797 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001798 q.update(h=1, i=-1, j=0)
1799 for counterop, numberop in [
1800 (Counter.__add__, lambda x, y: max(0, x+y)),
1801 (Counter.__sub__, lambda x, y: max(0, x-y)),
1802 (Counter.__or__, lambda x, y: max(0,x,y)),
1803 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001804 ]:
1805 result = counterop(p, q)
1806 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001807 self.assertEqual(numberop(p[x], q[x]), result[x],
1808 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001809 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001810 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001811
1812 elements = 'abcdef'
1813 for i in range(100):
1814 # verify that random multisets with no repeats are exactly like sets
1815 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1816 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1817 for counterop, setop in [
1818 (Counter.__sub__, set.__sub__),
1819 (Counter.__or__, set.__or__),
1820 (Counter.__and__, set.__and__),
1821 ]:
1822 counter_result = counterop(p, q)
1823 set_result = setop(set(p.elements()), set(q.elements()))
1824 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001825
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001826 def test_inplace_operations(self):
1827 elements = 'abcd'
1828 for i in range(1000):
1829 # test random pairs of multisets
1830 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1831 p.update(e=1, f=-1, g=0)
1832 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1833 q.update(h=1, i=-1, j=0)
1834 for inplace_op, regular_op in [
1835 (Counter.__iadd__, Counter.__add__),
1836 (Counter.__isub__, Counter.__sub__),
1837 (Counter.__ior__, Counter.__or__),
1838 (Counter.__iand__, Counter.__and__),
1839 ]:
1840 c = p.copy()
1841 c_id = id(c)
1842 regular_result = regular_op(c, q)
1843 inplace_result = inplace_op(c, q)
1844 self.assertEqual(inplace_result, regular_result)
1845 self.assertEqual(id(inplace_result), c_id)
1846
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001847 def test_subtract(self):
1848 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1849 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1850 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1851 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1852 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1853 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1854 c = Counter('aaabbcd')
1855 c.subtract('aaaabbcce')
1856 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001857
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001858 c = Counter()
1859 c.subtract(self=42)
1860 self.assertEqual(list(c.items()), [('self', -42)])
1861 c = Counter()
1862 c.subtract(iterable=42)
1863 self.assertEqual(list(c.items()), [('iterable', -42)])
1864 self.assertRaises(TypeError, Counter().subtract, 42)
1865 self.assertRaises(TypeError, Counter().subtract, {}, {})
1866 self.assertRaises(TypeError, Counter.subtract)
1867
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001868 def test_unary(self):
1869 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1870 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1871 self.assertEqual(dict(-c), dict(a=5))
1872
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001873 def test_repr_nonsortable(self):
1874 c = Counter(a=2, b=None)
1875 r = repr(c)
1876 self.assertIn("'a': 2", r)
1877 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001878
Raymond Hettinger426e0522011-01-03 02:12:02 +00001879 def test_helper_function(self):
1880 # two paths, one for real dicts and one for other mappings
1881 elems = list('abracadabra')
1882
1883 d = dict()
1884 _count_elements(d, elems)
1885 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1886
1887 m = OrderedDict()
1888 _count_elements(m, elems)
1889 self.assertEqual(m,
1890 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1891
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001892 # test fidelity to the pure python version
1893 c = CounterSubclassWithSetItem('abracadabra')
1894 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001895 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001896 c = CounterSubclassWithGet('abracadabra')
1897 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001898 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001899
Raymond Hettinger499e1932011-02-23 07:56:53 +00001900
1901################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001902### Run tests
1903################################################################################
1904
Guido van Rossumd8faa362007-04-27 19:54:29 +00001905def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001906 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001907 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001908 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06001909 TestUserObjects,
1910 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001911 support.run_unittest(*test_classes)
1912 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001913
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001914
Guido van Rossumd8faa362007-04-27 19:54:29 +00001915if __name__ == "__main__":
1916 test_main(verbose=True)