blob: f1fb0112667b9541d938820bc13bcc53bec2106f [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 Selivanove0104ae2015-05-14 12:19:16 -040022from collections.abc import Awaitable, Coroutine, AsyncIterator, AsyncIterable
Guido van Rossum16ca06b2016-04-04 10:59:29 -070023from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
Guido van Rossumf0666942016-08-23 10:47:07 -070024from collections.abc import Sized, Container, Callable, Collection
Raymond Hettinger57d1a882011-02-23 00:46:28 +000025from collections.abc import Set, MutableSet
Raymond Hettinger584e8ae2016-05-05 11:14:06 +030026from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
Raymond Hettinger57d1a882011-02-23 00:46:28 +000027from collections.abc import Sequence, MutableSequence
28from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000029
Raymond Hettinger499e1932011-02-23 07:56:53 +000030
Raymond Hettinger573b44c2015-05-22 16:56:32 -070031class TestUserObjects(unittest.TestCase):
32 def _superset_test(self, a, b):
33 self.assertGreaterEqual(
34 set(dir(a)),
35 set(dir(b)),
36 '{a} should have all the methods of {b}'.format(
37 a=a.__name__,
38 b=b.__name__,
39 ),
40 )
41 def test_str_protocol(self):
42 self._superset_test(UserString, str)
43
44 def test_list_protocol(self):
45 self._superset_test(UserList, list)
46
47 def test_dict_protocol(self):
48 self._superset_test(UserDict, dict)
49
50
Raymond Hettinger499e1932011-02-23 07:56:53 +000051################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000052### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000053################################################################################
54
55class TestChainMap(unittest.TestCase):
56
57 def test_basics(self):
58 c = ChainMap()
59 c['a'] = 1
60 c['b'] = 2
61 d = c.new_child()
62 d['b'] = 20
63 d['c'] = 30
64 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
65 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
66 self.assertEqual(len(d), 3) # check len
67 for key in 'abc': # check contains
68 self.assertIn(key, d)
69 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
70 self.assertEqual(d.get(k, 100), v)
71
72 del d['b'] # unmask a value
73 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
74 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
75 self.assertEqual(len(d), 3) # check len
76 for key in 'abc': # check contains
77 self.assertIn(key, d)
78 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
79 self.assertEqual(d.get(k, 100), v)
80 self.assertIn(repr(d), [ # check repr
81 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
82 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
83 ])
84
85 for e in d.copy(), copy.copy(d): # check shallow copies
86 self.assertEqual(d, e)
87 self.assertEqual(d.maps, e.maps)
88 self.assertIsNot(d, e)
89 self.assertIsNot(d.maps[0], e.maps[0])
90 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
91 self.assertIs(m1, m2)
92
Serhiy Storchakabad12572014-12-15 14:03:42 +020093 # check deep copies
94 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
95 e = pickle.loads(pickle.dumps(d, proto))
96 self.assertEqual(d, e)
97 self.assertEqual(d.maps, e.maps)
98 self.assertIsNot(d, e)
99 for m1, m2 in zip(d.maps, e.maps):
100 self.assertIsNot(m1, m2, e)
101 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +0000102 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200103 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000104 self.assertEqual(d, e)
105 self.assertEqual(d.maps, e.maps)
106 self.assertIsNot(d, e)
107 for m1, m2 in zip(d.maps, e.maps):
108 self.assertIsNot(m1, m2, e)
109
Raymond Hettingerd0321312011-02-26 06:53:58 +0000110 f = d.new_child()
111 f['b'] = 5
112 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
113 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
114 self.assertEqual(f['b'], 5) # find first in chain
115 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000116
Martin Pantereb995702016-07-28 01:11:04 +0000117 def test_constructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000118 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000119 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
120
Raymond Hettingerd0321312011-02-26 06:53:58 +0000121 def test_bool(self):
122 self.assertFalse(ChainMap())
123 self.assertFalse(ChainMap({}, {}))
124 self.assertTrue(ChainMap({1:2}, {}))
125 self.assertTrue(ChainMap({}, {1:2}))
126
Raymond Hettinger499e1932011-02-23 07:56:53 +0000127 def test_missing(self):
128 class DefaultChainMap(ChainMap):
129 def __missing__(self, key):
130 return 999
131 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
132 for k, v in dict(a=1, b=2, c=30, d=999).items():
133 self.assertEqual(d[k], v) # check __getitem__ w/missing
134 for k, v in dict(a=1, b=2, c=30, d=77).items():
135 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
136 for k, v in dict(a=True, b=True, c=True, d=False).items():
137 self.assertEqual(k in d, v) # check __contains__ w/missing
138 self.assertEqual(d.pop('a', 1001), 1, d)
139 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
140 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
141 with self.assertRaises(KeyError):
142 d.popitem()
143
144 def test_dict_coercion(self):
145 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
146 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
147 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
148
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000149 def test_new_child(self):
150 'Tests for changes for issue #16613.'
151 c = ChainMap()
152 c['a'] = 1
153 c['b'] = 2
154 m = {'b':20, 'c': 30}
155 d = c.new_child(m)
156 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
157 self.assertIs(m, d.maps[0])
158
159 # Use a different map than a dict
160 class lowerdict(dict):
161 def __getitem__(self, key):
162 if isinstance(key, str):
163 key = key.lower()
164 return dict.__getitem__(self, key)
165 def __contains__(self, key):
166 if isinstance(key, str):
167 key = key.lower()
168 return dict.__contains__(self, key)
169
170 c = ChainMap()
171 c['a'] = 1
172 c['b'] = 2
173 m = lowerdict(b=20, c=30)
174 d = c.new_child(m)
175 self.assertIs(m, d.maps[0])
176 for key in 'abc': # check contains
177 self.assertIn(key, d)
178 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
179 self.assertEqual(d.get(k, 100), v)
180
Raymond Hettinger499e1932011-02-23 07:56:53 +0000181
182################################################################################
183### Named Tuples
184################################################################################
185
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000186TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000187
188class TestNamedTuple(unittest.TestCase):
189
190 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000191 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000192 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000193 self.assertEqual(Point.__slots__, ())
194 self.assertEqual(Point.__module__, __name__)
195 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000196 self.assertEqual(Point._fields, ('x', 'y'))
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700197 self.assertIn('class Point(tuple)', Point._source)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000198
199 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
200 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
201 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
202
203 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
204 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
205 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000206 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000207 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
208
209 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000210 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000211
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000212 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000213 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000214 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000215 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000216
Christian Heimesfaf2f632008-01-06 16:59:19 +0000217 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
218 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
219
R. David Murray378c0cf2010-02-24 01:46:21 +0000220 @unittest.skipIf(sys.flags.optimize >= 2,
221 "Docstrings are omitted with -O2 and above")
222 def test_factory_doc_attr(self):
223 Point = namedtuple('Point', 'x y')
224 self.assertEqual(Point.__doc__, 'Point(x, y)')
225
Raymond Hettingereac503a2015-05-13 01:09:59 -0700226 @unittest.skipIf(sys.flags.optimize >= 2,
227 "Docstrings are omitted with -O2 and above")
228 def test_doc_writable(self):
229 Point = namedtuple('Point', 'x y')
230 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
231 Point.x.__doc__ = 'docstring for Point.x'
232 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
233
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000234 def test_name_fixer(self):
235 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000236 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
237 [('abc', 'class'), ('abc', '_1')], # field has keyword
238 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
239 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
240 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
241 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000242 ]:
243 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
244
Guido van Rossumd8faa362007-04-27 19:54:29 +0000245 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000246 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000247 p = Point(11, 22)
248 self.assertEqual(p, Point(x=11, y=22))
249 self.assertEqual(p, Point(11, y=22))
250 self.assertEqual(p, Point(y=22, x=11))
251 self.assertEqual(p, Point(*(11, 22)))
252 self.assertEqual(p, Point(**dict(x=11, y=22)))
253 self.assertRaises(TypeError, Point, 1) # too few args
254 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
255 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
256 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
257 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000258 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000259 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000260 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
261 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700262 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000263
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000264 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000265 p._replace(x=1, error=2)
266 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000267 pass
268 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000269 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000270
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000271 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000272 Point = namedtuple('Point', 'x, y')
273 p = Point(x=11, y=22)
274 self.assertEqual(repr(p), 'Point(x=11, y=22)')
275
276 # verify that fieldspec can be a non-string sequence
277 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000278 p = Point(x=11, y=22)
279 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000280
281 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000282 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000283 p = Point(11, 22)
284
Ezio Melottie9615932010-01-24 19:26:24 +0000285 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000286 self.assertEqual(p, (11, 22)) # matches a real tuple
287 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
288 self.assertEqual(list(p), [11, 22]) # coercable to a list
289 self.assertEqual(max(p), 22) # iterable
290 self.assertEqual(max(*p), 22) # star-able
291 x, y = p
292 self.assertEqual(p, (x, y)) # unpacks like a tuple
293 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
294 self.assertRaises(IndexError, p.__getitem__, 3)
295
296 self.assertEqual(p.x, x)
297 self.assertEqual(p.y, y)
298 self.assertRaises(AttributeError, eval, 'p.z', locals())
299
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000300 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000301 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000302 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000303 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000304 self.assertEqual(repr(Zero()), 'Zero()')
305 self.assertEqual(Zero()._asdict(), {})
306 self.assertEqual(Zero()._fields, ())
307
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000308 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000309 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000310 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000311 self.assertEqual(Dot(1).d, 1)
312 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
313 self.assertEqual(Dot(1)._asdict(), {'d':1})
314 self.assertEqual(Dot(1)._replace(d=999), (999,))
315 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000316
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000317 # n = 5000
Christian Heimes99170a52007-12-19 02:07:34 +0000318 n = 254 # SyntaxError: more than 255 arguments:
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200319 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000320 for j in range(10)]) for i in range(n)))
321 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000322 Big = namedtuple('Big', names)
323 b = Big(*range(n))
324 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000325 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000326 for pos, name in enumerate(names):
327 self.assertEqual(getattr(b, name), pos)
328 repr(b) # make sure repr() doesn't blow-up
329 d = b._asdict()
330 d_expected = dict(zip(names, range(n)))
331 self.assertEqual(d, d_expected)
332 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
333 b2_expected = list(range(n))
334 b2_expected[1] = 999
335 b2_expected[-5] = 42
336 self.assertEqual(b2, tuple(b2_expected))
337 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000338
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000339 def test_pickle(self):
340 p = TestNT(x=10, y=20, z=30)
341 for module in (pickle,):
342 loads = getattr(module, 'loads')
343 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500344 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000345 q = loads(dumps(p, protocol))
346 self.assertEqual(p, q)
347 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700348 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000349
350 def test_copy(self):
351 p = TestNT(x=10, y=20, z=30)
352 for copier in copy.copy, copy.deepcopy:
353 q = copier(p)
354 self.assertEqual(p, q)
355 self.assertEqual(p._fields, q._fields)
356
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000357 def test_name_conflicts(self):
358 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
359 # failed when used as field names. Test to make sure these now work.
360 T = namedtuple('T', 'itemgetter property self cls tuple')
361 t = T(1, 2, 3, 4, 5)
362 self.assertEqual(t, (1,2,3,4,5))
363 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
364 self.assertEqual(newt, (10,20,30,40,50))
365
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000366 # Broader test of all interesting names in a template
367 with support.captured_stdout() as template:
368 T = namedtuple('T', 'x', verbose=True)
369 words = set(re.findall('[A-Za-z]+', template.getvalue()))
370 words -= set(keyword.kwlist)
371 T = namedtuple('T', words)
372 # test __new__
373 values = tuple(range(len(words)))
374 t = T(*values)
375 self.assertEqual(t, values)
376 t = T(**dict(zip(T._fields, values)))
377 self.assertEqual(t, values)
378 # test _make
379 t = T._make(values)
380 self.assertEqual(t, values)
381 # exercise __repr__
382 repr(t)
383 # test _asdict
384 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
385 # test _replace
386 t = T._make(values)
387 newvalues = tuple(v*10 for v in values)
388 newt = t._replace(**dict(zip(T._fields, newvalues)))
389 self.assertEqual(newt, newvalues)
390 # test _fields
391 self.assertEqual(T._fields, tuple(words))
392 # test __getnewargs__
393 self.assertEqual(t.__getnewargs__(), values)
394
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000395 def test_repr(self):
396 with support.captured_stdout() as template:
397 A = namedtuple('A', 'x', verbose=True)
398 self.assertEqual(repr(A(1)), 'A(x=1)')
399 # repr should show the name of the subclass
400 class B(A):
401 pass
402 self.assertEqual(repr(B(1)), 'B(x=1)')
403
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700404 def test_source(self):
405 # verify that _source can be run through exec()
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700406 tmp = namedtuple('NTColor', 'red green blue')
407 globals().pop('NTColor', None) # remove artifacts from other tests
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700408 exec(tmp._source, globals())
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700409 self.assertIn('NTColor', globals())
410 c = NTColor(10, 20, 30)
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700411 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700412 self.assertEqual(NTColor._fields, ('red', 'green', 'blue'))
413 globals().pop('NTColor', None) # clean-up after this test
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700414
Raymond Hettinger6538b432016-08-16 10:55:43 -0700415 def test_keyword_only_arguments(self):
416 # See issue 25628
417 with support.captured_stdout() as template:
418 NT = namedtuple('NT', ['x', 'y'], verbose=True)
419 self.assertIn('class NT', NT._source)
420 with self.assertRaises(TypeError):
421 NT = namedtuple('NT', ['x', 'y'], True)
422
423 NT = namedtuple('NT', ['abc', 'def'], rename=True)
424 self.assertEqual(NT._fields, ('abc', '_1'))
425 with self.assertRaises(TypeError):
426 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000427
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700428 def test_namedtuple_subclass_issue_24931(self):
429 class Point(namedtuple('_Point', ['x', 'y'])):
430 pass
431
432 a = Point(3, 4)
433 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
434
435 a.w = 5
436 self.assertEqual(a.__dict__, {'w': 5})
437
438
Raymond Hettinger499e1932011-02-23 07:56:53 +0000439################################################################################
440### Abstract Base Classes
441################################################################################
442
Raymond Hettingerae650182009-01-28 23:33:59 +0000443class ABCTestCase(unittest.TestCase):
444
445 def validate_abstract_methods(self, abc, *names):
446 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
447
448 # everything should work will all required methods are present
449 C = type('C', (abc,), methodstubs)
450 C()
451
452 # instantiation should fail if a required method is missing
453 for name in names:
454 stubs = methodstubs.copy()
455 del stubs[name]
456 C = type('C', (abc,), stubs)
457 self.assertRaises(TypeError, C, name)
458
Florent Xiclunace153f62010-03-08 15:34:35 +0000459 def validate_isinstance(self, abc, name):
460 stub = lambda s, *args: 0
461
462 C = type('C', (object,), {'__hash__': None})
463 setattr(C, name, stub)
464 self.assertIsInstance(C(), abc)
465 self.assertTrue(issubclass(C, abc))
466
467 C = type('C', (object,), {'__hash__': None})
468 self.assertNotIsInstance(C(), abc)
469 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000470
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000471 def validate_comparison(self, instance):
472 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
473 operators = {}
474 for op in ops:
475 name = '__' + op + '__'
476 operators[name] = getattr(operator, name)
477
478 class Other:
479 def __init__(self):
480 self.right_side = False
481 def __eq__(self, other):
482 self.right_side = True
483 return True
484 __lt__ = __eq__
485 __gt__ = __eq__
486 __le__ = __eq__
487 __ge__ = __eq__
488 __ne__ = __eq__
489 __ror__ = __eq__
490 __rand__ = __eq__
491 __rxor__ = __eq__
492 __rsub__ = __eq__
493
494 for name, op in operators.items():
495 if not hasattr(instance, name):
496 continue
497 other = Other()
498 op(instance, other)
499 self.assertTrue(other.right_side,'Right side not called for %s.%s'
500 % (type(instance), name))
501
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700502def _test_gen():
503 yield
504
Raymond Hettingerae650182009-01-28 23:33:59 +0000505class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000506
Yury Selivanov75445082015-05-11 22:57:16 -0400507 def test_Awaitable(self):
508 def gen():
509 yield
510
511 @types.coroutine
512 def coro():
513 yield
514
515 async def new_coro():
516 pass
517
518 class Bar:
519 def __await__(self):
520 yield
521
522 class MinimalCoro(Coroutine):
523 def send(self, value):
524 return value
525 def throw(self, typ, val=None, tb=None):
526 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400527 def __await__(self):
528 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400529
530 non_samples = [None, int(), gen(), object()]
531 for x in non_samples:
532 self.assertNotIsInstance(x, Awaitable)
533 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
534
535 samples = [Bar(), MinimalCoro()]
536 for x in samples:
537 self.assertIsInstance(x, Awaitable)
538 self.assertTrue(issubclass(type(x), Awaitable))
539
540 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400541 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
542 # flag don't have '__await__' method, hence can't be instances
543 # of Awaitable. Use inspect.isawaitable to detect them.
544 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400545
546 c = new_coro()
547 self.assertIsInstance(c, Awaitable)
548 c.close() # awoid RuntimeWarning that coro() was not awaited
549
Yury Selivanov56fc6142015-05-29 09:01:29 -0400550 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400551 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400552 self.assertTrue(isinstance(CoroLike(), Awaitable))
553 self.assertTrue(issubclass(CoroLike, Awaitable))
554 CoroLike = None
555 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400556
Yury Selivanov75445082015-05-11 22:57:16 -0400557 def test_Coroutine(self):
558 def gen():
559 yield
560
561 @types.coroutine
562 def coro():
563 yield
564
565 async def new_coro():
566 pass
567
568 class Bar:
569 def __await__(self):
570 yield
571
572 class MinimalCoro(Coroutine):
573 def send(self, value):
574 return value
575 def throw(self, typ, val=None, tb=None):
576 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400577 def __await__(self):
578 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400579
580 non_samples = [None, int(), gen(), object(), Bar()]
581 for x in non_samples:
582 self.assertNotIsInstance(x, Coroutine)
583 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
584
585 samples = [MinimalCoro()]
586 for x in samples:
587 self.assertIsInstance(x, Awaitable)
588 self.assertTrue(issubclass(type(x), Awaitable))
589
590 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400591 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
592 # flag don't have '__await__' method, hence can't be instances
593 # of Coroutine. Use inspect.isawaitable to detect them.
594 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400595
596 c = new_coro()
597 self.assertIsInstance(c, Coroutine)
598 c.close() # awoid RuntimeWarning that coro() was not awaited
599
Yury Selivanov56fc6142015-05-29 09:01:29 -0400600 class CoroLike:
601 def send(self, value):
602 pass
603 def throw(self, typ, val=None, tb=None):
604 pass
605 def close(self):
606 pass
607 def __await__(self):
608 pass
609 self.assertTrue(isinstance(CoroLike(), Coroutine))
610 self.assertTrue(issubclass(CoroLike, Coroutine))
611
612 class CoroLike:
613 def send(self, value):
614 pass
615 def close(self):
616 pass
617 def __await__(self):
618 pass
619 self.assertFalse(isinstance(CoroLike(), Coroutine))
620 self.assertFalse(issubclass(CoroLike, Coroutine))
621
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000622 def test_Hashable(self):
623 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000624 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000625 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000626 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000627 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000628 # Check some hashables
629 samples = [None,
630 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000631 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000632 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000633 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000634 ]
635 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000636 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000637 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000638 self.assertRaises(TypeError, Hashable)
639 # Check direct subclassing
640 class H(Hashable):
641 def __hash__(self):
642 return super().__hash__()
643 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000644 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000645 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000646 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000647
Yury Selivanove0104ae2015-05-14 12:19:16 -0400648 def test_AsyncIterable(self):
649 class AI:
650 async def __aiter__(self):
651 return self
652 self.assertTrue(isinstance(AI(), AsyncIterable))
653 self.assertTrue(issubclass(AI, AsyncIterable))
654 # Check some non-iterables
655 non_samples = [None, object, []]
656 for x in non_samples:
657 self.assertNotIsInstance(x, AsyncIterable)
658 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
659 self.validate_abstract_methods(AsyncIterable, '__aiter__')
660 self.validate_isinstance(AsyncIterable, '__aiter__')
661
662 def test_AsyncIterator(self):
663 class AI:
664 async def __aiter__(self):
665 return self
666 async def __anext__(self):
667 raise StopAsyncIteration
668 self.assertTrue(isinstance(AI(), AsyncIterator))
669 self.assertTrue(issubclass(AI, AsyncIterator))
670 non_samples = [None, object, []]
671 # Check some non-iterables
672 for x in non_samples:
673 self.assertNotIsInstance(x, AsyncIterator)
674 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
675 # Similarly to regular iterators (see issue 10565)
676 class AnextOnly:
677 async def __anext__(self):
678 raise StopAsyncIteration
679 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
680 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
681
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000682 def test_Iterable(self):
683 # Check some non-iterables
684 non_samples = [None, 42, 3.14, 1j]
685 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000686 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000687 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000688 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000689 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000690 tuple(), list(), set(), frozenset(), dict(),
691 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700692 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000693 (x for x in []),
694 ]
695 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000696 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000697 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000698 # Check direct subclassing
699 class I(Iterable):
700 def __iter__(self):
701 return super().__iter__()
702 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000703 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000704 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000705 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700706 # Check None blocking
707 class It:
708 def __iter__(self): return iter([])
709 class ItBlocked(It):
710 __iter__ = None
711 self.assertTrue(issubclass(It, Iterable))
712 self.assertTrue(isinstance(It(), Iterable))
713 self.assertFalse(issubclass(ItBlocked, Iterable))
714 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000715
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700716 def test_Reversible(self):
717 # Check some non-reversibles
718 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()]
719 for x in non_samples:
720 self.assertNotIsInstance(x, Reversible)
721 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700722 # Check some non-reversible iterables
723 non_reversibles = [dict().keys(), dict().items(), dict().values(),
724 Counter(), Counter().keys(), Counter().items(),
725 Counter().values(), _test_gen(),
726 (x for x in []), iter([]), reversed([])]
727 for x in non_reversibles:
728 self.assertNotIsInstance(x, Reversible)
729 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
730 # Check some reversible iterables
731 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
732 OrderedDict().keys(), OrderedDict().items(),
733 OrderedDict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700734 for x in samples:
735 self.assertIsInstance(x, Reversible)
736 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
737 # Check also Mapping, MutableMapping, and Sequence
738 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
739 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
740 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
741 # Check direct subclassing
742 class R(Reversible):
743 def __iter__(self):
744 return iter(list())
745 def __reversed__(self):
746 return iter(list())
747 self.assertEqual(list(reversed(R())), [])
748 self.assertFalse(issubclass(float, R))
749 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700750 # Check reversible non-iterable (which is not Reversible)
751 class RevNoIter:
752 def __reversed__(self): return reversed([])
753 class RevPlusIter(RevNoIter):
754 def __iter__(self): return iter([])
755 self.assertFalse(issubclass(RevNoIter, Reversible))
756 self.assertFalse(isinstance(RevNoIter(), Reversible))
757 self.assertTrue(issubclass(RevPlusIter, Reversible))
758 self.assertTrue(isinstance(RevPlusIter(), Reversible))
759 # Check None blocking
760 class Rev:
761 def __iter__(self): return iter([])
762 def __reversed__(self): return reversed([])
763 class RevItBlocked(Rev):
764 __iter__ = None
765 class RevRevBlocked(Rev):
766 __reversed__ = None
767 self.assertTrue(issubclass(Rev, Reversible))
768 self.assertTrue(isinstance(Rev(), Reversible))
769 self.assertFalse(issubclass(RevItBlocked, Reversible))
770 self.assertFalse(isinstance(RevItBlocked(), Reversible))
771 self.assertFalse(issubclass(RevRevBlocked, Reversible))
772 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700773
Guido van Rossumf0666942016-08-23 10:47:07 -0700774 def test_Collection(self):
775 # Check some non-collections
776 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
777 for x in non_collections:
778 self.assertNotIsInstance(x, Collection)
779 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
780 # Check some non-collection iterables
781 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
782 (x for x in []), dict().values()]
783 for x in non_col_iterables:
784 self.assertNotIsInstance(x, Collection)
785 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
786 # Check some collections
787 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
788 list(), dict().keys(), dict().items()]
789 for x in samples:
790 self.assertIsInstance(x, Collection)
791 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
792 # Check also Mapping, MutableMapping, etc.
793 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
794 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
795 self.assertTrue(issubclass(MutableMapping, Collection),
796 repr(MutableMapping))
797 self.assertTrue(issubclass(Set, Collection), repr(Set))
798 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
799 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
800 # Check direct subclassing
801 class Col(Collection):
802 def __iter__(self):
803 return iter(list())
804 def __len__(self):
805 return 0
806 def __contains__(self, item):
807 return False
808 class DerCol(Col): pass
809 self.assertEqual(list(iter(Col())), [])
810 self.assertFalse(issubclass(list, Col))
811 self.assertFalse(issubclass(set, Col))
812 self.assertFalse(issubclass(float, Col))
813 self.assertEqual(list(iter(DerCol())), [])
814 self.assertFalse(issubclass(list, DerCol))
815 self.assertFalse(issubclass(set, DerCol))
816 self.assertFalse(issubclass(float, DerCol))
817 self.validate_abstract_methods(Collection, '__len__', '__iter__',
818 '__contains__')
819 # Check sized container non-iterable (which is not Collection) etc.
820 class ColNoIter:
821 def __len__(self): return 0
822 def __contains__(self, item): return False
823 class ColNoSize:
824 def __iter__(self): return iter([])
825 def __contains__(self, item): return False
826 class ColNoCont:
827 def __iter__(self): return iter([])
828 def __len__(self): return 0
829 self.assertFalse(issubclass(ColNoIter, Collection))
830 self.assertFalse(isinstance(ColNoIter(), Collection))
831 self.assertFalse(issubclass(ColNoSize, Collection))
832 self.assertFalse(isinstance(ColNoSize(), Collection))
833 self.assertFalse(issubclass(ColNoCont, Collection))
834 self.assertFalse(isinstance(ColNoCont(), Collection))
835 # Check None blocking
836 class SizeBlock:
837 def __iter__(self): return iter([])
838 def __contains__(self): return False
839 __len__ = None
840 class IterBlock:
841 def __len__(self): return 0
842 def __contains__(self): return True
843 __iter__ = None
844 self.assertFalse(issubclass(SizeBlock, Collection))
845 self.assertFalse(isinstance(SizeBlock(), Collection))
846 self.assertFalse(issubclass(IterBlock, Collection))
847 self.assertFalse(isinstance(IterBlock(), Collection))
848 # Check None blocking in subclass
849 class ColImpl:
850 def __iter__(self):
851 return iter(list())
852 def __len__(self):
853 return 0
854 def __contains__(self, item):
855 return False
856 class NonCol(ColImpl):
857 __contains__ = None
858 self.assertFalse(issubclass(NonCol, Collection))
859 self.assertFalse(isinstance(NonCol(), Collection))
860
861
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000862 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000863 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000864 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000865 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000866 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000867 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000868 iter(tuple()), iter(list()), iter(dict()),
869 iter(set()), iter(frozenset()),
870 iter(dict().keys()), iter(dict().items()),
871 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700872 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000873 (x for x in []),
874 ]
875 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000876 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000877 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000878 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
879
880 # Issue 10565
881 class NextOnly:
882 def __next__(self):
883 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800884 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000885 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000886
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400887 def test_Generator(self):
888 class NonGen1:
889 def __iter__(self): return self
890 def __next__(self): return None
891 def close(self): pass
892 def throw(self, typ, val=None, tb=None): pass
893
894 class NonGen2:
895 def __iter__(self): return self
896 def __next__(self): return None
897 def close(self): pass
898 def send(self, value): return value
899
900 class NonGen3:
901 def close(self): pass
902 def send(self, value): return value
903 def throw(self, typ, val=None, tb=None): pass
904
905 non_samples = [
906 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
907 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
908 for x in non_samples:
909 self.assertNotIsInstance(x, Generator)
910 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
911
912 class Gen:
913 def __iter__(self): return self
914 def __next__(self): return None
915 def close(self): pass
916 def send(self, value): return value
917 def throw(self, typ, val=None, tb=None): pass
918
919 class MinimalGen(Generator):
920 def send(self, value):
921 return value
922 def throw(self, typ, val=None, tb=None):
923 super().throw(typ, val, tb)
924
925 def gen():
926 yield 1
927
928 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
929 for x in samples:
930 self.assertIsInstance(x, Iterator)
931 self.assertIsInstance(x, Generator)
932 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
933 self.validate_abstract_methods(Generator, 'send', 'throw')
934
935 # mixin tests
936 mgen = MinimalGen()
937 self.assertIs(mgen, iter(mgen))
938 self.assertIs(mgen.send(None), next(mgen))
939 self.assertEqual(2, mgen.send(2))
940 self.assertIsNone(mgen.close())
941 self.assertRaises(ValueError, mgen.throw, ValueError)
942 self.assertRaisesRegex(ValueError, "^huhu$",
943 mgen.throw, ValueError, ValueError("huhu"))
944 self.assertRaises(StopIteration, mgen.throw, StopIteration())
945
946 class FailOnClose(Generator):
947 def send(self, value): return value
948 def throw(self, *args): raise ValueError
949
950 self.assertRaises(ValueError, FailOnClose().close)
951
952 class IgnoreGeneratorExit(Generator):
953 def send(self, value): return value
954 def throw(self, *args): pass
955
956 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
957
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000958 def test_Sized(self):
959 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700960 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000961 (x for x in []),
962 ]
963 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000964 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000965 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000966 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000967 tuple(), list(), set(), frozenset(), dict(),
968 dict().keys(), dict().items(), dict().values(),
969 ]
970 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000971 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000972 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000973 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000974 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000975
976 def test_Container(self):
977 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700978 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000979 (x for x in []),
980 ]
981 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000982 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000983 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000984 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000985 tuple(), list(), set(), frozenset(), dict(),
986 dict().keys(), dict().items(),
987 ]
988 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000989 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000990 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000991 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000992 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000993
994 def test_Callable(self):
995 non_samples = [None, 42, 3.14, 1j,
996 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700997 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000998 (x for x in []),
999 ]
1000 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001001 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001002 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001003 samples = [lambda: None,
1004 type, int, object,
1005 len,
1006 list.append, [].append,
1007 ]
1008 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001009 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001010 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001011 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001012 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001013
1014 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001015 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001016 class C(B):
1017 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001018 self.assertTrue(issubclass(C, B))
1019 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001020
1021 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001022 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001023 class C:
1024 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001025 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001026 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001027 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001028
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001029class WithSet(MutableSet):
1030
1031 def __init__(self, it=()):
1032 self.data = set(it)
1033
1034 def __len__(self):
1035 return len(self.data)
1036
1037 def __iter__(self):
1038 return iter(self.data)
1039
1040 def __contains__(self, item):
1041 return item in self.data
1042
1043 def add(self, item):
1044 self.data.add(item)
1045
1046 def discard(self, item):
1047 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001048
Raymond Hettingerae650182009-01-28 23:33:59 +00001049class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001050
1051 # XXX For now, we only test some virtual inheritance properties.
1052 # We should also test the proper behavior of the collection ABCs
1053 # as real base classes or mix-in classes.
1054
1055 def test_Set(self):
1056 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001057 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001058 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001059 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001060 class MySet(Set):
1061 def __contains__(self, x):
1062 return False
1063 def __len__(self):
1064 return 0
1065 def __iter__(self):
1066 return iter([])
1067 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001068
Benjamin Peterson41181742008-07-02 20:22:54 +00001069 def test_hash_Set(self):
1070 class OneTwoThreeSet(Set):
1071 def __init__(self):
1072 self.contents = [1, 2, 3]
1073 def __contains__(self, x):
1074 return x in self.contents
1075 def __len__(self):
1076 return len(self.contents)
1077 def __iter__(self):
1078 return iter(self.contents)
1079 def __hash__(self):
1080 return self._hash()
1081 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001082 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001083
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001084 def test_isdisjoint_Set(self):
1085 class MySet(Set):
1086 def __init__(self, itr):
1087 self.contents = itr
1088 def __contains__(self, x):
1089 return x in self.contents
1090 def __iter__(self):
1091 return iter(self.contents)
1092 def __len__(self):
1093 return len([x for x in self.contents])
1094 s1 = MySet((1, 2, 3))
1095 s2 = MySet((4, 5, 6))
1096 s3 = MySet((1, 5, 6))
1097 self.assertTrue(s1.isdisjoint(s2))
1098 self.assertFalse(s1.isdisjoint(s3))
1099
1100 def test_equality_Set(self):
1101 class MySet(Set):
1102 def __init__(self, itr):
1103 self.contents = itr
1104 def __contains__(self, x):
1105 return x in self.contents
1106 def __iter__(self):
1107 return iter(self.contents)
1108 def __len__(self):
1109 return len([x for x in self.contents])
1110 s1 = MySet((1,))
1111 s2 = MySet((1, 2))
1112 s3 = MySet((3, 4))
1113 s4 = MySet((3, 4))
1114 self.assertTrue(s2 > s1)
1115 self.assertTrue(s1 < s2)
1116 self.assertFalse(s2 <= s1)
1117 self.assertFalse(s2 <= s3)
1118 self.assertFalse(s1 >= s2)
1119 self.assertEqual(s3, s4)
1120 self.assertNotEqual(s2, s3)
1121
1122 def test_arithmetic_Set(self):
1123 class MySet(Set):
1124 def __init__(self, itr):
1125 self.contents = itr
1126 def __contains__(self, x):
1127 return x in self.contents
1128 def __iter__(self):
1129 return iter(self.contents)
1130 def __len__(self):
1131 return len([x for x in self.contents])
1132 s1 = MySet((1, 2, 3))
1133 s2 = MySet((3, 4, 5))
1134 s3 = s1 & s2
1135 self.assertEqual(s3, MySet((3,)))
1136
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001137 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001138 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001139 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001140 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001141 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001142 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1143 'add', 'discard')
1144
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001145 def test_issue_5647(self):
1146 # MutableSet.__iand__ mutated the set during iteration
1147 s = WithSet('abcd')
1148 s &= WithSet('cdef') # This used to fail
1149 self.assertEqual(set(s), set('cd'))
1150
Raymond Hettingerae650182009-01-28 23:33:59 +00001151 def test_issue_4920(self):
1152 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001153 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001154 __slots__=['__s']
1155 def __init__(self,items=None):
1156 if items is None:
1157 items=[]
1158 self.__s=set(items)
1159 def __contains__(self,v):
1160 return v in self.__s
1161 def __iter__(self):
1162 return iter(self.__s)
1163 def __len__(self):
1164 return len(self.__s)
1165 def add(self,v):
1166 result=v not in self.__s
1167 self.__s.add(v)
1168 return result
1169 def discard(self,v):
1170 result=v in self.__s
1171 self.__s.discard(v)
1172 return result
1173 def __repr__(self):
1174 return "MySet(%s)" % repr(list(self))
1175 s = MySet([5,43,2,1])
1176 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001177
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001178 def test_issue8750(self):
1179 empty = WithSet()
1180 full = WithSet(range(10))
1181 s = WithSet(full)
1182 s -= s
1183 self.assertEqual(s, empty)
1184 s = WithSet(full)
1185 s ^= s
1186 self.assertEqual(s, empty)
1187 s = WithSet(full)
1188 s &= s
1189 self.assertEqual(s, full)
1190 s |= s
1191 self.assertEqual(s, full)
1192
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001193 def test_issue16373(self):
1194 # Recursion error comparing comparable and noncomparable
1195 # Set instances
1196 class MyComparableSet(Set):
1197 def __contains__(self, x):
1198 return False
1199 def __len__(self):
1200 return 0
1201 def __iter__(self):
1202 return iter([])
1203 class MyNonComparableSet(Set):
1204 def __contains__(self, x):
1205 return False
1206 def __len__(self):
1207 return 0
1208 def __iter__(self):
1209 return iter([])
1210 def __le__(self, x):
1211 return NotImplemented
1212 def __lt__(self, x):
1213 return NotImplemented
1214
1215 cs = MyComparableSet()
1216 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001217 self.assertFalse(ncs < cs)
1218 self.assertTrue(ncs <= cs)
1219 self.assertFalse(ncs > cs)
1220 self.assertTrue(ncs >= cs)
1221
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001222 def test_issue26915(self):
1223 # Container membership test should check identity first
1224 class CustomEqualObject:
1225 def __eq__(self, other):
1226 return False
1227 class CustomSequence(list):
1228 def __contains__(self, value):
1229 return Sequence.__contains__(self, value)
1230
1231 nan = float('nan')
1232 obj = CustomEqualObject()
1233 containers = [
1234 CustomSequence([nan, obj]),
1235 ItemsView({1: nan, 2: obj}),
1236 ValuesView({1: nan, 2: obj})
1237 ]
1238 for container in containers:
1239 for elem in container:
1240 self.assertIn(elem, container)
1241
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001242 def assertSameSet(self, s1, s2):
1243 # coerce both to a real set then check equality
1244 self.assertSetEqual(set(s1), set(s2))
1245
1246 def test_Set_interoperability_with_real_sets(self):
1247 # Issue: 8743
1248 class ListSet(Set):
1249 def __init__(self, elements=()):
1250 self.data = []
1251 for elem in elements:
1252 if elem not in self.data:
1253 self.data.append(elem)
1254 def __contains__(self, elem):
1255 return elem in self.data
1256 def __iter__(self):
1257 return iter(self.data)
1258 def __len__(self):
1259 return len(self.data)
1260 def __repr__(self):
1261 return 'Set({!r})'.format(self.data)
1262
1263 r1 = set('abc')
1264 r2 = set('bcd')
1265 r3 = set('abcde')
1266 f1 = ListSet('abc')
1267 f2 = ListSet('bcd')
1268 f3 = ListSet('abcde')
1269 l1 = list('abccba')
1270 l2 = list('bcddcb')
1271 l3 = list('abcdeedcba')
1272
1273 target = r1 & r2
1274 self.assertSameSet(f1 & f2, target)
1275 self.assertSameSet(f1 & r2, target)
1276 self.assertSameSet(r2 & f1, target)
1277 self.assertSameSet(f1 & l2, target)
1278
1279 target = r1 | r2
1280 self.assertSameSet(f1 | f2, target)
1281 self.assertSameSet(f1 | r2, target)
1282 self.assertSameSet(r2 | f1, target)
1283 self.assertSameSet(f1 | l2, target)
1284
1285 fwd_target = r1 - r2
1286 rev_target = r2 - r1
1287 self.assertSameSet(f1 - f2, fwd_target)
1288 self.assertSameSet(f2 - f1, rev_target)
1289 self.assertSameSet(f1 - r2, fwd_target)
1290 self.assertSameSet(f2 - r1, rev_target)
1291 self.assertSameSet(r1 - f2, fwd_target)
1292 self.assertSameSet(r2 - f1, rev_target)
1293 self.assertSameSet(f1 - l2, fwd_target)
1294 self.assertSameSet(f2 - l1, rev_target)
1295
1296 target = r1 ^ r2
1297 self.assertSameSet(f1 ^ f2, target)
1298 self.assertSameSet(f1 ^ r2, target)
1299 self.assertSameSet(r2 ^ f1, target)
1300 self.assertSameSet(f1 ^ l2, target)
1301
1302 # Don't change the following to use assertLess or other
1303 # "more specific" unittest assertions. The current
1304 # assertTrue/assertFalse style makes the pattern of test
1305 # case combinations clear and allows us to know for sure
1306 # the exact operator being invoked.
1307
1308 # proper subset
1309 self.assertTrue(f1 < f3)
1310 self.assertFalse(f1 < f1)
1311 self.assertFalse(f1 < f2)
1312 self.assertTrue(r1 < f3)
1313 self.assertFalse(r1 < f1)
1314 self.assertFalse(r1 < f2)
1315 self.assertTrue(r1 < r3)
1316 self.assertFalse(r1 < r1)
1317 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001318 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001319 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001320 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001321 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001322 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001323 f1 < l2
1324
1325 # any subset
1326 self.assertTrue(f1 <= f3)
1327 self.assertTrue(f1 <= f1)
1328 self.assertFalse(f1 <= f2)
1329 self.assertTrue(r1 <= f3)
1330 self.assertTrue(r1 <= f1)
1331 self.assertFalse(r1 <= f2)
1332 self.assertTrue(r1 <= r3)
1333 self.assertTrue(r1 <= r1)
1334 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001335 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001336 f1 <= l3
1337 with self.assertRaises(TypeError):
1338 f1 <= l1
1339 with self.assertRaises(TypeError):
1340 f1 <= l2
1341
1342 # proper superset
1343 self.assertTrue(f3 > f1)
1344 self.assertFalse(f1 > f1)
1345 self.assertFalse(f2 > f1)
1346 self.assertTrue(r3 > r1)
1347 self.assertFalse(f1 > r1)
1348 self.assertFalse(f2 > r1)
1349 self.assertTrue(r3 > r1)
1350 self.assertFalse(r1 > r1)
1351 self.assertFalse(r2 > r1)
1352 with self.assertRaises(TypeError):
1353 f1 > l3
1354 with self.assertRaises(TypeError):
1355 f1 > l1
1356 with self.assertRaises(TypeError):
1357 f1 > l2
1358
1359 # any superset
1360 self.assertTrue(f3 >= f1)
1361 self.assertTrue(f1 >= f1)
1362 self.assertFalse(f2 >= f1)
1363 self.assertTrue(r3 >= r1)
1364 self.assertTrue(f1 >= r1)
1365 self.assertFalse(f2 >= r1)
1366 self.assertTrue(r3 >= r1)
1367 self.assertTrue(r1 >= r1)
1368 self.assertFalse(r2 >= r1)
1369 with self.assertRaises(TypeError):
1370 f1 >= l3
1371 with self.assertRaises(TypeError):
1372 f1 >=l1
1373 with self.assertRaises(TypeError):
1374 f1 >= l2
1375
1376 # equality
1377 self.assertTrue(f1 == f1)
1378 self.assertTrue(r1 == f1)
1379 self.assertTrue(f1 == r1)
1380 self.assertFalse(f1 == f3)
1381 self.assertFalse(r1 == f3)
1382 self.assertFalse(f1 == r3)
1383 self.assertFalse(f1 == l3)
1384 self.assertFalse(f1 == l1)
1385 self.assertFalse(f1 == l2)
1386
1387 # inequality
1388 self.assertFalse(f1 != f1)
1389 self.assertFalse(r1 != f1)
1390 self.assertFalse(f1 != r1)
1391 self.assertTrue(f1 != f3)
1392 self.assertTrue(r1 != f3)
1393 self.assertTrue(f1 != r3)
1394 self.assertTrue(f1 != l3)
1395 self.assertTrue(f1 != l1)
1396 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001397
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001398 def test_Mapping(self):
1399 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001400 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001401 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001402 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1403 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001404 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001405 def __len__(self):
1406 return 0
1407 def __getitem__(self, i):
1408 raise IndexError
1409 def __iter__(self):
1410 return iter(())
1411 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001412 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001413
1414 def test_MutableMapping(self):
1415 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001416 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001417 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001418 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1419 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001420
Raymond Hettinger9117c752010-08-22 07:44:24 +00001421 def test_MutableMapping_subclass(self):
1422 # Test issue 9214
1423 mymap = UserDict()
1424 mymap['red'] = 5
1425 self.assertIsInstance(mymap.keys(), Set)
1426 self.assertIsInstance(mymap.keys(), KeysView)
1427 self.assertIsInstance(mymap.items(), Set)
1428 self.assertIsInstance(mymap.items(), ItemsView)
1429
1430 mymap = UserDict()
1431 mymap['red'] = 5
1432 z = mymap.keys() | {'orange'}
1433 self.assertIsInstance(z, set)
1434 list(z)
1435 mymap['blue'] = 7 # Shouldn't affect 'z'
1436 self.assertEqual(sorted(z), ['orange', 'red'])
1437
1438 mymap = UserDict()
1439 mymap['red'] = 5
1440 z = mymap.items() | {('orange', 3)}
1441 self.assertIsInstance(z, set)
1442 list(z)
1443 mymap['blue'] = 7 # Shouldn't affect 'z'
1444 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1445
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001446 def test_Sequence(self):
1447 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001448 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001449 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001450 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001451 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001452 self.assertIsInstance(memoryview(b""), Sequence)
1453 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001454 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001455 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1456 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001457
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001458 def test_Sequence_mixins(self):
1459 class SequenceSubclass(Sequence):
1460 def __init__(self, seq=()):
1461 self.seq = seq
1462
1463 def __getitem__(self, index):
1464 return self.seq[index]
1465
1466 def __len__(self):
1467 return len(self.seq)
1468
1469 # Compare Sequence.index() behavior to (list|str).index() behavior
1470 def assert_index_same(seq1, seq2, index_args):
1471 try:
1472 expected = seq1.index(*index_args)
1473 except ValueError:
1474 with self.assertRaises(ValueError):
1475 seq2.index(*index_args)
1476 else:
1477 actual = seq2.index(*index_args)
1478 self.assertEqual(
1479 actual, expected, '%r.index%s' % (seq1, index_args))
1480
1481 for ty in list, str:
1482 nativeseq = ty('abracadabra')
1483 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1484 seqseq = SequenceSubclass(nativeseq)
1485 for letter in set(nativeseq) | {'z'}:
1486 assert_index_same(nativeseq, seqseq, (letter,))
1487 for start in range(-3, len(nativeseq) + 3):
1488 assert_index_same(nativeseq, seqseq, (letter, start))
1489 for stop in range(-3, len(nativeseq) + 3):
1490 assert_index_same(
1491 nativeseq, seqseq, (letter, start, stop))
1492
Guido van Rossumd05eb002007-11-21 22:26:24 +00001493 def test_ByteString(self):
1494 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001495 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001496 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001497 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001498 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001499 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001500 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001501 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001502
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001503 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001504 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001505 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001506 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001507 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001508 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001509 self.assertTrue(issubclass(sample, MutableSequence))
1510 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001511 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1512 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001513
Eli Bendersky0716a572011-03-04 10:38:14 +00001514 def test_MutableSequence_mixins(self):
1515 # Test the mixins of MutableSequence by creating a miminal concrete
1516 # class inherited from it.
1517 class MutableSequenceSubclass(MutableSequence):
1518 def __init__(self):
1519 self.lst = []
1520
1521 def __setitem__(self, index, value):
1522 self.lst[index] = value
1523
1524 def __getitem__(self, index):
1525 return self.lst[index]
1526
1527 def __len__(self):
1528 return len(self.lst)
1529
1530 def __delitem__(self, index):
1531 del self.lst[index]
1532
1533 def insert(self, index, value):
1534 self.lst.insert(index, value)
1535
1536 mss = MutableSequenceSubclass()
1537 mss.append(0)
1538 mss.extend((1, 2, 3, 4))
1539 self.assertEqual(len(mss), 5)
1540 self.assertEqual(mss[3], 3)
1541 mss.reverse()
1542 self.assertEqual(mss[3], 1)
1543 mss.pop()
1544 self.assertEqual(len(mss), 4)
1545 mss.remove(3)
1546 self.assertEqual(len(mss), 3)
1547 mss += (10, 20, 30)
1548 self.assertEqual(len(mss), 6)
1549 self.assertEqual(mss[-1], 30)
1550 mss.clear()
1551 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001552
1553################################################################################
1554### Counter
1555################################################################################
1556
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001557class CounterSubclassWithSetItem(Counter):
1558 # Test a counter subclass that overrides __setitem__
1559 def __init__(self, *args, **kwds):
1560 self.called = False
1561 Counter.__init__(self, *args, **kwds)
1562 def __setitem__(self, key, value):
1563 self.called = True
1564 Counter.__setitem__(self, key, value)
1565
1566class CounterSubclassWithGet(Counter):
1567 # Test a counter subclass that overrides get()
1568 def __init__(self, *args, **kwds):
1569 self.called = False
1570 Counter.__init__(self, *args, **kwds)
1571 def get(self, key, default):
1572 self.called = True
1573 return Counter.get(self, key, default)
1574
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001575class TestCounter(unittest.TestCase):
1576
1577 def test_basics(self):
1578 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001579 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1580 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001581 self.assertIsInstance(c, dict)
1582 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001583 self.assertTrue(issubclass(Counter, dict))
1584 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001585 self.assertEqual(len(c), 3)
1586 self.assertEqual(sum(c.values()), 6)
1587 self.assertEqual(sorted(c.values()), [1, 2, 3])
1588 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1589 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1590 self.assertEqual(sorted(c.items()),
1591 [('a', 3), ('b', 2), ('c', 1)])
1592 self.assertEqual(c['b'], 2)
1593 self.assertEqual(c['z'], 0)
1594 self.assertEqual(c.__contains__('c'), True)
1595 self.assertEqual(c.__contains__('z'), False)
1596 self.assertEqual(c.get('b', 10), 2)
1597 self.assertEqual(c.get('z', 10), 10)
1598 self.assertEqual(c, dict(a=3, b=2, c=1))
1599 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1600 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1601 for i in range(5):
1602 self.assertEqual(c.most_common(i),
1603 [('a', 3), ('b', 2), ('c', 1)][:i])
1604 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1605 c['a'] += 1 # increment an existing value
1606 c['b'] -= 2 # sub existing value to zero
1607 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001608 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001609 c['d'] -= 2 # sub from a missing value
1610 c['e'] = -5 # directly assign a missing value
1611 c['f'] += 4 # add to a missing value
1612 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1613 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1614 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001615 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001616 for i in range(3):
1617 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001618 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001619 c.clear()
1620 self.assertEqual(c, {})
1621 self.assertEqual(repr(c), 'Counter()')
1622 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1623 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001624 c.update(dict(a=5, b=3))
1625 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001626 c.update(Counter('a' * 50 + 'b' * 30))
1627 c.update() # test case with no args
1628 c.__init__('a' * 500 + 'b' * 300)
1629 c.__init__('cdc')
1630 c.__init__()
1631 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1632 self.assertEqual(c.setdefault('d', 5), 1)
1633 self.assertEqual(c['d'], 1)
1634 self.assertEqual(c.setdefault('e', 5), 5)
1635 self.assertEqual(c['e'], 5)
1636
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001637 def test_init(self):
1638 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1639 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1640 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1641 self.assertRaises(TypeError, Counter, 42)
1642 self.assertRaises(TypeError, Counter, (), ())
1643 self.assertRaises(TypeError, Counter.__init__)
1644
1645 def test_update(self):
1646 c = Counter()
1647 c.update(self=42)
1648 self.assertEqual(list(c.items()), [('self', 42)])
1649 c = Counter()
1650 c.update(iterable=42)
1651 self.assertEqual(list(c.items()), [('iterable', 42)])
1652 c = Counter()
1653 c.update(iterable=None)
1654 self.assertEqual(list(c.items()), [('iterable', None)])
1655 self.assertRaises(TypeError, Counter().update, 42)
1656 self.assertRaises(TypeError, Counter().update, {}, {})
1657 self.assertRaises(TypeError, Counter.update)
1658
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001659 def test_copying(self):
1660 # Check that counters are copyable, deepcopyable, picklable, and
1661 #have a repr/eval round-trip
1662 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001663 def check(dup):
1664 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1665 self.assertIsNot(dup, words, msg)
1666 self.assertEqual(dup, words)
1667 check(words.copy())
1668 check(copy.copy(words))
1669 check(copy.deepcopy(words))
1670 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1671 with self.subTest(proto=proto):
1672 check(pickle.loads(pickle.dumps(words, proto)))
1673 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001674 update_test = Counter()
1675 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001676 check(update_test)
1677 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001678
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001679 def test_copy_subclass(self):
1680 class MyCounter(Counter):
1681 pass
1682 c = MyCounter('slartibartfast')
1683 d = c.copy()
1684 self.assertEqual(d, c)
1685 self.assertEqual(len(d), len(c))
1686 self.assertEqual(type(d), type(c))
1687
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001688 def test_conversions(self):
1689 # Convert to: set, list, dict
1690 s = 'she sells sea shells by the sea shore'
1691 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1692 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1693 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1694 self.assertEqual(set(Counter(s)), set(s))
1695
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001696 def test_invariant_for_the_in_operator(self):
1697 c = Counter(a=10, b=-2, c=0)
1698 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001699 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001700 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001701
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001702 def test_multiset_operations(self):
1703 # Verify that adding a zero counter will strip zeros and negatives
1704 c = Counter(a=10, b=-2, c=0) + Counter()
1705 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001706
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001707 elements = 'abcd'
1708 for i in range(1000):
1709 # test random pairs of multisets
1710 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001711 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001712 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001713 q.update(h=1, i=-1, j=0)
1714 for counterop, numberop in [
1715 (Counter.__add__, lambda x, y: max(0, x+y)),
1716 (Counter.__sub__, lambda x, y: max(0, x-y)),
1717 (Counter.__or__, lambda x, y: max(0,x,y)),
1718 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001719 ]:
1720 result = counterop(p, q)
1721 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001722 self.assertEqual(numberop(p[x], q[x]), result[x],
1723 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001724 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001725 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001726
1727 elements = 'abcdef'
1728 for i in range(100):
1729 # verify that random multisets with no repeats are exactly like sets
1730 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1731 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1732 for counterop, setop in [
1733 (Counter.__sub__, set.__sub__),
1734 (Counter.__or__, set.__or__),
1735 (Counter.__and__, set.__and__),
1736 ]:
1737 counter_result = counterop(p, q)
1738 set_result = setop(set(p.elements()), set(q.elements()))
1739 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001740
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001741 def test_inplace_operations(self):
1742 elements = 'abcd'
1743 for i in range(1000):
1744 # test random pairs of multisets
1745 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1746 p.update(e=1, f=-1, g=0)
1747 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1748 q.update(h=1, i=-1, j=0)
1749 for inplace_op, regular_op in [
1750 (Counter.__iadd__, Counter.__add__),
1751 (Counter.__isub__, Counter.__sub__),
1752 (Counter.__ior__, Counter.__or__),
1753 (Counter.__iand__, Counter.__and__),
1754 ]:
1755 c = p.copy()
1756 c_id = id(c)
1757 regular_result = regular_op(c, q)
1758 inplace_result = inplace_op(c, q)
1759 self.assertEqual(inplace_result, regular_result)
1760 self.assertEqual(id(inplace_result), c_id)
1761
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001762 def test_subtract(self):
1763 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1764 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1765 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1766 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1767 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1768 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1769 c = Counter('aaabbcd')
1770 c.subtract('aaaabbcce')
1771 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001772
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001773 c = Counter()
1774 c.subtract(self=42)
1775 self.assertEqual(list(c.items()), [('self', -42)])
1776 c = Counter()
1777 c.subtract(iterable=42)
1778 self.assertEqual(list(c.items()), [('iterable', -42)])
1779 self.assertRaises(TypeError, Counter().subtract, 42)
1780 self.assertRaises(TypeError, Counter().subtract, {}, {})
1781 self.assertRaises(TypeError, Counter.subtract)
1782
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001783 def test_unary(self):
1784 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1785 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1786 self.assertEqual(dict(-c), dict(a=5))
1787
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001788 def test_repr_nonsortable(self):
1789 c = Counter(a=2, b=None)
1790 r = repr(c)
1791 self.assertIn("'a': 2", r)
1792 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001793
Raymond Hettinger426e0522011-01-03 02:12:02 +00001794 def test_helper_function(self):
1795 # two paths, one for real dicts and one for other mappings
1796 elems = list('abracadabra')
1797
1798 d = dict()
1799 _count_elements(d, elems)
1800 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1801
1802 m = OrderedDict()
1803 _count_elements(m, elems)
1804 self.assertEqual(m,
1805 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1806
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001807 # test fidelity to the pure python version
1808 c = CounterSubclassWithSetItem('abracadabra')
1809 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001810 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001811 c = CounterSubclassWithGet('abracadabra')
1812 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001813 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001814
Raymond Hettinger499e1932011-02-23 07:56:53 +00001815
1816################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001817### Run tests
1818################################################################################
1819
Guido van Rossumd8faa362007-04-27 19:54:29 +00001820def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001821 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001822 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001823 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06001824 TestUserObjects,
1825 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001826 support.run_unittest(*test_classes)
1827 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001828
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001829
Guido van Rossumd8faa362007-04-27 19:54:29 +00001830if __name__ == "__main__":
1831 test_main(verbose=True)