blob: 52ff256eb9438b526447282bd8b364e314ab39a5 [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
Raymond Hettinger0d5048c2016-09-12 00:18:31 -0700245 def test_module_parameter(self):
246 NT = namedtuple('NT', ['x', 'y'], module=collections)
247 self.assertEqual(NT.__module__, collections)
248
Guido van Rossumd8faa362007-04-27 19:54:29 +0000249 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000250 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000251 p = Point(11, 22)
252 self.assertEqual(p, Point(x=11, y=22))
253 self.assertEqual(p, Point(11, y=22))
254 self.assertEqual(p, Point(y=22, x=11))
255 self.assertEqual(p, Point(*(11, 22)))
256 self.assertEqual(p, Point(**dict(x=11, y=22)))
257 self.assertRaises(TypeError, Point, 1) # too few args
258 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
259 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
260 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
261 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000262 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000263 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000264 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
265 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700266 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000267
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000268 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000269 p._replace(x=1, error=2)
270 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000271 pass
272 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000273 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000274
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000275 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000276 Point = namedtuple('Point', 'x, y')
277 p = Point(x=11, y=22)
278 self.assertEqual(repr(p), 'Point(x=11, y=22)')
279
280 # verify that fieldspec can be a non-string sequence
281 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000282 p = Point(x=11, y=22)
283 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000284
285 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000286 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000287 p = Point(11, 22)
288
Ezio Melottie9615932010-01-24 19:26:24 +0000289 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000290 self.assertEqual(p, (11, 22)) # matches a real tuple
291 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
292 self.assertEqual(list(p), [11, 22]) # coercable to a list
293 self.assertEqual(max(p), 22) # iterable
294 self.assertEqual(max(*p), 22) # star-able
295 x, y = p
296 self.assertEqual(p, (x, y)) # unpacks like a tuple
297 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
298 self.assertRaises(IndexError, p.__getitem__, 3)
299
300 self.assertEqual(p.x, x)
301 self.assertEqual(p.y, y)
302 self.assertRaises(AttributeError, eval, 'p.z', locals())
303
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000304 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000305 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000306 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000307 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000308 self.assertEqual(repr(Zero()), 'Zero()')
309 self.assertEqual(Zero()._asdict(), {})
310 self.assertEqual(Zero()._fields, ())
311
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000312 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000313 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000314 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000315 self.assertEqual(Dot(1).d, 1)
316 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
317 self.assertEqual(Dot(1)._asdict(), {'d':1})
318 self.assertEqual(Dot(1)._replace(d=999), (999,))
319 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000320
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000321 # n = 5000
Christian Heimes99170a52007-12-19 02:07:34 +0000322 n = 254 # SyntaxError: more than 255 arguments:
Serhiy Storchaka33e7ea52015-11-25 17:09:01 +0200323 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandlb533e262008-05-25 18:19:30 +0000324 for j in range(10)]) for i in range(n)))
325 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000326 Big = namedtuple('Big', names)
327 b = Big(*range(n))
328 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000329 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000330 for pos, name in enumerate(names):
331 self.assertEqual(getattr(b, name), pos)
332 repr(b) # make sure repr() doesn't blow-up
333 d = b._asdict()
334 d_expected = dict(zip(names, range(n)))
335 self.assertEqual(d, d_expected)
336 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
337 b2_expected = list(range(n))
338 b2_expected[1] = 999
339 b2_expected[-5] = 42
340 self.assertEqual(b2, tuple(b2_expected))
341 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000342
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000343 def test_pickle(self):
344 p = TestNT(x=10, y=20, z=30)
345 for module in (pickle,):
346 loads = getattr(module, 'loads')
347 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500348 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000349 q = loads(dumps(p, protocol))
350 self.assertEqual(p, q)
351 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700352 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000353
354 def test_copy(self):
355 p = TestNT(x=10, y=20, z=30)
356 for copier in copy.copy, copy.deepcopy:
357 q = copier(p)
358 self.assertEqual(p, q)
359 self.assertEqual(p._fields, q._fields)
360
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000361 def test_name_conflicts(self):
362 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
363 # failed when used as field names. Test to make sure these now work.
364 T = namedtuple('T', 'itemgetter property self cls tuple')
365 t = T(1, 2, 3, 4, 5)
366 self.assertEqual(t, (1,2,3,4,5))
367 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
368 self.assertEqual(newt, (10,20,30,40,50))
369
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000370 # Broader test of all interesting names in a template
371 with support.captured_stdout() as template:
372 T = namedtuple('T', 'x', verbose=True)
373 words = set(re.findall('[A-Za-z]+', template.getvalue()))
374 words -= set(keyword.kwlist)
375 T = namedtuple('T', words)
376 # test __new__
377 values = tuple(range(len(words)))
378 t = T(*values)
379 self.assertEqual(t, values)
380 t = T(**dict(zip(T._fields, values)))
381 self.assertEqual(t, values)
382 # test _make
383 t = T._make(values)
384 self.assertEqual(t, values)
385 # exercise __repr__
386 repr(t)
387 # test _asdict
388 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
389 # test _replace
390 t = T._make(values)
391 newvalues = tuple(v*10 for v in values)
392 newt = t._replace(**dict(zip(T._fields, newvalues)))
393 self.assertEqual(newt, newvalues)
394 # test _fields
395 self.assertEqual(T._fields, tuple(words))
396 # test __getnewargs__
397 self.assertEqual(t.__getnewargs__(), values)
398
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000399 def test_repr(self):
400 with support.captured_stdout() as template:
401 A = namedtuple('A', 'x', verbose=True)
402 self.assertEqual(repr(A(1)), 'A(x=1)')
403 # repr should show the name of the subclass
404 class B(A):
405 pass
406 self.assertEqual(repr(B(1)), 'B(x=1)')
407
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700408 def test_source(self):
409 # verify that _source can be run through exec()
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700410 tmp = namedtuple('NTColor', 'red green blue')
411 globals().pop('NTColor', None) # remove artifacts from other tests
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700412 exec(tmp._source, globals())
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700413 self.assertIn('NTColor', globals())
414 c = NTColor(10, 20, 30)
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700415 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700416 self.assertEqual(NTColor._fields, ('red', 'green', 'blue'))
417 globals().pop('NTColor', None) # clean-up after this test
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700418
Raymond Hettinger6538b432016-08-16 10:55:43 -0700419 def test_keyword_only_arguments(self):
420 # See issue 25628
421 with support.captured_stdout() as template:
422 NT = namedtuple('NT', ['x', 'y'], verbose=True)
423 self.assertIn('class NT', NT._source)
424 with self.assertRaises(TypeError):
425 NT = namedtuple('NT', ['x', 'y'], True)
426
427 NT = namedtuple('NT', ['abc', 'def'], rename=True)
428 self.assertEqual(NT._fields, ('abc', '_1'))
429 with self.assertRaises(TypeError):
430 NT = namedtuple('NT', ['abc', 'def'], False, True)
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000431
Raymond Hettinger7a3602e2015-08-30 09:13:48 -0700432 def test_namedtuple_subclass_issue_24931(self):
433 class Point(namedtuple('_Point', ['x', 'y'])):
434 pass
435
436 a = Point(3, 4)
437 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
438
439 a.w = 5
440 self.assertEqual(a.__dict__, {'w': 5})
441
442
Raymond Hettinger499e1932011-02-23 07:56:53 +0000443################################################################################
444### Abstract Base Classes
445################################################################################
446
Raymond Hettingerae650182009-01-28 23:33:59 +0000447class ABCTestCase(unittest.TestCase):
448
449 def validate_abstract_methods(self, abc, *names):
450 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
451
452 # everything should work will all required methods are present
453 C = type('C', (abc,), methodstubs)
454 C()
455
456 # instantiation should fail if a required method is missing
457 for name in names:
458 stubs = methodstubs.copy()
459 del stubs[name]
460 C = type('C', (abc,), stubs)
461 self.assertRaises(TypeError, C, name)
462
Florent Xiclunace153f62010-03-08 15:34:35 +0000463 def validate_isinstance(self, abc, name):
464 stub = lambda s, *args: 0
465
466 C = type('C', (object,), {'__hash__': None})
467 setattr(C, name, stub)
468 self.assertIsInstance(C(), abc)
469 self.assertTrue(issubclass(C, abc))
470
471 C = type('C', (object,), {'__hash__': None})
472 self.assertNotIsInstance(C(), abc)
473 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000474
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000475 def validate_comparison(self, instance):
476 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
477 operators = {}
478 for op in ops:
479 name = '__' + op + '__'
480 operators[name] = getattr(operator, name)
481
482 class Other:
483 def __init__(self):
484 self.right_side = False
485 def __eq__(self, other):
486 self.right_side = True
487 return True
488 __lt__ = __eq__
489 __gt__ = __eq__
490 __le__ = __eq__
491 __ge__ = __eq__
492 __ne__ = __eq__
493 __ror__ = __eq__
494 __rand__ = __eq__
495 __rxor__ = __eq__
496 __rsub__ = __eq__
497
498 for name, op in operators.items():
499 if not hasattr(instance, name):
500 continue
501 other = Other()
502 op(instance, other)
503 self.assertTrue(other.right_side,'Right side not called for %s.%s'
504 % (type(instance), name))
505
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700506def _test_gen():
507 yield
508
Raymond Hettingerae650182009-01-28 23:33:59 +0000509class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000510
Yury Selivanov75445082015-05-11 22:57:16 -0400511 def test_Awaitable(self):
512 def gen():
513 yield
514
515 @types.coroutine
516 def coro():
517 yield
518
519 async def new_coro():
520 pass
521
522 class Bar:
523 def __await__(self):
524 yield
525
526 class MinimalCoro(Coroutine):
527 def send(self, value):
528 return value
529 def throw(self, typ, val=None, tb=None):
530 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400531 def __await__(self):
532 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400533
534 non_samples = [None, int(), gen(), object()]
535 for x in non_samples:
536 self.assertNotIsInstance(x, Awaitable)
537 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
538
539 samples = [Bar(), MinimalCoro()]
540 for x in samples:
541 self.assertIsInstance(x, Awaitable)
542 self.assertTrue(issubclass(type(x), Awaitable))
543
544 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400545 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
546 # flag don't have '__await__' method, hence can't be instances
547 # of Awaitable. Use inspect.isawaitable to detect them.
548 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400549
550 c = new_coro()
551 self.assertIsInstance(c, Awaitable)
552 c.close() # awoid RuntimeWarning that coro() was not awaited
553
Yury Selivanov56fc6142015-05-29 09:01:29 -0400554 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400555 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400556 self.assertTrue(isinstance(CoroLike(), Awaitable))
557 self.assertTrue(issubclass(CoroLike, Awaitable))
558 CoroLike = None
559 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400560
Yury Selivanov75445082015-05-11 22:57:16 -0400561 def test_Coroutine(self):
562 def gen():
563 yield
564
565 @types.coroutine
566 def coro():
567 yield
568
569 async def new_coro():
570 pass
571
572 class Bar:
573 def __await__(self):
574 yield
575
576 class MinimalCoro(Coroutine):
577 def send(self, value):
578 return value
579 def throw(self, typ, val=None, tb=None):
580 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400581 def __await__(self):
582 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400583
584 non_samples = [None, int(), gen(), object(), Bar()]
585 for x in non_samples:
586 self.assertNotIsInstance(x, Coroutine)
587 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
588
589 samples = [MinimalCoro()]
590 for x in samples:
591 self.assertIsInstance(x, Awaitable)
592 self.assertTrue(issubclass(type(x), Awaitable))
593
594 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400595 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
596 # flag don't have '__await__' method, hence can't be instances
597 # of Coroutine. Use inspect.isawaitable to detect them.
598 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400599
600 c = new_coro()
601 self.assertIsInstance(c, Coroutine)
602 c.close() # awoid RuntimeWarning that coro() was not awaited
603
Yury Selivanov56fc6142015-05-29 09:01:29 -0400604 class CoroLike:
605 def send(self, value):
606 pass
607 def throw(self, typ, val=None, tb=None):
608 pass
609 def close(self):
610 pass
611 def __await__(self):
612 pass
613 self.assertTrue(isinstance(CoroLike(), Coroutine))
614 self.assertTrue(issubclass(CoroLike, Coroutine))
615
616 class CoroLike:
617 def send(self, value):
618 pass
619 def close(self):
620 pass
621 def __await__(self):
622 pass
623 self.assertFalse(isinstance(CoroLike(), Coroutine))
624 self.assertFalse(issubclass(CoroLike, Coroutine))
625
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000626 def test_Hashable(self):
627 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000628 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000629 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000630 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000631 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000632 # Check some hashables
633 samples = [None,
634 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000635 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000636 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000637 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000638 ]
639 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000640 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000641 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000642 self.assertRaises(TypeError, Hashable)
643 # Check direct subclassing
644 class H(Hashable):
645 def __hash__(self):
646 return super().__hash__()
647 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000648 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000649 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000650 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000651
Yury Selivanove0104ae2015-05-14 12:19:16 -0400652 def test_AsyncIterable(self):
653 class AI:
654 async def __aiter__(self):
655 return self
656 self.assertTrue(isinstance(AI(), AsyncIterable))
657 self.assertTrue(issubclass(AI, AsyncIterable))
658 # Check some non-iterables
659 non_samples = [None, object, []]
660 for x in non_samples:
661 self.assertNotIsInstance(x, AsyncIterable)
662 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
663 self.validate_abstract_methods(AsyncIterable, '__aiter__')
664 self.validate_isinstance(AsyncIterable, '__aiter__')
665
666 def test_AsyncIterator(self):
667 class AI:
668 async def __aiter__(self):
669 return self
670 async def __anext__(self):
671 raise StopAsyncIteration
672 self.assertTrue(isinstance(AI(), AsyncIterator))
673 self.assertTrue(issubclass(AI, AsyncIterator))
674 non_samples = [None, object, []]
675 # Check some non-iterables
676 for x in non_samples:
677 self.assertNotIsInstance(x, AsyncIterator)
678 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
679 # Similarly to regular iterators (see issue 10565)
680 class AnextOnly:
681 async def __anext__(self):
682 raise StopAsyncIteration
683 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
684 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
685
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000686 def test_Iterable(self):
687 # Check some non-iterables
688 non_samples = [None, 42, 3.14, 1j]
689 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000690 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000691 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000692 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000693 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000694 tuple(), list(), set(), frozenset(), dict(),
695 dict().keys(), dict().items(), dict().values(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700696 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000697 (x for x in []),
698 ]
699 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000700 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000701 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000702 # Check direct subclassing
703 class I(Iterable):
704 def __iter__(self):
705 return super().__iter__()
706 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000707 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000708 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000709 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700710 # Check None blocking
711 class It:
712 def __iter__(self): return iter([])
713 class ItBlocked(It):
714 __iter__ = None
715 self.assertTrue(issubclass(It, Iterable))
716 self.assertTrue(isinstance(It(), Iterable))
717 self.assertFalse(issubclass(ItBlocked, Iterable))
718 self.assertFalse(isinstance(ItBlocked(), Iterable))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000719
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700720 def test_Reversible(self):
721 # Check some non-reversibles
722 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()]
723 for x in non_samples:
724 self.assertNotIsInstance(x, Reversible)
725 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700726 # Check some non-reversible iterables
727 non_reversibles = [dict().keys(), dict().items(), dict().values(),
728 Counter(), Counter().keys(), Counter().items(),
729 Counter().values(), _test_gen(),
730 (x for x in []), iter([]), reversed([])]
731 for x in non_reversibles:
732 self.assertNotIsInstance(x, Reversible)
733 self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
734 # Check some reversible iterables
735 samples = [bytes(), str(), tuple(), list(), OrderedDict(),
736 OrderedDict().keys(), OrderedDict().items(),
737 OrderedDict().values()]
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700738 for x in samples:
739 self.assertIsInstance(x, Reversible)
740 self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
741 # Check also Mapping, MutableMapping, and Sequence
742 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
743 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
744 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
745 # Check direct subclassing
746 class R(Reversible):
747 def __iter__(self):
748 return iter(list())
749 def __reversed__(self):
750 return iter(list())
751 self.assertEqual(list(reversed(R())), [])
752 self.assertFalse(issubclass(float, R))
753 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700754 # Check reversible non-iterable (which is not Reversible)
755 class RevNoIter:
756 def __reversed__(self): return reversed([])
757 class RevPlusIter(RevNoIter):
758 def __iter__(self): return iter([])
759 self.assertFalse(issubclass(RevNoIter, Reversible))
760 self.assertFalse(isinstance(RevNoIter(), Reversible))
761 self.assertTrue(issubclass(RevPlusIter, Reversible))
762 self.assertTrue(isinstance(RevPlusIter(), Reversible))
763 # Check None blocking
764 class Rev:
765 def __iter__(self): return iter([])
766 def __reversed__(self): return reversed([])
767 class RevItBlocked(Rev):
768 __iter__ = None
769 class RevRevBlocked(Rev):
770 __reversed__ = None
771 self.assertTrue(issubclass(Rev, Reversible))
772 self.assertTrue(isinstance(Rev(), Reversible))
773 self.assertFalse(issubclass(RevItBlocked, Reversible))
774 self.assertFalse(isinstance(RevItBlocked(), Reversible))
775 self.assertFalse(issubclass(RevRevBlocked, Reversible))
776 self.assertFalse(isinstance(RevRevBlocked(), Reversible))
Guido van Rossum16ca06b2016-04-04 10:59:29 -0700777
Guido van Rossumf0666942016-08-23 10:47:07 -0700778 def test_Collection(self):
779 # Check some non-collections
780 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
781 for x in non_collections:
782 self.assertNotIsInstance(x, Collection)
783 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
784 # Check some non-collection iterables
785 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
786 (x for x in []), dict().values()]
787 for x in non_col_iterables:
788 self.assertNotIsInstance(x, Collection)
789 self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
790 # Check some collections
791 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
792 list(), dict().keys(), dict().items()]
793 for x in samples:
794 self.assertIsInstance(x, Collection)
795 self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
796 # Check also Mapping, MutableMapping, etc.
797 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
798 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
799 self.assertTrue(issubclass(MutableMapping, Collection),
800 repr(MutableMapping))
801 self.assertTrue(issubclass(Set, Collection), repr(Set))
802 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
803 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
804 # Check direct subclassing
805 class Col(Collection):
806 def __iter__(self):
807 return iter(list())
808 def __len__(self):
809 return 0
810 def __contains__(self, item):
811 return False
812 class DerCol(Col): pass
813 self.assertEqual(list(iter(Col())), [])
814 self.assertFalse(issubclass(list, Col))
815 self.assertFalse(issubclass(set, Col))
816 self.assertFalse(issubclass(float, Col))
817 self.assertEqual(list(iter(DerCol())), [])
818 self.assertFalse(issubclass(list, DerCol))
819 self.assertFalse(issubclass(set, DerCol))
820 self.assertFalse(issubclass(float, DerCol))
821 self.validate_abstract_methods(Collection, '__len__', '__iter__',
822 '__contains__')
823 # Check sized container non-iterable (which is not Collection) etc.
824 class ColNoIter:
825 def __len__(self): return 0
826 def __contains__(self, item): return False
827 class ColNoSize:
828 def __iter__(self): return iter([])
829 def __contains__(self, item): return False
830 class ColNoCont:
831 def __iter__(self): return iter([])
832 def __len__(self): return 0
833 self.assertFalse(issubclass(ColNoIter, Collection))
834 self.assertFalse(isinstance(ColNoIter(), Collection))
835 self.assertFalse(issubclass(ColNoSize, Collection))
836 self.assertFalse(isinstance(ColNoSize(), Collection))
837 self.assertFalse(issubclass(ColNoCont, Collection))
838 self.assertFalse(isinstance(ColNoCont(), Collection))
839 # Check None blocking
840 class SizeBlock:
841 def __iter__(self): return iter([])
842 def __contains__(self): return False
843 __len__ = None
844 class IterBlock:
845 def __len__(self): return 0
846 def __contains__(self): return True
847 __iter__ = None
848 self.assertFalse(issubclass(SizeBlock, Collection))
849 self.assertFalse(isinstance(SizeBlock(), Collection))
850 self.assertFalse(issubclass(IterBlock, Collection))
851 self.assertFalse(isinstance(IterBlock(), Collection))
852 # Check None blocking in subclass
853 class ColImpl:
854 def __iter__(self):
855 return iter(list())
856 def __len__(self):
857 return 0
858 def __contains__(self, item):
859 return False
860 class NonCol(ColImpl):
861 __contains__ = None
862 self.assertFalse(issubclass(NonCol, Collection))
863 self.assertFalse(isinstance(NonCol(), Collection))
864
865
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000866 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000867 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000868 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000869 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000870 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000871 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000872 iter(tuple()), iter(list()), iter(dict()),
873 iter(set()), iter(frozenset()),
874 iter(dict().keys()), iter(dict().items()),
875 iter(dict().values()),
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700876 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000877 (x for x in []),
878 ]
879 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000880 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000881 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000882 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
883
884 # Issue 10565
885 class NextOnly:
886 def __next__(self):
887 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800888 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000889 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000890
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400891 def test_Generator(self):
892 class NonGen1:
893 def __iter__(self): return self
894 def __next__(self): return None
895 def close(self): pass
896 def throw(self, typ, val=None, tb=None): pass
897
898 class NonGen2:
899 def __iter__(self): return self
900 def __next__(self): return None
901 def close(self): pass
902 def send(self, value): return value
903
904 class NonGen3:
905 def close(self): pass
906 def send(self, value): return value
907 def throw(self, typ, val=None, tb=None): pass
908
909 non_samples = [
910 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
911 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
912 for x in non_samples:
913 self.assertNotIsInstance(x, Generator)
914 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
915
916 class Gen:
917 def __iter__(self): return self
918 def __next__(self): return None
919 def close(self): pass
920 def send(self, value): return value
921 def throw(self, typ, val=None, tb=None): pass
922
923 class MinimalGen(Generator):
924 def send(self, value):
925 return value
926 def throw(self, typ, val=None, tb=None):
927 super().throw(typ, val, tb)
928
929 def gen():
930 yield 1
931
932 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
933 for x in samples:
934 self.assertIsInstance(x, Iterator)
935 self.assertIsInstance(x, Generator)
936 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
937 self.validate_abstract_methods(Generator, 'send', 'throw')
938
939 # mixin tests
940 mgen = MinimalGen()
941 self.assertIs(mgen, iter(mgen))
942 self.assertIs(mgen.send(None), next(mgen))
943 self.assertEqual(2, mgen.send(2))
944 self.assertIsNone(mgen.close())
945 self.assertRaises(ValueError, mgen.throw, ValueError)
946 self.assertRaisesRegex(ValueError, "^huhu$",
947 mgen.throw, ValueError, ValueError("huhu"))
948 self.assertRaises(StopIteration, mgen.throw, StopIteration())
949
950 class FailOnClose(Generator):
951 def send(self, value): return value
952 def throw(self, *args): raise ValueError
953
954 self.assertRaises(ValueError, FailOnClose().close)
955
956 class IgnoreGeneratorExit(Generator):
957 def send(self, value): return value
958 def throw(self, *args): pass
959
960 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
961
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000962 def test_Sized(self):
963 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700964 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000965 (x for x in []),
966 ]
967 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000968 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000969 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000970 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000971 tuple(), list(), set(), frozenset(), dict(),
972 dict().keys(), dict().items(), dict().values(),
973 ]
974 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000975 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000976 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000977 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000978 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000979
980 def test_Container(self):
981 non_samples = [None, 42, 3.14, 1j,
Guido van Rossum97c1adf2016-08-18 09:22:23 -0700982 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000983 (x for x in []),
984 ]
985 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000986 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000987 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000988 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000989 tuple(), list(), set(), frozenset(), dict(),
990 dict().keys(), dict().items(),
991 ]
992 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000993 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000994 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000995 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000996 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000997
998 def test_Callable(self):
999 non_samples = [None, 42, 3.14, 1j,
1000 "", b"", (), [], {}, set(),
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001001 _test_gen(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001002 (x for x in []),
1003 ]
1004 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001005 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001006 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001007 samples = [lambda: None,
1008 type, int, object,
1009 len,
1010 list.append, [].append,
1011 ]
1012 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +00001013 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001014 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +00001015 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +00001016 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001017
1018 def test_direct_subclassing(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001019 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001020 class C(B):
1021 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001022 self.assertTrue(issubclass(C, B))
1023 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001024
1025 def test_registration(self):
Guido van Rossum16ca06b2016-04-04 10:59:29 -07001026 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001027 class C:
1028 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001029 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001030 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001031 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001032
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001033class WithSet(MutableSet):
1034
1035 def __init__(self, it=()):
1036 self.data = set(it)
1037
1038 def __len__(self):
1039 return len(self.data)
1040
1041 def __iter__(self):
1042 return iter(self.data)
1043
1044 def __contains__(self, item):
1045 return item in self.data
1046
1047 def add(self, item):
1048 self.data.add(item)
1049
1050 def discard(self, item):
1051 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001052
Raymond Hettingerae650182009-01-28 23:33:59 +00001053class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001054
1055 # XXX For now, we only test some virtual inheritance properties.
1056 # We should also test the proper behavior of the collection ABCs
1057 # as real base classes or mix-in classes.
1058
1059 def test_Set(self):
1060 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +00001061 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001062 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +00001063 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001064 class MySet(Set):
1065 def __contains__(self, x):
1066 return False
1067 def __len__(self):
1068 return 0
1069 def __iter__(self):
1070 return iter([])
1071 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001072
Benjamin Peterson41181742008-07-02 20:22:54 +00001073 def test_hash_Set(self):
1074 class OneTwoThreeSet(Set):
1075 def __init__(self):
1076 self.contents = [1, 2, 3]
1077 def __contains__(self, x):
1078 return x in self.contents
1079 def __len__(self):
1080 return len(self.contents)
1081 def __iter__(self):
1082 return iter(self.contents)
1083 def __hash__(self):
1084 return self._hash()
1085 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001086 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +00001087
Raymond Hettinger2d452ee2014-05-25 18:28:39 -07001088 def test_isdisjoint_Set(self):
1089 class MySet(Set):
1090 def __init__(self, itr):
1091 self.contents = itr
1092 def __contains__(self, x):
1093 return x in self.contents
1094 def __iter__(self):
1095 return iter(self.contents)
1096 def __len__(self):
1097 return len([x for x in self.contents])
1098 s1 = MySet((1, 2, 3))
1099 s2 = MySet((4, 5, 6))
1100 s3 = MySet((1, 5, 6))
1101 self.assertTrue(s1.isdisjoint(s2))
1102 self.assertFalse(s1.isdisjoint(s3))
1103
1104 def test_equality_Set(self):
1105 class MySet(Set):
1106 def __init__(self, itr):
1107 self.contents = itr
1108 def __contains__(self, x):
1109 return x in self.contents
1110 def __iter__(self):
1111 return iter(self.contents)
1112 def __len__(self):
1113 return len([x for x in self.contents])
1114 s1 = MySet((1,))
1115 s2 = MySet((1, 2))
1116 s3 = MySet((3, 4))
1117 s4 = MySet((3, 4))
1118 self.assertTrue(s2 > s1)
1119 self.assertTrue(s1 < s2)
1120 self.assertFalse(s2 <= s1)
1121 self.assertFalse(s2 <= s3)
1122 self.assertFalse(s1 >= s2)
1123 self.assertEqual(s3, s4)
1124 self.assertNotEqual(s2, s3)
1125
1126 def test_arithmetic_Set(self):
1127 class MySet(Set):
1128 def __init__(self, itr):
1129 self.contents = itr
1130 def __contains__(self, x):
1131 return x in self.contents
1132 def __iter__(self):
1133 return iter(self.contents)
1134 def __len__(self):
1135 return len([x for x in self.contents])
1136 s1 = MySet((1, 2, 3))
1137 s2 = MySet((3, 4, 5))
1138 s3 = s1 & s2
1139 self.assertEqual(s3, MySet((3,)))
1140
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001141 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +00001142 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001143 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +00001144 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001145 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +00001146 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1147 'add', 'discard')
1148
Raymond Hettinger3f10a952009-04-01 19:05:50 +00001149 def test_issue_5647(self):
1150 # MutableSet.__iand__ mutated the set during iteration
1151 s = WithSet('abcd')
1152 s &= WithSet('cdef') # This used to fail
1153 self.assertEqual(set(s), set('cd'))
1154
Raymond Hettingerae650182009-01-28 23:33:59 +00001155 def test_issue_4920(self):
1156 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001157 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +00001158 __slots__=['__s']
1159 def __init__(self,items=None):
1160 if items is None:
1161 items=[]
1162 self.__s=set(items)
1163 def __contains__(self,v):
1164 return v in self.__s
1165 def __iter__(self):
1166 return iter(self.__s)
1167 def __len__(self):
1168 return len(self.__s)
1169 def add(self,v):
1170 result=v not in self.__s
1171 self.__s.add(v)
1172 return result
1173 def discard(self,v):
1174 result=v in self.__s
1175 self.__s.discard(v)
1176 return result
1177 def __repr__(self):
1178 return "MySet(%s)" % repr(list(self))
1179 s = MySet([5,43,2,1])
1180 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001181
Daniel Stutzbach31da5b22010-08-24 20:49:57 +00001182 def test_issue8750(self):
1183 empty = WithSet()
1184 full = WithSet(range(10))
1185 s = WithSet(full)
1186 s -= s
1187 self.assertEqual(s, empty)
1188 s = WithSet(full)
1189 s ^= s
1190 self.assertEqual(s, empty)
1191 s = WithSet(full)
1192 s &= s
1193 self.assertEqual(s, full)
1194 s |= s
1195 self.assertEqual(s, full)
1196
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001197 def test_issue16373(self):
1198 # Recursion error comparing comparable and noncomparable
1199 # Set instances
1200 class MyComparableSet(Set):
1201 def __contains__(self, x):
1202 return False
1203 def __len__(self):
1204 return 0
1205 def __iter__(self):
1206 return iter([])
1207 class MyNonComparableSet(Set):
1208 def __contains__(self, x):
1209 return False
1210 def __len__(self):
1211 return 0
1212 def __iter__(self):
1213 return iter([])
1214 def __le__(self, x):
1215 return NotImplemented
1216 def __lt__(self, x):
1217 return NotImplemented
1218
1219 cs = MyComparableSet()
1220 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001221 self.assertFalse(ncs < cs)
1222 self.assertTrue(ncs <= cs)
1223 self.assertFalse(ncs > cs)
1224 self.assertTrue(ncs >= cs)
1225
Raymond Hettinger584e8ae2016-05-05 11:14:06 +03001226 def test_issue26915(self):
1227 # Container membership test should check identity first
1228 class CustomEqualObject:
1229 def __eq__(self, other):
1230 return False
1231 class CustomSequence(list):
1232 def __contains__(self, value):
1233 return Sequence.__contains__(self, value)
1234
1235 nan = float('nan')
1236 obj = CustomEqualObject()
1237 containers = [
1238 CustomSequence([nan, obj]),
1239 ItemsView({1: nan, 2: obj}),
1240 ValuesView({1: nan, 2: obj})
1241 ]
1242 for container in containers:
1243 for elem in container:
1244 self.assertIn(elem, container)
1245
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001246 def assertSameSet(self, s1, s2):
1247 # coerce both to a real set then check equality
1248 self.assertSetEqual(set(s1), set(s2))
1249
1250 def test_Set_interoperability_with_real_sets(self):
1251 # Issue: 8743
1252 class ListSet(Set):
1253 def __init__(self, elements=()):
1254 self.data = []
1255 for elem in elements:
1256 if elem not in self.data:
1257 self.data.append(elem)
1258 def __contains__(self, elem):
1259 return elem in self.data
1260 def __iter__(self):
1261 return iter(self.data)
1262 def __len__(self):
1263 return len(self.data)
1264 def __repr__(self):
1265 return 'Set({!r})'.format(self.data)
1266
1267 r1 = set('abc')
1268 r2 = set('bcd')
1269 r3 = set('abcde')
1270 f1 = ListSet('abc')
1271 f2 = ListSet('bcd')
1272 f3 = ListSet('abcde')
1273 l1 = list('abccba')
1274 l2 = list('bcddcb')
1275 l3 = list('abcdeedcba')
1276
1277 target = r1 & r2
1278 self.assertSameSet(f1 & f2, target)
1279 self.assertSameSet(f1 & r2, target)
1280 self.assertSameSet(r2 & f1, target)
1281 self.assertSameSet(f1 & l2, target)
1282
1283 target = r1 | r2
1284 self.assertSameSet(f1 | f2, target)
1285 self.assertSameSet(f1 | r2, target)
1286 self.assertSameSet(r2 | f1, target)
1287 self.assertSameSet(f1 | l2, target)
1288
1289 fwd_target = r1 - r2
1290 rev_target = r2 - r1
1291 self.assertSameSet(f1 - f2, fwd_target)
1292 self.assertSameSet(f2 - f1, rev_target)
1293 self.assertSameSet(f1 - r2, fwd_target)
1294 self.assertSameSet(f2 - r1, rev_target)
1295 self.assertSameSet(r1 - f2, fwd_target)
1296 self.assertSameSet(r2 - f1, rev_target)
1297 self.assertSameSet(f1 - l2, fwd_target)
1298 self.assertSameSet(f2 - l1, rev_target)
1299
1300 target = r1 ^ r2
1301 self.assertSameSet(f1 ^ f2, target)
1302 self.assertSameSet(f1 ^ r2, target)
1303 self.assertSameSet(r2 ^ f1, target)
1304 self.assertSameSet(f1 ^ l2, target)
1305
1306 # Don't change the following to use assertLess or other
1307 # "more specific" unittest assertions. The current
1308 # assertTrue/assertFalse style makes the pattern of test
1309 # case combinations clear and allows us to know for sure
1310 # the exact operator being invoked.
1311
1312 # proper subset
1313 self.assertTrue(f1 < f3)
1314 self.assertFalse(f1 < f1)
1315 self.assertFalse(f1 < f2)
1316 self.assertTrue(r1 < f3)
1317 self.assertFalse(r1 < f1)
1318 self.assertFalse(r1 < f2)
1319 self.assertTrue(r1 < r3)
1320 self.assertFalse(r1 < r1)
1321 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001322 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001323 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001324 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001325 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001326 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001327 f1 < l2
1328
1329 # any subset
1330 self.assertTrue(f1 <= f3)
1331 self.assertTrue(f1 <= f1)
1332 self.assertFalse(f1 <= f2)
1333 self.assertTrue(r1 <= f3)
1334 self.assertTrue(r1 <= f1)
1335 self.assertFalse(r1 <= f2)
1336 self.assertTrue(r1 <= r3)
1337 self.assertTrue(r1 <= r1)
1338 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001339 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001340 f1 <= l3
1341 with self.assertRaises(TypeError):
1342 f1 <= l1
1343 with self.assertRaises(TypeError):
1344 f1 <= l2
1345
1346 # proper superset
1347 self.assertTrue(f3 > f1)
1348 self.assertFalse(f1 > f1)
1349 self.assertFalse(f2 > f1)
1350 self.assertTrue(r3 > r1)
1351 self.assertFalse(f1 > r1)
1352 self.assertFalse(f2 > r1)
1353 self.assertTrue(r3 > r1)
1354 self.assertFalse(r1 > r1)
1355 self.assertFalse(r2 > r1)
1356 with self.assertRaises(TypeError):
1357 f1 > l3
1358 with self.assertRaises(TypeError):
1359 f1 > l1
1360 with self.assertRaises(TypeError):
1361 f1 > l2
1362
1363 # any superset
1364 self.assertTrue(f3 >= f1)
1365 self.assertTrue(f1 >= f1)
1366 self.assertFalse(f2 >= f1)
1367 self.assertTrue(r3 >= r1)
1368 self.assertTrue(f1 >= r1)
1369 self.assertFalse(f2 >= r1)
1370 self.assertTrue(r3 >= r1)
1371 self.assertTrue(r1 >= r1)
1372 self.assertFalse(r2 >= r1)
1373 with self.assertRaises(TypeError):
1374 f1 >= l3
1375 with self.assertRaises(TypeError):
1376 f1 >=l1
1377 with self.assertRaises(TypeError):
1378 f1 >= l2
1379
1380 # equality
1381 self.assertTrue(f1 == f1)
1382 self.assertTrue(r1 == f1)
1383 self.assertTrue(f1 == r1)
1384 self.assertFalse(f1 == f3)
1385 self.assertFalse(r1 == f3)
1386 self.assertFalse(f1 == r3)
1387 self.assertFalse(f1 == l3)
1388 self.assertFalse(f1 == l1)
1389 self.assertFalse(f1 == l2)
1390
1391 # inequality
1392 self.assertFalse(f1 != f1)
1393 self.assertFalse(r1 != f1)
1394 self.assertFalse(f1 != r1)
1395 self.assertTrue(f1 != f3)
1396 self.assertTrue(r1 != f3)
1397 self.assertTrue(f1 != r3)
1398 self.assertTrue(f1 != l3)
1399 self.assertTrue(f1 != l1)
1400 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001401
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001402 def test_Mapping(self):
1403 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001404 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001405 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001406 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1407 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001408 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001409 def __len__(self):
1410 return 0
1411 def __getitem__(self, i):
1412 raise IndexError
1413 def __iter__(self):
1414 return iter(())
1415 self.validate_comparison(MyMapping())
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001416 self.assertRaises(TypeError, reversed, MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001417
1418 def test_MutableMapping(self):
1419 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001420 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001421 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001422 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1423 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001424
Raymond Hettinger9117c752010-08-22 07:44:24 +00001425 def test_MutableMapping_subclass(self):
1426 # Test issue 9214
1427 mymap = UserDict()
1428 mymap['red'] = 5
1429 self.assertIsInstance(mymap.keys(), Set)
1430 self.assertIsInstance(mymap.keys(), KeysView)
1431 self.assertIsInstance(mymap.items(), Set)
1432 self.assertIsInstance(mymap.items(), ItemsView)
1433
1434 mymap = UserDict()
1435 mymap['red'] = 5
1436 z = mymap.keys() | {'orange'}
1437 self.assertIsInstance(z, set)
1438 list(z)
1439 mymap['blue'] = 7 # Shouldn't affect 'z'
1440 self.assertEqual(sorted(z), ['orange', 'red'])
1441
1442 mymap = UserDict()
1443 mymap['red'] = 5
1444 z = mymap.items() | {('orange', 3)}
1445 self.assertIsInstance(z, set)
1446 list(z)
1447 mymap['blue'] = 7 # Shouldn't affect 'z'
1448 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1449
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001450 def test_Sequence(self):
1451 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001452 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001453 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001454 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001455 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001456 self.assertIsInstance(memoryview(b""), Sequence)
1457 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001458 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001459 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1460 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001461
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001462 def test_Sequence_mixins(self):
1463 class SequenceSubclass(Sequence):
1464 def __init__(self, seq=()):
1465 self.seq = seq
1466
1467 def __getitem__(self, index):
1468 return self.seq[index]
1469
1470 def __len__(self):
1471 return len(self.seq)
1472
1473 # Compare Sequence.index() behavior to (list|str).index() behavior
1474 def assert_index_same(seq1, seq2, index_args):
1475 try:
1476 expected = seq1.index(*index_args)
1477 except ValueError:
1478 with self.assertRaises(ValueError):
1479 seq2.index(*index_args)
1480 else:
1481 actual = seq2.index(*index_args)
1482 self.assertEqual(
1483 actual, expected, '%r.index%s' % (seq1, index_args))
1484
1485 for ty in list, str:
1486 nativeseq = ty('abracadabra')
1487 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1488 seqseq = SequenceSubclass(nativeseq)
1489 for letter in set(nativeseq) | {'z'}:
1490 assert_index_same(nativeseq, seqseq, (letter,))
1491 for start in range(-3, len(nativeseq) + 3):
1492 assert_index_same(nativeseq, seqseq, (letter, start))
1493 for stop in range(-3, len(nativeseq) + 3):
1494 assert_index_same(
1495 nativeseq, seqseq, (letter, start, stop))
1496
Guido van Rossumd05eb002007-11-21 22:26:24 +00001497 def test_ByteString(self):
1498 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001499 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001500 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001501 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001502 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001503 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001504 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001505 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001506
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001507 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001508 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001509 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001510 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001511 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001512 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001513 self.assertTrue(issubclass(sample, MutableSequence))
1514 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001515 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1516 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001517
Eli Bendersky0716a572011-03-04 10:38:14 +00001518 def test_MutableSequence_mixins(self):
1519 # Test the mixins of MutableSequence by creating a miminal concrete
1520 # class inherited from it.
1521 class MutableSequenceSubclass(MutableSequence):
1522 def __init__(self):
1523 self.lst = []
1524
1525 def __setitem__(self, index, value):
1526 self.lst[index] = value
1527
1528 def __getitem__(self, index):
1529 return self.lst[index]
1530
1531 def __len__(self):
1532 return len(self.lst)
1533
1534 def __delitem__(self, index):
1535 del self.lst[index]
1536
1537 def insert(self, index, value):
1538 self.lst.insert(index, value)
1539
1540 mss = MutableSequenceSubclass()
1541 mss.append(0)
1542 mss.extend((1, 2, 3, 4))
1543 self.assertEqual(len(mss), 5)
1544 self.assertEqual(mss[3], 3)
1545 mss.reverse()
1546 self.assertEqual(mss[3], 1)
1547 mss.pop()
1548 self.assertEqual(len(mss), 4)
1549 mss.remove(3)
1550 self.assertEqual(len(mss), 3)
1551 mss += (10, 20, 30)
1552 self.assertEqual(len(mss), 6)
1553 self.assertEqual(mss[-1], 30)
1554 mss.clear()
1555 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001556
1557################################################################################
1558### Counter
1559################################################################################
1560
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001561class CounterSubclassWithSetItem(Counter):
1562 # Test a counter subclass that overrides __setitem__
1563 def __init__(self, *args, **kwds):
1564 self.called = False
1565 Counter.__init__(self, *args, **kwds)
1566 def __setitem__(self, key, value):
1567 self.called = True
1568 Counter.__setitem__(self, key, value)
1569
1570class CounterSubclassWithGet(Counter):
1571 # Test a counter subclass that overrides get()
1572 def __init__(self, *args, **kwds):
1573 self.called = False
1574 Counter.__init__(self, *args, **kwds)
1575 def get(self, key, default):
1576 self.called = True
1577 return Counter.get(self, key, default)
1578
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001579class TestCounter(unittest.TestCase):
1580
1581 def test_basics(self):
1582 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001583 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1584 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001585 self.assertIsInstance(c, dict)
1586 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001587 self.assertTrue(issubclass(Counter, dict))
1588 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001589 self.assertEqual(len(c), 3)
1590 self.assertEqual(sum(c.values()), 6)
1591 self.assertEqual(sorted(c.values()), [1, 2, 3])
1592 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1593 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1594 self.assertEqual(sorted(c.items()),
1595 [('a', 3), ('b', 2), ('c', 1)])
1596 self.assertEqual(c['b'], 2)
1597 self.assertEqual(c['z'], 0)
1598 self.assertEqual(c.__contains__('c'), True)
1599 self.assertEqual(c.__contains__('z'), False)
1600 self.assertEqual(c.get('b', 10), 2)
1601 self.assertEqual(c.get('z', 10), 10)
1602 self.assertEqual(c, dict(a=3, b=2, c=1))
1603 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1604 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1605 for i in range(5):
1606 self.assertEqual(c.most_common(i),
1607 [('a', 3), ('b', 2), ('c', 1)][:i])
1608 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1609 c['a'] += 1 # increment an existing value
1610 c['b'] -= 2 # sub existing value to zero
1611 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001612 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001613 c['d'] -= 2 # sub from a missing value
1614 c['e'] = -5 # directly assign a missing value
1615 c['f'] += 4 # add to a missing value
1616 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1617 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1618 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001619 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001620 for i in range(3):
1621 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001622 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001623 c.clear()
1624 self.assertEqual(c, {})
1625 self.assertEqual(repr(c), 'Counter()')
1626 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1627 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001628 c.update(dict(a=5, b=3))
1629 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001630 c.update(Counter('a' * 50 + 'b' * 30))
1631 c.update() # test case with no args
1632 c.__init__('a' * 500 + 'b' * 300)
1633 c.__init__('cdc')
1634 c.__init__()
1635 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1636 self.assertEqual(c.setdefault('d', 5), 1)
1637 self.assertEqual(c['d'], 1)
1638 self.assertEqual(c.setdefault('e', 5), 5)
1639 self.assertEqual(c['e'], 5)
1640
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001641 def test_init(self):
1642 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1643 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1644 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1645 self.assertRaises(TypeError, Counter, 42)
1646 self.assertRaises(TypeError, Counter, (), ())
1647 self.assertRaises(TypeError, Counter.__init__)
1648
1649 def test_update(self):
1650 c = Counter()
1651 c.update(self=42)
1652 self.assertEqual(list(c.items()), [('self', 42)])
1653 c = Counter()
1654 c.update(iterable=42)
1655 self.assertEqual(list(c.items()), [('iterable', 42)])
1656 c = Counter()
1657 c.update(iterable=None)
1658 self.assertEqual(list(c.items()), [('iterable', None)])
1659 self.assertRaises(TypeError, Counter().update, 42)
1660 self.assertRaises(TypeError, Counter().update, {}, {})
1661 self.assertRaises(TypeError, Counter.update)
1662
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001663 def test_copying(self):
1664 # Check that counters are copyable, deepcopyable, picklable, and
1665 #have a repr/eval round-trip
1666 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001667 def check(dup):
1668 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1669 self.assertIsNot(dup, words, msg)
1670 self.assertEqual(dup, words)
1671 check(words.copy())
1672 check(copy.copy(words))
1673 check(copy.deepcopy(words))
1674 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1675 with self.subTest(proto=proto):
1676 check(pickle.loads(pickle.dumps(words, proto)))
1677 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001678 update_test = Counter()
1679 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001680 check(update_test)
1681 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001682
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001683 def test_copy_subclass(self):
1684 class MyCounter(Counter):
1685 pass
1686 c = MyCounter('slartibartfast')
1687 d = c.copy()
1688 self.assertEqual(d, c)
1689 self.assertEqual(len(d), len(c))
1690 self.assertEqual(type(d), type(c))
1691
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001692 def test_conversions(self):
1693 # Convert to: set, list, dict
1694 s = 'she sells sea shells by the sea shore'
1695 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1696 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1697 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1698 self.assertEqual(set(Counter(s)), set(s))
1699
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001700 def test_invariant_for_the_in_operator(self):
1701 c = Counter(a=10, b=-2, c=0)
1702 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001703 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001704 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001705
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001706 def test_multiset_operations(self):
1707 # Verify that adding a zero counter will strip zeros and negatives
1708 c = Counter(a=10, b=-2, c=0) + Counter()
1709 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001710
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001711 elements = 'abcd'
1712 for i in range(1000):
1713 # test random pairs of multisets
1714 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001715 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001716 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001717 q.update(h=1, i=-1, j=0)
1718 for counterop, numberop in [
1719 (Counter.__add__, lambda x, y: max(0, x+y)),
1720 (Counter.__sub__, lambda x, y: max(0, x-y)),
1721 (Counter.__or__, lambda x, y: max(0,x,y)),
1722 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001723 ]:
1724 result = counterop(p, q)
1725 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001726 self.assertEqual(numberop(p[x], q[x]), result[x],
1727 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001728 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001729 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001730
1731 elements = 'abcdef'
1732 for i in range(100):
1733 # verify that random multisets with no repeats are exactly like sets
1734 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1735 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1736 for counterop, setop in [
1737 (Counter.__sub__, set.__sub__),
1738 (Counter.__or__, set.__or__),
1739 (Counter.__and__, set.__and__),
1740 ]:
1741 counter_result = counterop(p, q)
1742 set_result = setop(set(p.elements()), set(q.elements()))
1743 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001744
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001745 def test_inplace_operations(self):
1746 elements = 'abcd'
1747 for i in range(1000):
1748 # test random pairs of multisets
1749 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1750 p.update(e=1, f=-1, g=0)
1751 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1752 q.update(h=1, i=-1, j=0)
1753 for inplace_op, regular_op in [
1754 (Counter.__iadd__, Counter.__add__),
1755 (Counter.__isub__, Counter.__sub__),
1756 (Counter.__ior__, Counter.__or__),
1757 (Counter.__iand__, Counter.__and__),
1758 ]:
1759 c = p.copy()
1760 c_id = id(c)
1761 regular_result = regular_op(c, q)
1762 inplace_result = inplace_op(c, q)
1763 self.assertEqual(inplace_result, regular_result)
1764 self.assertEqual(id(inplace_result), c_id)
1765
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001766 def test_subtract(self):
1767 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1768 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1769 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1770 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1771 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1772 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1773 c = Counter('aaabbcd')
1774 c.subtract('aaaabbcce')
1775 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001776
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001777 c = Counter()
1778 c.subtract(self=42)
1779 self.assertEqual(list(c.items()), [('self', -42)])
1780 c = Counter()
1781 c.subtract(iterable=42)
1782 self.assertEqual(list(c.items()), [('iterable', -42)])
1783 self.assertRaises(TypeError, Counter().subtract, 42)
1784 self.assertRaises(TypeError, Counter().subtract, {}, {})
1785 self.assertRaises(TypeError, Counter.subtract)
1786
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001787 def test_unary(self):
1788 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1789 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1790 self.assertEqual(dict(-c), dict(a=5))
1791
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001792 def test_repr_nonsortable(self):
1793 c = Counter(a=2, b=None)
1794 r = repr(c)
1795 self.assertIn("'a': 2", r)
1796 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001797
Raymond Hettinger426e0522011-01-03 02:12:02 +00001798 def test_helper_function(self):
1799 # two paths, one for real dicts and one for other mappings
1800 elems = list('abracadabra')
1801
1802 d = dict()
1803 _count_elements(d, elems)
1804 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1805
1806 m = OrderedDict()
1807 _count_elements(m, elems)
1808 self.assertEqual(m,
1809 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1810
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001811 # test fidelity to the pure python version
1812 c = CounterSubclassWithSetItem('abracadabra')
1813 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001814 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001815 c = CounterSubclassWithGet('abracadabra')
1816 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001817 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001818
Raymond Hettinger499e1932011-02-23 07:56:53 +00001819
1820################################################################################
Raymond Hettinger499e1932011-02-23 07:56:53 +00001821### Run tests
1822################################################################################
1823
Guido van Rossumd8faa362007-04-27 19:54:29 +00001824def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00001825 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001826 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00001827 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06001828 TestUserObjects,
1829 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001830 support.run_unittest(*test_classes)
1831 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001832
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001833
Guido van Rossumd8faa362007-04-27 19:54:29 +00001834if __name__ == "__main__":
1835 test_main(verbose=True)