blob: 87454cc6704cb0725a8a4ee5d507dc0c2f573ab0 [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
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000322 # n = 5000
Christian Heimes99170a52007-12-19 02:07:34 +0000323 n = 254 # SyntaxError: more than 255 arguments:
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200324 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000325 for j in range(10)]) for i in range(n)))
326 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000327 Big = namedtuple('Big', names)
328 b = Big(*range(n))
329 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000330 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000331 for pos, name in enumerate(names):
332 self.assertEqual(getattr(b, name), pos)
333 repr(b) # make sure repr() doesn't blow-up
334 d = b._asdict()
335 d_expected = dict(zip(names, range(n)))
336 self.assertEqual(d, d_expected)
337 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
338 b2_expected = list(range(n))
339 b2_expected[1] = 999
340 b2_expected[-5] = 42
341 self.assertEqual(b2, tuple(b2_expected))
342 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000343
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000344 def test_pickle(self):
345 p = TestNT(x=10, y=20, z=30)
346 for module in (pickle,):
347 loads = getattr(module, 'loads')
348 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500349 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000350 q = loads(dumps(p, protocol))
351 self.assertEqual(p, q)
352 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700353 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000354
355 def test_copy(self):
356 p = TestNT(x=10, y=20, z=30)
357 for copier in copy.copy, copy.deepcopy:
358 q = copier(p)
359 self.assertEqual(p, q)
360 self.assertEqual(p._fields, q._fields)
361
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000362 def test_name_conflicts(self):
363 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
364 # failed when used as field names. Test to make sure these now work.
365 T = namedtuple('T', 'itemgetter property self cls tuple')
366 t = T(1, 2, 3, 4, 5)
367 self.assertEqual(t, (1,2,3,4,5))
368 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
369 self.assertEqual(newt, (10,20,30,40,50))
370
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000371 # Broader test of all interesting names in a template
372 with support.captured_stdout() as template:
373 T = namedtuple('T', 'x', verbose=True)
374 words = set(re.findall('[A-Za-z]+', template.getvalue()))
375 words -= set(keyword.kwlist)
376 T = namedtuple('T', words)
377 # test __new__
378 values = tuple(range(len(words)))
379 t = T(*values)
380 self.assertEqual(t, values)
381 t = T(**dict(zip(T._fields, values)))
382 self.assertEqual(t, values)
383 # test _make
384 t = T._make(values)
385 self.assertEqual(t, values)
386 # exercise __repr__
387 repr(t)
388 # test _asdict
389 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
390 # test _replace
391 t = T._make(values)
392 newvalues = tuple(v*10 for v in values)
393 newt = t._replace(**dict(zip(T._fields, newvalues)))
394 self.assertEqual(newt, newvalues)
395 # test _fields
396 self.assertEqual(T._fields, tuple(words))
397 # test __getnewargs__
398 self.assertEqual(t.__getnewargs__(), values)
399
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000400 def test_repr(self):
401 with support.captured_stdout() as template:
402 A = namedtuple('A', 'x', verbose=True)
403 self.assertEqual(repr(A(1)), 'A(x=1)')
404 # repr should show the name of the subclass
405 class B(A):
406 pass
407 self.assertEqual(repr(B(1)), 'B(x=1)')
408
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700409 def test_source(self):
410 # verify that _source can be run through exec()
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700411 tmp = namedtuple('NTColor', 'red green blue')
412 globals().pop('NTColor', None) # remove artifacts from other tests
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700413 exec(tmp._source, globals())
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700414 self.assertIn('NTColor', globals())
415 c = NTColor(10, 20, 30)
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700416 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700417 self.assertEqual(NTColor._fields, ('red', 'green', 'blue'))
418 globals().pop('NTColor', None) # clean-up after this test
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700419
Raymond Hettinger6538b432016-08-16 10:55:43 -0700420 def test_keyword_only_arguments(self):
421 # See issue 25628
422 with support.captured_stdout() as template:
423 NT = namedtuple('NT', ['x', 'y'], verbose=True)
424 self.assertIn('class NT', NT._source)
425 with self.assertRaises(TypeError):
426 NT = namedtuple('NT', ['x', 'y'], True)
427
428 NT = namedtuple('NT', ['abc', 'def'], rename=True)
429 self.assertEqual(NT._fields, ('abc', '_1'))
430 with self.assertRaises(TypeError):
431 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000432
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700433 def test_namedtuple_subclass_issue_24931(self):
434 class Point(namedtuple('_Point', ['x', 'y'])):
435 pass
436
437 a = Point(3, 4)
438 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
439
440 a.w = 5
441 self.assertEqual(a.__dict__, {'w': 5})
442
443
Raymond Hettinger499e1932011-02-23 07:56:53 +0000444################################################################################
445### Abstract Base Classes
446################################################################################
447
Raymond Hettingerae650182009-01-28 23:33:59 +0000448class ABCTestCase(unittest.TestCase):
449
450 def validate_abstract_methods(self, abc, *names):
451 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
452
453 # everything should work will all required methods are present
454 C = type('C', (abc,), methodstubs)
455 C()
456
457 # instantiation should fail if a required method is missing
458 for name in names:
459 stubs = methodstubs.copy()
460 del stubs[name]
461 C = type('C', (abc,), stubs)
462 self.assertRaises(TypeError, C, name)
463
Florent Xiclunace153f62010-03-08 15:34:35 +0000464 def validate_isinstance(self, abc, name):
465 stub = lambda s, *args: 0
466
467 C = type('C', (object,), {'__hash__': None})
468 setattr(C, name, stub)
469 self.assertIsInstance(C(), abc)
470 self.assertTrue(issubclass(C, abc))
471
472 C = type('C', (object,), {'__hash__': None})
473 self.assertNotIsInstance(C(), abc)
474 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000475
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000476 def validate_comparison(self, instance):
477 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
478 operators = {}
479 for op in ops:
480 name = '__' + op + '__'
481 operators[name] = getattr(operator, name)
482
483 class Other:
484 def __init__(self):
485 self.right_side = False
486 def __eq__(self, other):
487 self.right_side = True
488 return True
489 __lt__ = __eq__
490 __gt__ = __eq__
491 __le__ = __eq__
492 __ge__ = __eq__
493 __ne__ = __eq__
494 __ror__ = __eq__
495 __rand__ = __eq__
496 __rxor__ = __eq__
497 __rsub__ = __eq__
498
499 for name, op in operators.items():
500 if not hasattr(instance, name):
501 continue
502 other = Other()
503 op(instance, other)
504 self.assertTrue(other.right_side,'Right side not called for %s.%s'
505 % (type(instance), name))
506
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700507def _test_gen():
508 yield
509
Raymond Hettingerae650182009-01-28 23:33:59 +0000510class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000511
Yury Selivanov75445082015-05-11 22:57:16 -0400512 def test_Awaitable(self):
513 def gen():
514 yield
515
516 @types.coroutine
517 def coro():
518 yield
519
520 async def new_coro():
521 pass
522
523 class Bar:
524 def __await__(self):
525 yield
526
527 class MinimalCoro(Coroutine):
528 def send(self, value):
529 return value
530 def throw(self, typ, val=None, tb=None):
531 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400532 def __await__(self):
533 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400534
535 non_samples = [None, int(), gen(), object()]
536 for x in non_samples:
537 self.assertNotIsInstance(x, Awaitable)
538 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
539
540 samples = [Bar(), MinimalCoro()]
541 for x in samples:
542 self.assertIsInstance(x, Awaitable)
543 self.assertTrue(issubclass(type(x), Awaitable))
544
545 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400546 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
547 # flag don't have '__await__' method, hence can't be instances
548 # of Awaitable. Use inspect.isawaitable to detect them.
549 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400550
551 c = new_coro()
552 self.assertIsInstance(c, Awaitable)
553 c.close() # awoid RuntimeWarning that coro() was not awaited
554
Yury Selivanov56fc6142015-05-29 09:01:29 -0400555 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400556 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400557 self.assertTrue(isinstance(CoroLike(), Awaitable))
558 self.assertTrue(issubclass(CoroLike, Awaitable))
559 CoroLike = None
560 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400561
Yury Selivanov75445082015-05-11 22:57:16 -0400562 def test_Coroutine(self):
563 def gen():
564 yield
565
566 @types.coroutine
567 def coro():
568 yield
569
570 async def new_coro():
571 pass
572
573 class Bar:
574 def __await__(self):
575 yield
576
577 class MinimalCoro(Coroutine):
578 def send(self, value):
579 return value
580 def throw(self, typ, val=None, tb=None):
581 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400582 def __await__(self):
583 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400584
585 non_samples = [None, int(), gen(), object(), Bar()]
586 for x in non_samples:
587 self.assertNotIsInstance(x, Coroutine)
588 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
589
590 samples = [MinimalCoro()]
591 for x in samples:
592 self.assertIsInstance(x, Awaitable)
593 self.assertTrue(issubclass(type(x), Awaitable))
594
595 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400596 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
597 # flag don't have '__await__' method, hence can't be instances
598 # of Coroutine. Use inspect.isawaitable to detect them.
599 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400600
601 c = new_coro()
602 self.assertIsInstance(c, Coroutine)
603 c.close() # awoid RuntimeWarning that coro() was not awaited
604
Yury Selivanov56fc6142015-05-29 09:01:29 -0400605 class CoroLike:
606 def send(self, value):
607 pass
608 def throw(self, typ, val=None, tb=None):
609 pass
610 def close(self):
611 pass
612 def __await__(self):
613 pass
614 self.assertTrue(isinstance(CoroLike(), Coroutine))
615 self.assertTrue(issubclass(CoroLike, Coroutine))
616
617 class CoroLike:
618 def send(self, value):
619 pass
620 def close(self):
621 pass
622 def __await__(self):
623 pass
624 self.assertFalse(isinstance(CoroLike(), Coroutine))
625 self.assertFalse(issubclass(CoroLike, Coroutine))
626
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000627 def test_Hashable(self):
628 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000629 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000630 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000631 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000632 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000633 # Check some hashables
634 samples = [None,
635 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000636 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000637 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000638 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000639 ]
640 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000641 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000642 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000643 self.assertRaises(TypeError, Hashable)
644 # Check direct subclassing
645 class H(Hashable):
646 def __hash__(self):
647 return super().__hash__()
648 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000649 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000650 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000651 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000652
Yury Selivanove0104ae2015-05-14 12:19:16 -0400653 def test_AsyncIterable(self):
654 class AI:
655 async def __aiter__(self):
656 return self
657 self.assertTrue(isinstance(AI(), AsyncIterable))
658 self.assertTrue(issubclass(AI, AsyncIterable))
659 # Check some non-iterables
660 non_samples = [None, object, []]
661 for x in non_samples:
662 self.assertNotIsInstance(x, AsyncIterable)
663 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
664 self.validate_abstract_methods(AsyncIterable, '__aiter__')
665 self.validate_isinstance(AsyncIterable, '__aiter__')
666
667 def test_AsyncIterator(self):
668 class AI:
669 async def __aiter__(self):
670 return self
671 async def __anext__(self):
672 raise StopAsyncIteration
673 self.assertTrue(isinstance(AI(), AsyncIterator))
674 self.assertTrue(issubclass(AI, AsyncIterator))
675 non_samples = [None, object, []]
676 # Check some non-iterables
677 for x in non_samples:
678 self.assertNotIsInstance(x, AsyncIterator)
679 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
680 # Similarly to regular iterators (see issue 10565)
681 class AnextOnly:
682 async def __anext__(self):
683 raise StopAsyncIteration
684 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
685 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
686
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000687 def test_Iterable(self):
688 # Check some non-iterables
689 non_samples = [None, 42, 3.14, 1j]
690 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000691 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000692 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000693 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000694 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000695 tuple(), list(), set(), frozenset(), dict(),
696 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700697 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000698 (x for x in []),
699 ]
700 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000701 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000702 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000703 # Check direct subclassing
704 class I(Iterable):
705 def __iter__(self):
706 return super().__iter__()
707 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000708 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000709 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000710 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700711 # Check None blocking
712 class It:
713 def __iter__(self): return iter([])
714 class ItBlocked(It):
715 __iter__ = None
716 self.assertTrue(issubclass(It, Iterable))
717 self.assertTrue(isinstance(It(), Iterable))
718 self.assertFalse(issubclass(ItBlocked, Iterable))
719 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000720
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700721 def test_Reversible(self):
722 # Check some non-reversibles
723 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()]
724 for x in non_samples:
725 self.assertNotIsInstance(x, Reversible)
726 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700727 # Check some non-reversible iterables
728 non_reversibles = [dict().keys(), dict().items(), dict().values(),
729 Counter(), Counter().keys(), Counter().items(),
730 Counter().values(), _test_gen(),
731 (x for x in []), iter([]), reversed([])]
732 for x in non_reversibles:
733 self.assertNotIsInstance(x, Reversible)
734 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
735 # Check some reversible iterables
736 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
737 OrderedDict().keys(), OrderedDict().items(),
738 OrderedDict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700739 for x in samples:
740 self.assertIsInstance(x, Reversible)
741 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
742 # Check also Mapping, MutableMapping, and Sequence
743 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
744 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
745 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
746 # Check direct subclassing
747 class R(Reversible):
748 def __iter__(self):
749 return iter(list())
750 def __reversed__(self):
751 return iter(list())
752 self.assertEqual(list(reversed(R())), [])
753 self.assertFalse(issubclass(float, R))
754 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700755 # Check reversible non-iterable (which is not Reversible)
756 class RevNoIter:
757 def __reversed__(self): return reversed([])
758 class RevPlusIter(RevNoIter):
759 def __iter__(self): return iter([])
760 self.assertFalse(issubclass(RevNoIter, Reversible))
761 self.assertFalse(isinstance(RevNoIter(), Reversible))
762 self.assertTrue(issubclass(RevPlusIter, Reversible))
763 self.assertTrue(isinstance(RevPlusIter(), Reversible))
764 # Check None blocking
765 class Rev:
766 def __iter__(self): return iter([])
767 def __reversed__(self): return reversed([])
768 class RevItBlocked(Rev):
769 __iter__ = None
770 class RevRevBlocked(Rev):
771 __reversed__ = None
772 self.assertTrue(issubclass(Rev, Reversible))
773 self.assertTrue(isinstance(Rev(), Reversible))
774 self.assertFalse(issubclass(RevItBlocked, Reversible))
775 self.assertFalse(isinstance(RevItBlocked(), Reversible))
776 self.assertFalse(issubclass(RevRevBlocked, Reversible))
777 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700778
Guido van Rossumf0666942016-08-23 10:47:07 -0700779 def test_Collection(self):
780 # Check some non-collections
781 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
782 for x in non_collections:
783 self.assertNotIsInstance(x, Collection)
784 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
785 # Check some non-collection iterables
786 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
787 (x for x in []), dict().values()]
788 for x in non_col_iterables:
789 self.assertNotIsInstance(x, Collection)
790 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
791 # Check some collections
792 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
793 list(), dict().keys(), dict().items()]
794 for x in samples:
795 self.assertIsInstance(x, Collection)
796 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
797 # Check also Mapping, MutableMapping, etc.
798 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
799 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
800 self.assertTrue(issubclass(MutableMapping, Collection),
801 repr(MutableMapping))
802 self.assertTrue(issubclass(Set, Collection), repr(Set))
803 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
804 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
805 # Check direct subclassing
806 class Col(Collection):
807 def __iter__(self):
808 return iter(list())
809 def __len__(self):
810 return 0
811 def __contains__(self, item):
812 return False
813 class DerCol(Col): pass
814 self.assertEqual(list(iter(Col())), [])
815 self.assertFalse(issubclass(list, Col))
816 self.assertFalse(issubclass(set, Col))
817 self.assertFalse(issubclass(float, Col))
818 self.assertEqual(list(iter(DerCol())), [])
819 self.assertFalse(issubclass(list, DerCol))
820 self.assertFalse(issubclass(set, DerCol))
821 self.assertFalse(issubclass(float, DerCol))
822 self.validate_abstract_methods(Collection, '__len__', '__iter__',
823 '__contains__')
824 # Check sized container non-iterable (which is not Collection) etc.
825 class ColNoIter:
826 def __len__(self): return 0
827 def __contains__(self, item): return False
828 class ColNoSize:
829 def __iter__(self): return iter([])
830 def __contains__(self, item): return False
831 class ColNoCont:
832 def __iter__(self): return iter([])
833 def __len__(self): return 0
834 self.assertFalse(issubclass(ColNoIter, Collection))
835 self.assertFalse(isinstance(ColNoIter(), Collection))
836 self.assertFalse(issubclass(ColNoSize, Collection))
837 self.assertFalse(isinstance(ColNoSize(), Collection))
838 self.assertFalse(issubclass(ColNoCont, Collection))
839 self.assertFalse(isinstance(ColNoCont(), Collection))
840 # Check None blocking
841 class SizeBlock:
842 def __iter__(self): return iter([])
843 def __contains__(self): return False
844 __len__ = None
845 class IterBlock:
846 def __len__(self): return 0
847 def __contains__(self): return True
848 __iter__ = None
849 self.assertFalse(issubclass(SizeBlock, Collection))
850 self.assertFalse(isinstance(SizeBlock(), Collection))
851 self.assertFalse(issubclass(IterBlock, Collection))
852 self.assertFalse(isinstance(IterBlock(), Collection))
853 # Check None blocking in subclass
854 class ColImpl:
855 def __iter__(self):
856 return iter(list())
857 def __len__(self):
858 return 0
859 def __contains__(self, item):
860 return False
861 class NonCol(ColImpl):
862 __contains__ = None
863 self.assertFalse(issubclass(NonCol, Collection))
864 self.assertFalse(isinstance(NonCol(), Collection))
865
866
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000867 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000868 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000869 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000870 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000871 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000872 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000873 iter(tuple()), iter(list()), iter(dict()),
874 iter(set()), iter(frozenset()),
875 iter(dict().keys()), iter(dict().items()),
876 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700877 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000878 (x for x in []),
879 ]
880 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000881 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000882 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000883 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
884
885 # Issue 10565
886 class NextOnly:
887 def __next__(self):
888 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800889 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000890 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000891
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400892 def test_Generator(self):
893 class NonGen1:
894 def __iter__(self): return self
895 def __next__(self): return None
896 def close(self): pass
897 def throw(self, typ, val=None, tb=None): pass
898
899 class NonGen2:
900 def __iter__(self): return self
901 def __next__(self): return None
902 def close(self): pass
903 def send(self, value): return value
904
905 class NonGen3:
906 def close(self): pass
907 def send(self, value): return value
908 def throw(self, typ, val=None, tb=None): pass
909
910 non_samples = [
911 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
912 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
913 for x in non_samples:
914 self.assertNotIsInstance(x, Generator)
915 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
916
917 class Gen:
918 def __iter__(self): return self
919 def __next__(self): return None
920 def close(self): pass
921 def send(self, value): return value
922 def throw(self, typ, val=None, tb=None): pass
923
924 class MinimalGen(Generator):
925 def send(self, value):
926 return value
927 def throw(self, typ, val=None, tb=None):
928 super().throw(typ, val, tb)
929
930 def gen():
931 yield 1
932
933 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
934 for x in samples:
935 self.assertIsInstance(x, Iterator)
936 self.assertIsInstance(x, Generator)
937 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
938 self.validate_abstract_methods(Generator, 'send', 'throw')
939
940 # mixin tests
941 mgen = MinimalGen()
942 self.assertIs(mgen, iter(mgen))
943 self.assertIs(mgen.send(None), next(mgen))
944 self.assertEqual(2, mgen.send(2))
945 self.assertIsNone(mgen.close())
946 self.assertRaises(ValueError, mgen.throw, ValueError)
947 self.assertRaisesRegex(ValueError, "^huhu$",
948 mgen.throw, ValueError, ValueError("huhu"))
949 self.assertRaises(StopIteration, mgen.throw, StopIteration())
950
951 class FailOnClose(Generator):
952 def send(self, value): return value
953 def throw(self, *args): raise ValueError
954
955 self.assertRaises(ValueError, FailOnClose().close)
956
957 class IgnoreGeneratorExit(Generator):
958 def send(self, value): return value
959 def throw(self, *args): pass
960
961 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
962
Yury Selivanov22214ab2016-11-16 18:25:04 -0500963 def test_AsyncGenerator(self):
964 class NonAGen1:
965 def __aiter__(self): return self
966 def __anext__(self): return None
967 def aclose(self): pass
968 def athrow(self, typ, val=None, tb=None): pass
969
970 class NonAGen2:
971 def __aiter__(self): return self
972 def __anext__(self): return None
973 def aclose(self): pass
974 def asend(self, value): return value
975
976 class NonAGen3:
977 def aclose(self): pass
978 def asend(self, value): return value
979 def athrow(self, typ, val=None, tb=None): pass
980
981 non_samples = [
982 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
983 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
984 for x in non_samples:
985 self.assertNotIsInstance(x, AsyncGenerator)
986 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
987
988 class Gen:
989 def __aiter__(self): return self
990 async def __anext__(self): return None
991 async def aclose(self): pass
992 async def asend(self, value): return value
993 async def athrow(self, typ, val=None, tb=None): pass
994
995 class MinimalAGen(AsyncGenerator):
996 async def asend(self, value):
997 return value
998 async def athrow(self, typ, val=None, tb=None):
999 await super().athrow(typ, val, tb)
1000
1001 async def gen():
1002 yield 1
1003
1004 samples = [gen(), Gen(), MinimalAGen()]
1005 for x in samples:
1006 self.assertIsInstance(x, AsyncIterator)
1007 self.assertIsInstance(x, AsyncGenerator)
1008 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1009 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1010
1011 def run_async(coro):
1012 result = None
1013 while True:
1014 try:
1015 coro.send(None)
1016 except StopIteration as ex:
1017 result = ex.args[0] if ex.args else None
1018 break
1019 return result
1020
1021 # mixin tests
1022 mgen = MinimalAGen()
1023 self.assertIs(mgen, mgen.__aiter__())
1024 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1025 self.assertEqual(2, run_async(mgen.asend(2)))
1026 self.assertIsNone(run_async(mgen.aclose()))
1027 with self.assertRaises(ValueError):
1028 run_async(mgen.athrow(ValueError))
1029
1030 class FailOnClose(AsyncGenerator):
1031 async def asend(self, value): return value
1032 async def athrow(self, *args): raise ValueError
1033
1034 with self.assertRaises(ValueError):
1035 run_async(FailOnClose().aclose())
1036
1037 class IgnoreGeneratorExit(AsyncGenerator):
1038 async def asend(self, value): return value
1039 async def athrow(self, *args): pass
1040
1041 with self.assertRaises(RuntimeError):
1042 run_async(IgnoreGeneratorExit().aclose())
1043
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001044 def test_Sized(self):
1045 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001046 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001047 (x for x in []),
1048 ]
1049 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001050 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001051 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001052 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001053 tuple(), list(), set(), frozenset(), dict(),
1054 dict().keys(), dict().items(), dict().values(),
1055 ]
1056 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001057 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001058 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001059 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001060 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001061
1062 def test_Container(self):
1063 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001064 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001065 (x for x in []),
1066 ]
1067 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001068 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001069 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +00001070 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001071 tuple(), list(), set(), frozenset(), dict(),
1072 dict().keys(), dict().items(),
1073 ]
1074 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001075 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001076 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001077 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001078 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001079
1080 def test_Callable(self):
1081 non_samples = [None, 42, 3.14, 1j,
1082 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001083 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001084 (x for x in []),
1085 ]
1086 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001087 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001088 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001089 samples = [lambda: None,
1090 type, int, object,
1091 len,
1092 list.append, [].append,
1093 ]
1094 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001095 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001096 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001097 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001098 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001099
1100 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001101 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001102 class C(B):
1103 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001104 self.assertTrue(issubclass(C, B))
1105 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001106
1107 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001108 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001109 class C:
1110 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001111 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001112 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001113 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001114
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001115class WithSet(MutableSet):
1116
1117 def __init__(self, it=()):
1118 self.data = set(it)
1119
1120 def __len__(self):
1121 return len(self.data)
1122
1123 def __iter__(self):
1124 return iter(self.data)
1125
1126 def __contains__(self, item):
1127 return item in self.data
1128
1129 def add(self, item):
1130 self.data.add(item)
1131
1132 def discard(self, item):
1133 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001134
Raymond Hettingerae650182009-01-28 23:33:59 +00001135class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001136
1137 # XXX For now, we only test some virtual inheritance properties.
1138 # We should also test the proper behavior of the collection ABCs
1139 # as real base classes or mix-in classes.
1140
1141 def test_Set(self):
1142 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001143 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001144 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001145 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001146 class MySet(Set):
1147 def __contains__(self, x):
1148 return False
1149 def __len__(self):
1150 return 0
1151 def __iter__(self):
1152 return iter([])
1153 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001154
Benjamin Peterson41181742008-07-02 20:22:54 +00001155 def test_hash_Set(self):
1156 class OneTwoThreeSet(Set):
1157 def __init__(self):
1158 self.contents = [1, 2, 3]
1159 def __contains__(self, x):
1160 return x in self.contents
1161 def __len__(self):
1162 return len(self.contents)
1163 def __iter__(self):
1164 return iter(self.contents)
1165 def __hash__(self):
1166 return self._hash()
1167 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001168 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001169
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001170 def test_isdisjoint_Set(self):
1171 class MySet(Set):
1172 def __init__(self, itr):
1173 self.contents = itr
1174 def __contains__(self, x):
1175 return x in self.contents
1176 def __iter__(self):
1177 return iter(self.contents)
1178 def __len__(self):
1179 return len([x for x in self.contents])
1180 s1 = MySet((1, 2, 3))
1181 s2 = MySet((4, 5, 6))
1182 s3 = MySet((1, 5, 6))
1183 self.assertTrue(s1.isdisjoint(s2))
1184 self.assertFalse(s1.isdisjoint(s3))
1185
1186 def test_equality_Set(self):
1187 class MySet(Set):
1188 def __init__(self, itr):
1189 self.contents = itr
1190 def __contains__(self, x):
1191 return x in self.contents
1192 def __iter__(self):
1193 return iter(self.contents)
1194 def __len__(self):
1195 return len([x for x in self.contents])
1196 s1 = MySet((1,))
1197 s2 = MySet((1, 2))
1198 s3 = MySet((3, 4))
1199 s4 = MySet((3, 4))
1200 self.assertTrue(s2 > s1)
1201 self.assertTrue(s1 < s2)
1202 self.assertFalse(s2 <= s1)
1203 self.assertFalse(s2 <= s3)
1204 self.assertFalse(s1 >= s2)
1205 self.assertEqual(s3, s4)
1206 self.assertNotEqual(s2, s3)
1207
1208 def test_arithmetic_Set(self):
1209 class MySet(Set):
1210 def __init__(self, itr):
1211 self.contents = itr
1212 def __contains__(self, x):
1213 return x in self.contents
1214 def __iter__(self):
1215 return iter(self.contents)
1216 def __len__(self):
1217 return len([x for x in self.contents])
1218 s1 = MySet((1, 2, 3))
1219 s2 = MySet((3, 4, 5))
1220 s3 = s1 & s2
1221 self.assertEqual(s3, MySet((3,)))
1222
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001223 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001224 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001225 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001226 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001227 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001228 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1229 'add', 'discard')
1230
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001231 def test_issue_5647(self):
1232 # MutableSet.__iand__ mutated the set during iteration
1233 s = WithSet('abcd')
1234 s &= WithSet('cdef') # This used to fail
1235 self.assertEqual(set(s), set('cd'))
1236
Raymond Hettingerae650182009-01-28 23:33:59 +00001237 def test_issue_4920(self):
1238 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001239 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001240 __slots__=['__s']
1241 def __init__(self,items=None):
1242 if items is None:
1243 items=[]
1244 self.__s=set(items)
1245 def __contains__(self,v):
1246 return v in self.__s
1247 def __iter__(self):
1248 return iter(self.__s)
1249 def __len__(self):
1250 return len(self.__s)
1251 def add(self,v):
1252 result=v not in self.__s
1253 self.__s.add(v)
1254 return result
1255 def discard(self,v):
1256 result=v in self.__s
1257 self.__s.discard(v)
1258 return result
1259 def __repr__(self):
1260 return "MySet(%s)" % repr(list(self))
1261 s = MySet([5,43,2,1])
1262 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001263
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001264 def test_issue8750(self):
1265 empty = WithSet()
1266 full = WithSet(range(10))
1267 s = WithSet(full)
1268 s -= s
1269 self.assertEqual(s, empty)
1270 s = WithSet(full)
1271 s ^= s
1272 self.assertEqual(s, empty)
1273 s = WithSet(full)
1274 s &= s
1275 self.assertEqual(s, full)
1276 s |= s
1277 self.assertEqual(s, full)
1278
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001279 def test_issue16373(self):
1280 # Recursion error comparing comparable and noncomparable
1281 # Set instances
1282 class MyComparableSet(Set):
1283 def __contains__(self, x):
1284 return False
1285 def __len__(self):
1286 return 0
1287 def __iter__(self):
1288 return iter([])
1289 class MyNonComparableSet(Set):
1290 def __contains__(self, x):
1291 return False
1292 def __len__(self):
1293 return 0
1294 def __iter__(self):
1295 return iter([])
1296 def __le__(self, x):
1297 return NotImplemented
1298 def __lt__(self, x):
1299 return NotImplemented
1300
1301 cs = MyComparableSet()
1302 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001303 self.assertFalse(ncs < cs)
1304 self.assertTrue(ncs <= cs)
1305 self.assertFalse(ncs > cs)
1306 self.assertTrue(ncs >= cs)
1307
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001308 def test_issue26915(self):
1309 # Container membership test should check identity first
1310 class CustomEqualObject:
1311 def __eq__(self, other):
1312 return False
1313 class CustomSequence(list):
1314 def __contains__(self, value):
1315 return Sequence.__contains__(self, value)
1316
1317 nan = float('nan')
1318 obj = CustomEqualObject()
1319 containers = [
1320 CustomSequence([nan, obj]),
1321 ItemsView({1: nan, 2: obj}),
1322 ValuesView({1: nan, 2: obj})
1323 ]
1324 for container in containers:
1325 for elem in container:
1326 self.assertIn(elem, container)
1327
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001328 def assertSameSet(self, s1, s2):
1329 # coerce both to a real set then check equality
1330 self.assertSetEqual(set(s1), set(s2))
1331
1332 def test_Set_interoperability_with_real_sets(self):
1333 # Issue: 8743
1334 class ListSet(Set):
1335 def __init__(self, elements=()):
1336 self.data = []
1337 for elem in elements:
1338 if elem not in self.data:
1339 self.data.append(elem)
1340 def __contains__(self, elem):
1341 return elem in self.data
1342 def __iter__(self):
1343 return iter(self.data)
1344 def __len__(self):
1345 return len(self.data)
1346 def __repr__(self):
1347 return 'Set({!r})'.format(self.data)
1348
1349 r1 = set('abc')
1350 r2 = set('bcd')
1351 r3 = set('abcde')
1352 f1 = ListSet('abc')
1353 f2 = ListSet('bcd')
1354 f3 = ListSet('abcde')
1355 l1 = list('abccba')
1356 l2 = list('bcddcb')
1357 l3 = list('abcdeedcba')
1358
1359 target = r1 & r2
1360 self.assertSameSet(f1 & f2, target)
1361 self.assertSameSet(f1 & r2, target)
1362 self.assertSameSet(r2 & f1, target)
1363 self.assertSameSet(f1 & l2, target)
1364
1365 target = r1 | r2
1366 self.assertSameSet(f1 | f2, target)
1367 self.assertSameSet(f1 | r2, target)
1368 self.assertSameSet(r2 | f1, target)
1369 self.assertSameSet(f1 | l2, target)
1370
1371 fwd_target = r1 - r2
1372 rev_target = r2 - r1
1373 self.assertSameSet(f1 - f2, fwd_target)
1374 self.assertSameSet(f2 - f1, rev_target)
1375 self.assertSameSet(f1 - r2, fwd_target)
1376 self.assertSameSet(f2 - r1, rev_target)
1377 self.assertSameSet(r1 - f2, fwd_target)
1378 self.assertSameSet(r2 - f1, rev_target)
1379 self.assertSameSet(f1 - l2, fwd_target)
1380 self.assertSameSet(f2 - l1, rev_target)
1381
1382 target = r1 ^ r2
1383 self.assertSameSet(f1 ^ f2, target)
1384 self.assertSameSet(f1 ^ r2, target)
1385 self.assertSameSet(r2 ^ f1, target)
1386 self.assertSameSet(f1 ^ l2, target)
1387
1388 # Don't change the following to use assertLess or other
1389 # "more specific" unittest assertions. The current
1390 # assertTrue/assertFalse style makes the pattern of test
1391 # case combinations clear and allows us to know for sure
1392 # the exact operator being invoked.
1393
1394 # proper subset
1395 self.assertTrue(f1 < f3)
1396 self.assertFalse(f1 < f1)
1397 self.assertFalse(f1 < f2)
1398 self.assertTrue(r1 < f3)
1399 self.assertFalse(r1 < f1)
1400 self.assertFalse(r1 < f2)
1401 self.assertTrue(r1 < r3)
1402 self.assertFalse(r1 < r1)
1403 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001404 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001405 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001406 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001407 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001408 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001409 f1 < l2
1410
1411 # any subset
1412 self.assertTrue(f1 <= f3)
1413 self.assertTrue(f1 <= f1)
1414 self.assertFalse(f1 <= f2)
1415 self.assertTrue(r1 <= f3)
1416 self.assertTrue(r1 <= f1)
1417 self.assertFalse(r1 <= f2)
1418 self.assertTrue(r1 <= r3)
1419 self.assertTrue(r1 <= r1)
1420 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001421 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001422 f1 <= l3
1423 with self.assertRaises(TypeError):
1424 f1 <= l1
1425 with self.assertRaises(TypeError):
1426 f1 <= l2
1427
1428 # proper superset
1429 self.assertTrue(f3 > f1)
1430 self.assertFalse(f1 > f1)
1431 self.assertFalse(f2 > f1)
1432 self.assertTrue(r3 > r1)
1433 self.assertFalse(f1 > r1)
1434 self.assertFalse(f2 > r1)
1435 self.assertTrue(r3 > r1)
1436 self.assertFalse(r1 > r1)
1437 self.assertFalse(r2 > r1)
1438 with self.assertRaises(TypeError):
1439 f1 > l3
1440 with self.assertRaises(TypeError):
1441 f1 > l1
1442 with self.assertRaises(TypeError):
1443 f1 > l2
1444
1445 # any superset
1446 self.assertTrue(f3 >= f1)
1447 self.assertTrue(f1 >= f1)
1448 self.assertFalse(f2 >= f1)
1449 self.assertTrue(r3 >= r1)
1450 self.assertTrue(f1 >= r1)
1451 self.assertFalse(f2 >= r1)
1452 self.assertTrue(r3 >= r1)
1453 self.assertTrue(r1 >= r1)
1454 self.assertFalse(r2 >= r1)
1455 with self.assertRaises(TypeError):
1456 f1 >= l3
1457 with self.assertRaises(TypeError):
1458 f1 >=l1
1459 with self.assertRaises(TypeError):
1460 f1 >= l2
1461
1462 # equality
1463 self.assertTrue(f1 == f1)
1464 self.assertTrue(r1 == f1)
1465 self.assertTrue(f1 == r1)
1466 self.assertFalse(f1 == f3)
1467 self.assertFalse(r1 == f3)
1468 self.assertFalse(f1 == r3)
1469 self.assertFalse(f1 == l3)
1470 self.assertFalse(f1 == l1)
1471 self.assertFalse(f1 == l2)
1472
1473 # inequality
1474 self.assertFalse(f1 != f1)
1475 self.assertFalse(r1 != f1)
1476 self.assertFalse(f1 != r1)
1477 self.assertTrue(f1 != f3)
1478 self.assertTrue(r1 != f3)
1479 self.assertTrue(f1 != r3)
1480 self.assertTrue(f1 != l3)
1481 self.assertTrue(f1 != l1)
1482 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001483
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001484 def test_Mapping(self):
1485 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001486 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001487 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001488 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1489 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001490 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001491 def __len__(self):
1492 return 0
1493 def __getitem__(self, i):
1494 raise IndexError
1495 def __iter__(self):
1496 return iter(())
1497 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001498 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001499
1500 def test_MutableMapping(self):
1501 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001502 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001503 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001504 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1505 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001506
Raymond Hettinger9117c752010-08-22 07:44:24 +00001507 def test_MutableMapping_subclass(self):
1508 # Test issue 9214
1509 mymap = UserDict()
1510 mymap['red'] = 5
1511 self.assertIsInstance(mymap.keys(), Set)
1512 self.assertIsInstance(mymap.keys(), KeysView)
1513 self.assertIsInstance(mymap.items(), Set)
1514 self.assertIsInstance(mymap.items(), ItemsView)
1515
1516 mymap = UserDict()
1517 mymap['red'] = 5
1518 z = mymap.keys() | {'orange'}
1519 self.assertIsInstance(z, set)
1520 list(z)
1521 mymap['blue'] = 7 # Shouldn't affect 'z'
1522 self.assertEqual(sorted(z), ['orange', 'red'])
1523
1524 mymap = UserDict()
1525 mymap['red'] = 5
1526 z = mymap.items() | {('orange', 3)}
1527 self.assertIsInstance(z, set)
1528 list(z)
1529 mymap['blue'] = 7 # Shouldn't affect 'z'
1530 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1531
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001532 def test_Sequence(self):
1533 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001534 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001535 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001536 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001537 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001538 self.assertIsInstance(memoryview(b""), Sequence)
1539 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001540 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001541 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1542 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001543
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001544 def test_Sequence_mixins(self):
1545 class SequenceSubclass(Sequence):
1546 def __init__(self, seq=()):
1547 self.seq = seq
1548
1549 def __getitem__(self, index):
1550 return self.seq[index]
1551
1552 def __len__(self):
1553 return len(self.seq)
1554
1555 # Compare Sequence.index() behavior to (list|str).index() behavior
1556 def assert_index_same(seq1, seq2, index_args):
1557 try:
1558 expected = seq1.index(*index_args)
1559 except ValueError:
1560 with self.assertRaises(ValueError):
1561 seq2.index(*index_args)
1562 else:
1563 actual = seq2.index(*index_args)
1564 self.assertEqual(
1565 actual, expected, '%r.index%s' % (seq1, index_args))
1566
1567 for ty in list, str:
1568 nativeseq = ty('abracadabra')
1569 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1570 seqseq = SequenceSubclass(nativeseq)
1571 for letter in set(nativeseq) | {'z'}:
1572 assert_index_same(nativeseq, seqseq, (letter,))
1573 for start in range(-3, len(nativeseq) + 3):
1574 assert_index_same(nativeseq, seqseq, (letter, start))
1575 for stop in range(-3, len(nativeseq) + 3):
1576 assert_index_same(
1577 nativeseq, seqseq, (letter, start, stop))
1578
Guido van Rossumd05eb002007-11-21 22:26:24 +00001579 def test_ByteString(self):
1580 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001581 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001582 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001583 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001584 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001585 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001586 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001587 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001588
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001589 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001590 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001591 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001592 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001593 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001594 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001595 self.assertTrue(issubclass(sample, MutableSequence))
1596 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001597 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1598 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001599
Eli Bendersky0716a572011-03-04 10:38:14 +00001600 def test_MutableSequence_mixins(self):
1601 # Test the mixins of MutableSequence by creating a miminal concrete
1602 # class inherited from it.
1603 class MutableSequenceSubclass(MutableSequence):
1604 def __init__(self):
1605 self.lst = []
1606
1607 def __setitem__(self, index, value):
1608 self.lst[index] = value
1609
1610 def __getitem__(self, index):
1611 return self.lst[index]
1612
1613 def __len__(self):
1614 return len(self.lst)
1615
1616 def __delitem__(self, index):
1617 del self.lst[index]
1618
1619 def insert(self, index, value):
1620 self.lst.insert(index, value)
1621
1622 mss = MutableSequenceSubclass()
1623 mss.append(0)
1624 mss.extend((1, 2, 3, 4))
1625 self.assertEqual(len(mss), 5)
1626 self.assertEqual(mss[3], 3)
1627 mss.reverse()
1628 self.assertEqual(mss[3], 1)
1629 mss.pop()
1630 self.assertEqual(len(mss), 4)
1631 mss.remove(3)
1632 self.assertEqual(len(mss), 3)
1633 mss += (10, 20, 30)
1634 self.assertEqual(len(mss), 6)
1635 self.assertEqual(mss[-1], 30)
1636 mss.clear()
1637 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001638
1639################################################################################
1640### Counter
1641################################################################################
1642
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001643class CounterSubclassWithSetItem(Counter):
1644 # Test a counter subclass that overrides __setitem__
1645 def __init__(self, *args, **kwds):
1646 self.called = False
1647 Counter.__init__(self, *args, **kwds)
1648 def __setitem__(self, key, value):
1649 self.called = True
1650 Counter.__setitem__(self, key, value)
1651
1652class CounterSubclassWithGet(Counter):
1653 # Test a counter subclass that overrides get()
1654 def __init__(self, *args, **kwds):
1655 self.called = False
1656 Counter.__init__(self, *args, **kwds)
1657 def get(self, key, default):
1658 self.called = True
1659 return Counter.get(self, key, default)
1660
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001661class TestCounter(unittest.TestCase):
1662
1663 def test_basics(self):
1664 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001665 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1666 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001667 self.assertIsInstance(c, dict)
1668 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001669 self.assertTrue(issubclass(Counter, dict))
1670 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001671 self.assertEqual(len(c), 3)
1672 self.assertEqual(sum(c.values()), 6)
1673 self.assertEqual(sorted(c.values()), [1, 2, 3])
1674 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1675 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1676 self.assertEqual(sorted(c.items()),
1677 [('a', 3), ('b', 2), ('c', 1)])
1678 self.assertEqual(c['b'], 2)
1679 self.assertEqual(c['z'], 0)
1680 self.assertEqual(c.__contains__('c'), True)
1681 self.assertEqual(c.__contains__('z'), False)
1682 self.assertEqual(c.get('b', 10), 2)
1683 self.assertEqual(c.get('z', 10), 10)
1684 self.assertEqual(c, dict(a=3, b=2, c=1))
1685 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1686 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1687 for i in range(5):
1688 self.assertEqual(c.most_common(i),
1689 [('a', 3), ('b', 2), ('c', 1)][:i])
1690 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1691 c['a'] += 1 # increment an existing value
1692 c['b'] -= 2 # sub existing value to zero
1693 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001694 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001695 c['d'] -= 2 # sub from a missing value
1696 c['e'] = -5 # directly assign a missing value
1697 c['f'] += 4 # add to a missing value
1698 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1699 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1700 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001701 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001702 for i in range(3):
1703 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001704 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001705 c.clear()
1706 self.assertEqual(c, {})
1707 self.assertEqual(repr(c), 'Counter()')
1708 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1709 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001710 c.update(dict(a=5, b=3))
1711 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001712 c.update(Counter('a' * 50 + 'b' * 30))
1713 c.update() # test case with no args
1714 c.__init__('a' * 500 + 'b' * 300)
1715 c.__init__('cdc')
1716 c.__init__()
1717 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1718 self.assertEqual(c.setdefault('d', 5), 1)
1719 self.assertEqual(c['d'], 1)
1720 self.assertEqual(c.setdefault('e', 5), 5)
1721 self.assertEqual(c['e'], 5)
1722
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001723 def test_init(self):
1724 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1725 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1726 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1727 self.assertRaises(TypeError, Counter, 42)
1728 self.assertRaises(TypeError, Counter, (), ())
1729 self.assertRaises(TypeError, Counter.__init__)
1730
1731 def test_update(self):
1732 c = Counter()
1733 c.update(self=42)
1734 self.assertEqual(list(c.items()), [('self', 42)])
1735 c = Counter()
1736 c.update(iterable=42)
1737 self.assertEqual(list(c.items()), [('iterable', 42)])
1738 c = Counter()
1739 c.update(iterable=None)
1740 self.assertEqual(list(c.items()), [('iterable', None)])
1741 self.assertRaises(TypeError, Counter().update, 42)
1742 self.assertRaises(TypeError, Counter().update, {}, {})
1743 self.assertRaises(TypeError, Counter.update)
1744
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001745 def test_copying(self):
1746 # Check that counters are copyable, deepcopyable, picklable, and
1747 #have a repr/eval round-trip
1748 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001749 def check(dup):
1750 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1751 self.assertIsNot(dup, words, msg)
1752 self.assertEqual(dup, words)
1753 check(words.copy())
1754 check(copy.copy(words))
1755 check(copy.deepcopy(words))
1756 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1757 with self.subTest(proto=proto):
1758 check(pickle.loads(pickle.dumps(words, proto)))
1759 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001760 update_test = Counter()
1761 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001762 check(update_test)
1763 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001764
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001765 def test_copy_subclass(self):
1766 class MyCounter(Counter):
1767 pass
1768 c = MyCounter('slartibartfast')
1769 d = c.copy()
1770 self.assertEqual(d, c)
1771 self.assertEqual(len(d), len(c))
1772 self.assertEqual(type(d), type(c))
1773
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001774 def test_conversions(self):
1775 # Convert to: set, list, dict
1776 s = 'she sells sea shells by the sea shore'
1777 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1778 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1779 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1780 self.assertEqual(set(Counter(s)), set(s))
1781
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001782 def test_invariant_for_the_in_operator(self):
1783 c = Counter(a=10, b=-2, c=0)
1784 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001785 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001786 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001787
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001788 def test_multiset_operations(self):
1789 # Verify that adding a zero counter will strip zeros and negatives
1790 c = Counter(a=10, b=-2, c=0) + Counter()
1791 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001792
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001793 elements = 'abcd'
1794 for i in range(1000):
1795 # test random pairs of multisets
1796 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001797 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001798 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001799 q.update(h=1, i=-1, j=0)
1800 for counterop, numberop in [
1801 (Counter.__add__, lambda x, y: max(0, x+y)),
1802 (Counter.__sub__, lambda x, y: max(0, x-y)),
1803 (Counter.__or__, lambda x, y: max(0,x,y)),
1804 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001805 ]:
1806 result = counterop(p, q)
1807 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001808 self.assertEqual(numberop(p[x], q[x]), result[x],
1809 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001810 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001811 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001812
1813 elements = 'abcdef'
1814 for i in range(100):
1815 # verify that random multisets with no repeats are exactly like sets
1816 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1817 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1818 for counterop, setop in [
1819 (Counter.__sub__, set.__sub__),
1820 (Counter.__or__, set.__or__),
1821 (Counter.__and__, set.__and__),
1822 ]:
1823 counter_result = counterop(p, q)
1824 set_result = setop(set(p.elements()), set(q.elements()))
1825 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001826
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001827 def test_inplace_operations(self):
1828 elements = 'abcd'
1829 for i in range(1000):
1830 # test random pairs of multisets
1831 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1832 p.update(e=1, f=-1, g=0)
1833 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1834 q.update(h=1, i=-1, j=0)
1835 for inplace_op, regular_op in [
1836 (Counter.__iadd__, Counter.__add__),
1837 (Counter.__isub__, Counter.__sub__),
1838 (Counter.__ior__, Counter.__or__),
1839 (Counter.__iand__, Counter.__and__),
1840 ]:
1841 c = p.copy()
1842 c_id = id(c)
1843 regular_result = regular_op(c, q)
1844 inplace_result = inplace_op(c, q)
1845 self.assertEqual(inplace_result, regular_result)
1846 self.assertEqual(id(inplace_result), c_id)
1847
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001848 def test_subtract(self):
1849 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1850 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1851 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1852 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1853 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1854 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1855 c = Counter('aaabbcd')
1856 c.subtract('aaaabbcce')
1857 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001858
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001859 c = Counter()
1860 c.subtract(self=42)
1861 self.assertEqual(list(c.items()), [('self', -42)])
1862 c = Counter()
1863 c.subtract(iterable=42)
1864 self.assertEqual(list(c.items()), [('iterable', -42)])
1865 self.assertRaises(TypeError, Counter().subtract, 42)
1866 self.assertRaises(TypeError, Counter().subtract, {}, {})
1867 self.assertRaises(TypeError, Counter.subtract)
1868
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001869 def test_unary(self):
1870 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1871 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1872 self.assertEqual(dict(-c), dict(a=5))
1873
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001874 def test_repr_nonsortable(self):
1875 c = Counter(a=2, b=None)
1876 r = repr(c)
1877 self.assertIn("'a': 2", r)
1878 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001879
Raymond Hettinger426e0522011-01-03 02:12:02 +00001880 def test_helper_function(self):
1881 # two paths, one for real dicts and one for other mappings
1882 elems = list('abracadabra')
1883
1884 d = dict()
1885 _count_elements(d, elems)
1886 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1887
1888 m = OrderedDict()
1889 _count_elements(m, elems)
1890 self.assertEqual(m,
1891 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1892
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001893 # test fidelity to the pure python version
1894 c = CounterSubclassWithSetItem('abracadabra')
1895 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001896 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001897 c = CounterSubclassWithGet('abracadabra')
1898 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001899 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001900
Raymond Hettinger499e1932011-02-23 07:56:53 +00001901
1902################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001903### Run tests
1904################################################################################
1905
Guido van Rossumd8faa362007-04-27 19:54:29 +00001906def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001907 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001908 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001909 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06001910 TestUserObjects,
1911 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001912 support.run_unittest(*test_classes)
1913 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001914
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001915
Guido van Rossumd8faa362007-04-27 19:54:29 +00001916if __name__ == "__main__":
1917 test_main(verbose=True)