blob: c2d03eea74c4e620b28a29b951642e568beb4d7f [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001"""Unit tests for collections.py."""
2
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00003import unittest, doctest, operator
Eric Snow47db7172015-05-29 22:21:39 -06004from test.support import TESTFN, forget, unlink, import_fresh_module
5import contextlib
Raymond Hettinger2d32f632009-03-02 21:24:57 +00006import inspect
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Raymond Hettinger426e0522011-01-03 02:12:02 +00008from collections import namedtuple, Counter, OrderedDict, _count_elements
Raymond Hettinger2d32f632009-03-02 21:24:57 +00009from test import mapping_tests
Georg Brandlc28e1fa2008-06-10 19:20:26 +000010import pickle, copy
Raymond Hettinger2d32f632009-03-02 21:24:57 +000011from random import randrange, shuffle
Raymond Hettinger499b2ee2009-05-27 01:53:46 +000012import keyword
13import re
R. David Murray378c0cf2010-02-24 01:46:21 +000014import sys
Yury Selivanov75445082015-05-11 22:57:16 -040015import types
Raymond Hettinger573b44c2015-05-22 16:56:32 -070016from collections import UserDict, UserString, UserList
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000017from collections import ChainMap
Raymond Hettinger32ea1652015-03-21 01:37:37 -070018from collections import deque
Yury Selivanove0104ae2015-05-14 12:19:16 -040019from collections.abc import Awaitable, Coroutine, AsyncIterator, AsyncIterable
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -040020from collections.abc import Hashable, Iterable, Iterator, Generator
Raymond Hettinger57d1a882011-02-23 00:46:28 +000021from collections.abc import Sized, Container, Callable
22from collections.abc import Set, MutableSet
23from collections.abc import Mapping, MutableMapping, KeysView, ItemsView
24from collections.abc import Sequence, MutableSequence
25from collections.abc import ByteString
Guido van Rossumcd16bf62007-06-13 18:07:49 +000026
Raymond Hettinger499e1932011-02-23 07:56:53 +000027
Raymond Hettinger573b44c2015-05-22 16:56:32 -070028class TestUserObjects(unittest.TestCase):
29 def _superset_test(self, a, b):
30 self.assertGreaterEqual(
31 set(dir(a)),
32 set(dir(b)),
33 '{a} should have all the methods of {b}'.format(
34 a=a.__name__,
35 b=b.__name__,
36 ),
37 )
38 def test_str_protocol(self):
39 self._superset_test(UserString, str)
40
41 def test_list_protocol(self):
42 self._superset_test(UserList, list)
43
44 def test_dict_protocol(self):
45 self._superset_test(UserDict, dict)
46
47
Raymond Hettinger499e1932011-02-23 07:56:53 +000048################################################################################
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +000049### ChainMap (helper class for configparser and the string module)
Raymond Hettinger499e1932011-02-23 07:56:53 +000050################################################################################
51
52class TestChainMap(unittest.TestCase):
53
54 def test_basics(self):
55 c = ChainMap()
56 c['a'] = 1
57 c['b'] = 2
58 d = c.new_child()
59 d['b'] = 20
60 d['c'] = 30
61 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
62 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
63 self.assertEqual(len(d), 3) # check len
64 for key in 'abc': # check contains
65 self.assertIn(key, d)
66 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
67 self.assertEqual(d.get(k, 100), v)
68
69 del d['b'] # unmask a value
70 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
71 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
72 self.assertEqual(len(d), 3) # check len
73 for key in 'abc': # check contains
74 self.assertIn(key, d)
75 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
76 self.assertEqual(d.get(k, 100), v)
77 self.assertIn(repr(d), [ # check repr
78 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
79 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
80 ])
81
82 for e in d.copy(), copy.copy(d): # check shallow copies
83 self.assertEqual(d, e)
84 self.assertEqual(d.maps, e.maps)
85 self.assertIsNot(d, e)
86 self.assertIsNot(d.maps[0], e.maps[0])
87 for m1, m2 in zip(d.maps[1:], e.maps[1:]):
88 self.assertIs(m1, m2)
89
Serhiy Storchakabad12572014-12-15 14:03:42 +020090 # check deep copies
91 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
92 e = pickle.loads(pickle.dumps(d, proto))
93 self.assertEqual(d, e)
94 self.assertEqual(d.maps, e.maps)
95 self.assertIsNot(d, e)
96 for m1, m2 in zip(d.maps, e.maps):
97 self.assertIsNot(m1, m2, e)
98 for e in [copy.deepcopy(d),
Raymond Hettinger499e1932011-02-23 07:56:53 +000099 eval(repr(d))
Serhiy Storchakabad12572014-12-15 14:03:42 +0200100 ]:
Raymond Hettinger499e1932011-02-23 07:56:53 +0000101 self.assertEqual(d, e)
102 self.assertEqual(d.maps, e.maps)
103 self.assertIsNot(d, e)
104 for m1, m2 in zip(d.maps, e.maps):
105 self.assertIsNot(m1, m2, e)
106
Raymond Hettingerd0321312011-02-26 06:53:58 +0000107 f = d.new_child()
108 f['b'] = 5
109 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
110 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
111 self.assertEqual(f['b'], 5) # find first in chain
112 self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
Raymond Hettinger499e1932011-02-23 07:56:53 +0000113
114 def test_contructor(self):
Raymond Hettingerd0321312011-02-26 06:53:58 +0000115 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
Raymond Hettinger499e1932011-02-23 07:56:53 +0000116 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
117
Raymond Hettingerd0321312011-02-26 06:53:58 +0000118 def test_bool(self):
119 self.assertFalse(ChainMap())
120 self.assertFalse(ChainMap({}, {}))
121 self.assertTrue(ChainMap({1:2}, {}))
122 self.assertTrue(ChainMap({}, {1:2}))
123
Raymond Hettinger499e1932011-02-23 07:56:53 +0000124 def test_missing(self):
125 class DefaultChainMap(ChainMap):
126 def __missing__(self, key):
127 return 999
128 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
129 for k, v in dict(a=1, b=2, c=30, d=999).items():
130 self.assertEqual(d[k], v) # check __getitem__ w/missing
131 for k, v in dict(a=1, b=2, c=30, d=77).items():
132 self.assertEqual(d.get(k, 77), v) # check get() w/ missing
133 for k, v in dict(a=True, b=True, c=True, d=False).items():
134 self.assertEqual(k in d, v) # check __contains__ w/missing
135 self.assertEqual(d.pop('a', 1001), 1, d)
136 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
137 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
138 with self.assertRaises(KeyError):
139 d.popitem()
140
141 def test_dict_coercion(self):
142 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
143 self.assertEqual(dict(d), dict(a=1, b=2, c=30))
144 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
145
Vinay Sajip1ba81ee2013-01-11 23:39:53 +0000146 def test_new_child(self):
147 'Tests for changes for issue #16613.'
148 c = ChainMap()
149 c['a'] = 1
150 c['b'] = 2
151 m = {'b':20, 'c': 30}
152 d = c.new_child(m)
153 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
154 self.assertIs(m, d.maps[0])
155
156 # Use a different map than a dict
157 class lowerdict(dict):
158 def __getitem__(self, key):
159 if isinstance(key, str):
160 key = key.lower()
161 return dict.__getitem__(self, key)
162 def __contains__(self, key):
163 if isinstance(key, str):
164 key = key.lower()
165 return dict.__contains__(self, key)
166
167 c = ChainMap()
168 c['a'] = 1
169 c['b'] = 2
170 m = lowerdict(b=20, c=30)
171 d = c.new_child(m)
172 self.assertIs(m, d.maps[0])
173 for key in 'abc': # check contains
174 self.assertIn(key, d)
175 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
176 self.assertEqual(d.get(k, 100), v)
177
Raymond Hettinger499e1932011-02-23 07:56:53 +0000178
179################################################################################
180### Named Tuples
181################################################################################
182
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000183TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Guido van Rossumd8faa362007-04-27 19:54:29 +0000184
185class TestNamedTuple(unittest.TestCase):
186
187 def test_factory(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000188 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000189 self.assertEqual(Point.__name__, 'Point')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000190 self.assertEqual(Point.__slots__, ())
191 self.assertEqual(Point.__module__, __name__)
192 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000193 self.assertEqual(Point._fields, ('x', 'y'))
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700194 self.assertIn('class Point(tuple)', Point._source)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000195
196 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
197 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
198 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
199
200 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
201 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
202 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Christian Heimes0449f632007-12-15 01:27:15 +0000203 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000204 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
205
206 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Christian Heimes0449f632007-12-15 01:27:15 +0000207 namedtuple('_', 'a b c') # Test leading underscores in a typename
Guido van Rossumd8faa362007-04-27 19:54:29 +0000208
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000209 nt = namedtuple('nt', 'the quick brown fox') # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000210 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000211 nt = namedtuple('nt', ('the', 'quick')) # check unicode input
Benjamin Peterson577473f2010-01-19 00:09:57 +0000212 self.assertNotIn("u'", repr(nt._fields))
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000213
Christian Heimesfaf2f632008-01-06 16:59:19 +0000214 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
215 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
216
R. David Murray378c0cf2010-02-24 01:46:21 +0000217 @unittest.skipIf(sys.flags.optimize >= 2,
218 "Docstrings are omitted with -O2 and above")
219 def test_factory_doc_attr(self):
220 Point = namedtuple('Point', 'x y')
221 self.assertEqual(Point.__doc__, 'Point(x, y)')
222
Raymond Hettingereac503a2015-05-13 01:09:59 -0700223 @unittest.skipIf(sys.flags.optimize >= 2,
224 "Docstrings are omitted with -O2 and above")
225 def test_doc_writable(self):
226 Point = namedtuple('Point', 'x y')
227 self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
228 Point.x.__doc__ = 'docstring for Point.x'
229 self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
230
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000231 def test_name_fixer(self):
232 for spec, renamed in [
Raymond Hettinger56145242009-04-02 22:31:59 +0000233 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
234 [('abc', 'class'), ('abc', '_1')], # field has keyword
235 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
236 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
237 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
238 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000239 ]:
240 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
241
Guido van Rossumd8faa362007-04-27 19:54:29 +0000242 def test_instance(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000243 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000244 p = Point(11, 22)
245 self.assertEqual(p, Point(x=11, y=22))
246 self.assertEqual(p, Point(11, y=22))
247 self.assertEqual(p, Point(y=22, x=11))
248 self.assertEqual(p, Point(*(11, 22)))
249 self.assertEqual(p, Point(**dict(x=11, y=22)))
250 self.assertRaises(TypeError, Point, 1) # too few args
251 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
252 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
253 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
254 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000255 self.assertNotIn('__weakref__', dir(p))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000256 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Christian Heimes0449f632007-12-15 01:27:15 +0000257 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
258 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
Raymond Hettinger163e9822013-05-18 00:05:20 -0700259 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
260 self.assertEqual(vars(p), p._asdict()) # verify that vars() works
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000261
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000262 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000263 p._replace(x=1, error=2)
264 except ValueError:
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000265 pass
266 else:
Christian Heimesfaf2f632008-01-06 16:59:19 +0000267 self._fail('Did not detect an incorrect fieldname')
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000268
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000269 # verify that field string can have commas
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000270 Point = namedtuple('Point', 'x, y')
271 p = Point(x=11, y=22)
272 self.assertEqual(repr(p), 'Point(x=11, y=22)')
273
274 # verify that fieldspec can be a non-string sequence
275 Point = namedtuple('Point', ('x', 'y'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000276 p = Point(x=11, y=22)
277 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000278
279 def test_tupleness(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000280 Point = namedtuple('Point', 'x y')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000281 p = Point(11, 22)
282
Ezio Melottie9615932010-01-24 19:26:24 +0000283 self.assertIsInstance(p, tuple)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000284 self.assertEqual(p, (11, 22)) # matches a real tuple
285 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
286 self.assertEqual(list(p), [11, 22]) # coercable to a list
287 self.assertEqual(max(p), 22) # iterable
288 self.assertEqual(max(*p), 22) # star-able
289 x, y = p
290 self.assertEqual(p, (x, y)) # unpacks like a tuple
291 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
292 self.assertRaises(IndexError, p.__getitem__, 3)
293
294 self.assertEqual(p.x, x)
295 self.assertEqual(p.y, y)
296 self.assertRaises(AttributeError, eval, 'p.z', locals())
297
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000298 def test_odd_sizes(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000299 Zero = namedtuple('Zero', '')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000300 self.assertEqual(Zero(), ())
Christian Heimesfaf2f632008-01-06 16:59:19 +0000301 self.assertEqual(Zero._make([]), ())
Christian Heimes99170a52007-12-19 02:07:34 +0000302 self.assertEqual(repr(Zero()), 'Zero()')
303 self.assertEqual(Zero()._asdict(), {})
304 self.assertEqual(Zero()._fields, ())
305
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000306 Dot = namedtuple('Dot', 'd')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000307 self.assertEqual(Dot(1), (1,))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000308 self.assertEqual(Dot._make([1]), (1,))
Christian Heimes99170a52007-12-19 02:07:34 +0000309 self.assertEqual(Dot(1).d, 1)
310 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
311 self.assertEqual(Dot(1)._asdict(), {'d':1})
312 self.assertEqual(Dot(1)._replace(d=999), (999,))
313 self.assertEqual(Dot(1)._fields, ('d',))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000314
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000315 # n = 5000
Christian Heimes99170a52007-12-19 02:07:34 +0000316 n = 254 # SyntaxError: more than 255 arguments:
317 import string, random
Georg Brandlb533e262008-05-25 18:19:30 +0000318 names = list(set(''.join([random.choice(string.ascii_letters)
319 for j in range(10)]) for i in range(n)))
320 n = len(names)
Christian Heimes99170a52007-12-19 02:07:34 +0000321 Big = namedtuple('Big', names)
322 b = Big(*range(n))
323 self.assertEqual(b, tuple(range(n)))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000324 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Christian Heimes99170a52007-12-19 02:07:34 +0000325 for pos, name in enumerate(names):
326 self.assertEqual(getattr(b, name), pos)
327 repr(b) # make sure repr() doesn't blow-up
328 d = b._asdict()
329 d_expected = dict(zip(names, range(n)))
330 self.assertEqual(d, d_expected)
331 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
332 b2_expected = list(range(n))
333 b2_expected[1] = 999
334 b2_expected[-5] = 42
335 self.assertEqual(b2, tuple(b2_expected))
336 self.assertEqual(b._fields, tuple(names))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000337
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000338 def test_pickle(self):
339 p = TestNT(x=10, y=20, z=30)
340 for module in (pickle,):
341 loads = getattr(module, 'loads')
342 dumps = getattr(module, 'dumps')
Eric V. Smith4d5d69d2014-02-05 10:33:14 -0500343 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000344 q = loads(dumps(p, protocol))
345 self.assertEqual(p, q)
346 self.assertEqual(p._fields, q._fields)
Raymond Hettingerb98dcc12013-05-03 02:24:15 -0700347 self.assertNotIn(b'OrderedDict', dumps(p, protocol))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000348
349 def test_copy(self):
350 p = TestNT(x=10, y=20, z=30)
351 for copier in copy.copy, copy.deepcopy:
352 q = copier(p)
353 self.assertEqual(p, q)
354 self.assertEqual(p._fields, q._fields)
355
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000356 def test_name_conflicts(self):
357 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
358 # failed when used as field names. Test to make sure these now work.
359 T = namedtuple('T', 'itemgetter property self cls tuple')
360 t = T(1, 2, 3, 4, 5)
361 self.assertEqual(t, (1,2,3,4,5))
362 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
363 self.assertEqual(newt, (10,20,30,40,50))
364
Raymond Hettinger499b2ee2009-05-27 01:53:46 +0000365 # Broader test of all interesting names in a template
366 with support.captured_stdout() as template:
367 T = namedtuple('T', 'x', verbose=True)
368 words = set(re.findall('[A-Za-z]+', template.getvalue()))
369 words -= set(keyword.kwlist)
370 T = namedtuple('T', words)
371 # test __new__
372 values = tuple(range(len(words)))
373 t = T(*values)
374 self.assertEqual(t, values)
375 t = T(**dict(zip(T._fields, values)))
376 self.assertEqual(t, values)
377 # test _make
378 t = T._make(values)
379 self.assertEqual(t, values)
380 # exercise __repr__
381 repr(t)
382 # test _asdict
383 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
384 # test _replace
385 t = T._make(values)
386 newvalues = tuple(v*10 for v in values)
387 newt = t._replace(**dict(zip(T._fields, newvalues)))
388 self.assertEqual(newt, newvalues)
389 # test _fields
390 self.assertEqual(T._fields, tuple(words))
391 # test __getnewargs__
392 self.assertEqual(t.__getnewargs__(), values)
393
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000394 def test_repr(self):
395 with support.captured_stdout() as template:
396 A = namedtuple('A', 'x', verbose=True)
397 self.assertEqual(repr(A(1)), 'A(x=1)')
398 # repr should show the name of the subclass
399 class B(A):
400 pass
401 self.assertEqual(repr(B(1)), 'B(x=1)')
402
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700403 def test_source(self):
404 # verify that _source can be run through exec()
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700405 tmp = namedtuple('NTColor', 'red green blue')
406 globals().pop('NTColor', None) # remove artifacts from other tests
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700407 exec(tmp._source, globals())
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700408 self.assertIn('NTColor', globals())
409 c = NTColor(10, 20, 30)
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700410 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
Raymond Hettingerd4652fa2011-03-24 09:45:43 -0700411 self.assertEqual(NTColor._fields, ('red', 'green', 'blue'))
412 globals().pop('NTColor', None) # clean-up after this test
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700413
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000414
Raymond Hettinger499e1932011-02-23 07:56:53 +0000415################################################################################
416### Abstract Base Classes
417################################################################################
418
Raymond Hettingerae650182009-01-28 23:33:59 +0000419class ABCTestCase(unittest.TestCase):
420
421 def validate_abstract_methods(self, abc, *names):
422 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
423
424 # everything should work will all required methods are present
425 C = type('C', (abc,), methodstubs)
426 C()
427
428 # instantiation should fail if a required method is missing
429 for name in names:
430 stubs = methodstubs.copy()
431 del stubs[name]
432 C = type('C', (abc,), stubs)
433 self.assertRaises(TypeError, C, name)
434
Florent Xiclunace153f62010-03-08 15:34:35 +0000435 def validate_isinstance(self, abc, name):
436 stub = lambda s, *args: 0
437
438 C = type('C', (object,), {'__hash__': None})
439 setattr(C, name, stub)
440 self.assertIsInstance(C(), abc)
441 self.assertTrue(issubclass(C, abc))
442
443 C = type('C', (object,), {'__hash__': None})
444 self.assertNotIsInstance(C(), abc)
445 self.assertFalse(issubclass(C, abc))
Raymond Hettingerae650182009-01-28 23:33:59 +0000446
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000447 def validate_comparison(self, instance):
448 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
449 operators = {}
450 for op in ops:
451 name = '__' + op + '__'
452 operators[name] = getattr(operator, name)
453
454 class Other:
455 def __init__(self):
456 self.right_side = False
457 def __eq__(self, other):
458 self.right_side = True
459 return True
460 __lt__ = __eq__
461 __gt__ = __eq__
462 __le__ = __eq__
463 __ge__ = __eq__
464 __ne__ = __eq__
465 __ror__ = __eq__
466 __rand__ = __eq__
467 __rxor__ = __eq__
468 __rsub__ = __eq__
469
470 for name, op in operators.items():
471 if not hasattr(instance, name):
472 continue
473 other = Other()
474 op(instance, other)
475 self.assertTrue(other.right_side,'Right side not called for %s.%s'
476 % (type(instance), name))
477
Raymond Hettingerae650182009-01-28 23:33:59 +0000478class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000479
Yury Selivanov75445082015-05-11 22:57:16 -0400480 def test_Awaitable(self):
481 def gen():
482 yield
483
484 @types.coroutine
485 def coro():
486 yield
487
488 async def new_coro():
489 pass
490
491 class Bar:
492 def __await__(self):
493 yield
494
495 class MinimalCoro(Coroutine):
496 def send(self, value):
497 return value
498 def throw(self, typ, val=None, tb=None):
499 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400500 def __await__(self):
501 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400502
503 non_samples = [None, int(), gen(), object()]
504 for x in non_samples:
505 self.assertNotIsInstance(x, Awaitable)
506 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
507
508 samples = [Bar(), MinimalCoro()]
509 for x in samples:
510 self.assertIsInstance(x, Awaitable)
511 self.assertTrue(issubclass(type(x), Awaitable))
512
513 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400514 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
515 # flag don't have '__await__' method, hence can't be instances
516 # of Awaitable. Use inspect.isawaitable to detect them.
517 self.assertNotIsInstance(c, Awaitable)
Yury Selivanov75445082015-05-11 22:57:16 -0400518
519 c = new_coro()
520 self.assertIsInstance(c, Awaitable)
521 c.close() # awoid RuntimeWarning that coro() was not awaited
522
Yury Selivanov56fc6142015-05-29 09:01:29 -0400523 class CoroLike: pass
Yury Selivanovaded55c2015-05-13 23:41:55 -0400524 Coroutine.register(CoroLike)
Yury Selivanov08e53002015-05-13 23:57:59 -0400525 self.assertTrue(isinstance(CoroLike(), Awaitable))
526 self.assertTrue(issubclass(CoroLike, Awaitable))
527 CoroLike = None
528 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
Yury Selivanovaded55c2015-05-13 23:41:55 -0400529
Yury Selivanov75445082015-05-11 22:57:16 -0400530 def test_Coroutine(self):
531 def gen():
532 yield
533
534 @types.coroutine
535 def coro():
536 yield
537
538 async def new_coro():
539 pass
540
541 class Bar:
542 def __await__(self):
543 yield
544
545 class MinimalCoro(Coroutine):
546 def send(self, value):
547 return value
548 def throw(self, typ, val=None, tb=None):
549 super().throw(typ, val, tb)
Yury Selivanov56fc6142015-05-29 09:01:29 -0400550 def __await__(self):
551 yield
Yury Selivanov75445082015-05-11 22:57:16 -0400552
553 non_samples = [None, int(), gen(), object(), Bar()]
554 for x in non_samples:
555 self.assertNotIsInstance(x, Coroutine)
556 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
557
558 samples = [MinimalCoro()]
559 for x in samples:
560 self.assertIsInstance(x, Awaitable)
561 self.assertTrue(issubclass(type(x), Awaitable))
562
563 c = coro()
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400564 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
565 # flag don't have '__await__' method, hence can't be instances
566 # of Coroutine. Use inspect.isawaitable to detect them.
567 self.assertNotIsInstance(c, Coroutine)
Yury Selivanov75445082015-05-11 22:57:16 -0400568
569 c = new_coro()
570 self.assertIsInstance(c, Coroutine)
571 c.close() # awoid RuntimeWarning that coro() was not awaited
572
Yury Selivanov56fc6142015-05-29 09:01:29 -0400573 class CoroLike:
574 def send(self, value):
575 pass
576 def throw(self, typ, val=None, tb=None):
577 pass
578 def close(self):
579 pass
580 def __await__(self):
581 pass
582 self.assertTrue(isinstance(CoroLike(), Coroutine))
583 self.assertTrue(issubclass(CoroLike, Coroutine))
584
585 class CoroLike:
586 def send(self, value):
587 pass
588 def close(self):
589 pass
590 def __await__(self):
591 pass
592 self.assertFalse(isinstance(CoroLike(), Coroutine))
593 self.assertFalse(issubclass(CoroLike, Coroutine))
594
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000595 def test_Hashable(self):
596 # Check some non-hashables
Guido van Rossum254348e2007-11-21 19:29:53 +0000597 non_samples = [bytearray(), list(), set(), dict()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000598 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000599 self.assertNotIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000600 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000601 # Check some hashables
602 samples = [None,
603 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +0000604 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000605 tuple(), frozenset(),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000606 int, list, object, type, bytes()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000607 ]
608 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000609 self.assertIsInstance(x, Hashable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000610 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000611 self.assertRaises(TypeError, Hashable)
612 # Check direct subclassing
613 class H(Hashable):
614 def __hash__(self):
615 return super().__hash__()
616 self.assertEqual(hash(H()), 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000617 self.assertFalse(issubclass(int, H))
Raymond Hettingerae650182009-01-28 23:33:59 +0000618 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000619 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000620
Yury Selivanove0104ae2015-05-14 12:19:16 -0400621 def test_AsyncIterable(self):
622 class AI:
623 async def __aiter__(self):
624 return self
625 self.assertTrue(isinstance(AI(), AsyncIterable))
626 self.assertTrue(issubclass(AI, AsyncIterable))
627 # Check some non-iterables
628 non_samples = [None, object, []]
629 for x in non_samples:
630 self.assertNotIsInstance(x, AsyncIterable)
631 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
632 self.validate_abstract_methods(AsyncIterable, '__aiter__')
633 self.validate_isinstance(AsyncIterable, '__aiter__')
634
635 def test_AsyncIterator(self):
636 class AI:
637 async def __aiter__(self):
638 return self
639 async def __anext__(self):
640 raise StopAsyncIteration
641 self.assertTrue(isinstance(AI(), AsyncIterator))
642 self.assertTrue(issubclass(AI, AsyncIterator))
643 non_samples = [None, object, []]
644 # Check some non-iterables
645 for x in non_samples:
646 self.assertNotIsInstance(x, AsyncIterator)
647 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
648 # Similarly to regular iterators (see issue 10565)
649 class AnextOnly:
650 async def __anext__(self):
651 raise StopAsyncIteration
652 self.assertNotIsInstance(AnextOnly(), AsyncIterator)
653 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
654
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000655 def test_Iterable(self):
656 # Check some non-iterables
657 non_samples = [None, 42, 3.14, 1j]
658 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000659 self.assertNotIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000660 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000661 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000662 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000663 tuple(), list(), set(), frozenset(), dict(),
664 dict().keys(), dict().items(), dict().values(),
665 (lambda: (yield))(),
666 (x for x in []),
667 ]
668 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000669 self.assertIsInstance(x, Iterable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000670 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000671 # Check direct subclassing
672 class I(Iterable):
673 def __iter__(self):
674 return super().__iter__()
675 self.assertEqual(list(I()), [])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000676 self.assertFalse(issubclass(str, I))
Raymond Hettingerae650182009-01-28 23:33:59 +0000677 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000678 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000679
680 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000681 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000682 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000683 self.assertNotIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000684 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000685 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000686 iter(tuple()), iter(list()), iter(dict()),
687 iter(set()), iter(frozenset()),
688 iter(dict().keys()), iter(dict().items()),
689 iter(dict().values()),
690 (lambda: (yield))(),
691 (x for x in []),
692 ]
693 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000694 self.assertIsInstance(x, Iterator)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000695 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Raymond Hettingeread22222010-11-29 03:56:12 +0000696 self.validate_abstract_methods(Iterator, '__next__', '__iter__')
697
698 # Issue 10565
699 class NextOnly:
700 def __next__(self):
701 yield 1
Raymond Hettingerbb6c0aa2014-11-22 22:14:41 -0800702 return
Raymond Hettingeread22222010-11-29 03:56:12 +0000703 self.assertNotIsInstance(NextOnly(), Iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000704
Raymond Hettingerbd60e8d2015-05-09 01:07:23 -0400705 def test_Generator(self):
706 class NonGen1:
707 def __iter__(self): return self
708 def __next__(self): return None
709 def close(self): pass
710 def throw(self, typ, val=None, tb=None): pass
711
712 class NonGen2:
713 def __iter__(self): return self
714 def __next__(self): return None
715 def close(self): pass
716 def send(self, value): return value
717
718 class NonGen3:
719 def close(self): pass
720 def send(self, value): return value
721 def throw(self, typ, val=None, tb=None): pass
722
723 non_samples = [
724 None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
725 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
726 for x in non_samples:
727 self.assertNotIsInstance(x, Generator)
728 self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
729
730 class Gen:
731 def __iter__(self): return self
732 def __next__(self): return None
733 def close(self): pass
734 def send(self, value): return value
735 def throw(self, typ, val=None, tb=None): pass
736
737 class MinimalGen(Generator):
738 def send(self, value):
739 return value
740 def throw(self, typ, val=None, tb=None):
741 super().throw(typ, val, tb)
742
743 def gen():
744 yield 1
745
746 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
747 for x in samples:
748 self.assertIsInstance(x, Iterator)
749 self.assertIsInstance(x, Generator)
750 self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
751 self.validate_abstract_methods(Generator, 'send', 'throw')
752
753 # mixin tests
754 mgen = MinimalGen()
755 self.assertIs(mgen, iter(mgen))
756 self.assertIs(mgen.send(None), next(mgen))
757 self.assertEqual(2, mgen.send(2))
758 self.assertIsNone(mgen.close())
759 self.assertRaises(ValueError, mgen.throw, ValueError)
760 self.assertRaisesRegex(ValueError, "^huhu$",
761 mgen.throw, ValueError, ValueError("huhu"))
762 self.assertRaises(StopIteration, mgen.throw, StopIteration())
763
764 class FailOnClose(Generator):
765 def send(self, value): return value
766 def throw(self, *args): raise ValueError
767
768 self.assertRaises(ValueError, FailOnClose().close)
769
770 class IgnoreGeneratorExit(Generator):
771 def send(self, value): return value
772 def throw(self, *args): pass
773
774 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
775
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000776 def test_Sized(self):
777 non_samples = [None, 42, 3.14, 1j,
778 (lambda: (yield))(),
779 (x for x in []),
780 ]
781 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000782 self.assertNotIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000783 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000784 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000785 tuple(), list(), set(), frozenset(), dict(),
786 dict().keys(), dict().items(), dict().values(),
787 ]
788 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000789 self.assertIsInstance(x, Sized)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000790 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000791 self.validate_abstract_methods(Sized, '__len__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000792 self.validate_isinstance(Sized, '__len__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000793
794 def test_Container(self):
795 non_samples = [None, 42, 3.14, 1j,
796 (lambda: (yield))(),
797 (x for x in []),
798 ]
799 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000800 self.assertNotIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000801 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000802 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000803 tuple(), list(), set(), frozenset(), dict(),
804 dict().keys(), dict().items(),
805 ]
806 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000807 self.assertIsInstance(x, Container)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000808 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000809 self.validate_abstract_methods(Container, '__contains__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000810 self.validate_isinstance(Container, '__contains__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000811
812 def test_Callable(self):
813 non_samples = [None, 42, 3.14, 1j,
814 "", b"", (), [], {}, set(),
815 (lambda: (yield))(),
816 (x for x in []),
817 ]
818 for x in non_samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000819 self.assertNotIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000820 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000821 samples = [lambda: None,
822 type, int, object,
823 len,
824 list.append, [].append,
825 ]
826 for x in samples:
Ezio Melottie9615932010-01-24 19:26:24 +0000827 self.assertIsInstance(x, Callable)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000828 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerae650182009-01-28 23:33:59 +0000829 self.validate_abstract_methods(Callable, '__call__')
Florent Xiclunace153f62010-03-08 15:34:35 +0000830 self.validate_isinstance(Callable, '__call__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000831
832 def test_direct_subclassing(self):
833 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
834 class C(B):
835 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000836 self.assertTrue(issubclass(C, B))
837 self.assertFalse(issubclass(int, C))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000838
839 def test_registration(self):
840 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
841 class C:
842 __hash__ = None # Make sure it isn't hashable by default
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000843 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000844 B.register(C)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000845 self.assertTrue(issubclass(C, B))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000846
Raymond Hettinger3f10a952009-04-01 19:05:50 +0000847class WithSet(MutableSet):
848
849 def __init__(self, it=()):
850 self.data = set(it)
851
852 def __len__(self):
853 return len(self.data)
854
855 def __iter__(self):
856 return iter(self.data)
857
858 def __contains__(self, item):
859 return item in self.data
860
861 def add(self, item):
862 self.data.add(item)
863
864 def discard(self, item):
865 self.data.discard(item)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000866
Raymond Hettingerae650182009-01-28 23:33:59 +0000867class TestCollectionABCs(ABCTestCase):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000868
869 # XXX For now, we only test some virtual inheritance properties.
870 # We should also test the proper behavior of the collection ABCs
871 # as real base classes or mix-in classes.
872
873 def test_Set(self):
874 for sample in [set, frozenset]:
Ezio Melottie9615932010-01-24 19:26:24 +0000875 self.assertIsInstance(sample(), Set)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000876 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerae650182009-01-28 23:33:59 +0000877 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +0000878 class MySet(Set):
879 def __contains__(self, x):
880 return False
881 def __len__(self):
882 return 0
883 def __iter__(self):
884 return iter([])
885 self.validate_comparison(MySet())
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000886
Benjamin Peterson41181742008-07-02 20:22:54 +0000887 def test_hash_Set(self):
888 class OneTwoThreeSet(Set):
889 def __init__(self):
890 self.contents = [1, 2, 3]
891 def __contains__(self, x):
892 return x in self.contents
893 def __len__(self):
894 return len(self.contents)
895 def __iter__(self):
896 return iter(self.contents)
897 def __hash__(self):
898 return self._hash()
899 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000900 self.assertTrue(hash(a) == hash(b))
Benjamin Peterson41181742008-07-02 20:22:54 +0000901
Raymond Hettinger2d452ee2014-05-25 18:28:39 -0700902 def test_isdisjoint_Set(self):
903 class MySet(Set):
904 def __init__(self, itr):
905 self.contents = itr
906 def __contains__(self, x):
907 return x in self.contents
908 def __iter__(self):
909 return iter(self.contents)
910 def __len__(self):
911 return len([x for x in self.contents])
912 s1 = MySet((1, 2, 3))
913 s2 = MySet((4, 5, 6))
914 s3 = MySet((1, 5, 6))
915 self.assertTrue(s1.isdisjoint(s2))
916 self.assertFalse(s1.isdisjoint(s3))
917
918 def test_equality_Set(self):
919 class MySet(Set):
920 def __init__(self, itr):
921 self.contents = itr
922 def __contains__(self, x):
923 return x in self.contents
924 def __iter__(self):
925 return iter(self.contents)
926 def __len__(self):
927 return len([x for x in self.contents])
928 s1 = MySet((1,))
929 s2 = MySet((1, 2))
930 s3 = MySet((3, 4))
931 s4 = MySet((3, 4))
932 self.assertTrue(s2 > s1)
933 self.assertTrue(s1 < s2)
934 self.assertFalse(s2 <= s1)
935 self.assertFalse(s2 <= s3)
936 self.assertFalse(s1 >= s2)
937 self.assertEqual(s3, s4)
938 self.assertNotEqual(s2, s3)
939
940 def test_arithmetic_Set(self):
941 class MySet(Set):
942 def __init__(self, itr):
943 self.contents = itr
944 def __contains__(self, x):
945 return x in self.contents
946 def __iter__(self):
947 return iter(self.contents)
948 def __len__(self):
949 return len([x for x in self.contents])
950 s1 = MySet((1, 2, 3))
951 s2 = MySet((3, 4, 5))
952 s3 = s1 & s2
953 self.assertEqual(s3, MySet((3,)))
954
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000955 def test_MutableSet(self):
Ezio Melottie9615932010-01-24 19:26:24 +0000956 self.assertIsInstance(set(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000957 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottie9615932010-01-24 19:26:24 +0000958 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000959 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerae650182009-01-28 23:33:59 +0000960 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
961 'add', 'discard')
962
Raymond Hettinger3f10a952009-04-01 19:05:50 +0000963 def test_issue_5647(self):
964 # MutableSet.__iand__ mutated the set during iteration
965 s = WithSet('abcd')
966 s &= WithSet('cdef') # This used to fail
967 self.assertEqual(set(s), set('cd'))
968
Raymond Hettingerae650182009-01-28 23:33:59 +0000969 def test_issue_4920(self):
970 # MutableSet.pop() method did not work
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000971 class MySet(MutableSet):
Raymond Hettingerae650182009-01-28 23:33:59 +0000972 __slots__=['__s']
973 def __init__(self,items=None):
974 if items is None:
975 items=[]
976 self.__s=set(items)
977 def __contains__(self,v):
978 return v in self.__s
979 def __iter__(self):
980 return iter(self.__s)
981 def __len__(self):
982 return len(self.__s)
983 def add(self,v):
984 result=v not in self.__s
985 self.__s.add(v)
986 return result
987 def discard(self,v):
988 result=v in self.__s
989 self.__s.discard(v)
990 return result
991 def __repr__(self):
992 return "MySet(%s)" % repr(list(self))
993 s = MySet([5,43,2,1])
994 self.assertEqual(s.pop(), 1)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000995
Daniel Stutzbach31da5b22010-08-24 20:49:57 +0000996 def test_issue8750(self):
997 empty = WithSet()
998 full = WithSet(range(10))
999 s = WithSet(full)
1000 s -= s
1001 self.assertEqual(s, empty)
1002 s = WithSet(full)
1003 s ^= s
1004 self.assertEqual(s, empty)
1005 s = WithSet(full)
1006 s &= s
1007 self.assertEqual(s, full)
1008 s |= s
1009 self.assertEqual(s, full)
1010
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001011 def test_issue16373(self):
1012 # Recursion error comparing comparable and noncomparable
1013 # Set instances
1014 class MyComparableSet(Set):
1015 def __contains__(self, x):
1016 return False
1017 def __len__(self):
1018 return 0
1019 def __iter__(self):
1020 return iter([])
1021 class MyNonComparableSet(Set):
1022 def __contains__(self, x):
1023 return False
1024 def __len__(self):
1025 return 0
1026 def __iter__(self):
1027 return iter([])
1028 def __le__(self, x):
1029 return NotImplemented
1030 def __lt__(self, x):
1031 return NotImplemented
1032
1033 cs = MyComparableSet()
1034 ncs = MyNonComparableSet()
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001035 self.assertFalse(ncs < cs)
1036 self.assertTrue(ncs <= cs)
1037 self.assertFalse(ncs > cs)
1038 self.assertTrue(ncs >= cs)
1039
1040 def assertSameSet(self, s1, s2):
1041 # coerce both to a real set then check equality
1042 self.assertSetEqual(set(s1), set(s2))
1043
1044 def test_Set_interoperability_with_real_sets(self):
1045 # Issue: 8743
1046 class ListSet(Set):
1047 def __init__(self, elements=()):
1048 self.data = []
1049 for elem in elements:
1050 if elem not in self.data:
1051 self.data.append(elem)
1052 def __contains__(self, elem):
1053 return elem in self.data
1054 def __iter__(self):
1055 return iter(self.data)
1056 def __len__(self):
1057 return len(self.data)
1058 def __repr__(self):
1059 return 'Set({!r})'.format(self.data)
1060
1061 r1 = set('abc')
1062 r2 = set('bcd')
1063 r3 = set('abcde')
1064 f1 = ListSet('abc')
1065 f2 = ListSet('bcd')
1066 f3 = ListSet('abcde')
1067 l1 = list('abccba')
1068 l2 = list('bcddcb')
1069 l3 = list('abcdeedcba')
1070
1071 target = r1 & r2
1072 self.assertSameSet(f1 & f2, target)
1073 self.assertSameSet(f1 & r2, target)
1074 self.assertSameSet(r2 & f1, target)
1075 self.assertSameSet(f1 & l2, target)
1076
1077 target = r1 | r2
1078 self.assertSameSet(f1 | f2, target)
1079 self.assertSameSet(f1 | r2, target)
1080 self.assertSameSet(r2 | f1, target)
1081 self.assertSameSet(f1 | l2, target)
1082
1083 fwd_target = r1 - r2
1084 rev_target = r2 - r1
1085 self.assertSameSet(f1 - f2, fwd_target)
1086 self.assertSameSet(f2 - f1, rev_target)
1087 self.assertSameSet(f1 - r2, fwd_target)
1088 self.assertSameSet(f2 - r1, rev_target)
1089 self.assertSameSet(r1 - f2, fwd_target)
1090 self.assertSameSet(r2 - f1, rev_target)
1091 self.assertSameSet(f1 - l2, fwd_target)
1092 self.assertSameSet(f2 - l1, rev_target)
1093
1094 target = r1 ^ r2
1095 self.assertSameSet(f1 ^ f2, target)
1096 self.assertSameSet(f1 ^ r2, target)
1097 self.assertSameSet(r2 ^ f1, target)
1098 self.assertSameSet(f1 ^ l2, target)
1099
1100 # Don't change the following to use assertLess or other
1101 # "more specific" unittest assertions. The current
1102 # assertTrue/assertFalse style makes the pattern of test
1103 # case combinations clear and allows us to know for sure
1104 # the exact operator being invoked.
1105
1106 # proper subset
1107 self.assertTrue(f1 < f3)
1108 self.assertFalse(f1 < f1)
1109 self.assertFalse(f1 < f2)
1110 self.assertTrue(r1 < f3)
1111 self.assertFalse(r1 < f1)
1112 self.assertFalse(r1 < f2)
1113 self.assertTrue(r1 < r3)
1114 self.assertFalse(r1 < r1)
1115 self.assertFalse(r1 < r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001116 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001117 f1 < l3
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001118 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001119 f1 < l1
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001120 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001121 f1 < l2
1122
1123 # any subset
1124 self.assertTrue(f1 <= f3)
1125 self.assertTrue(f1 <= f1)
1126 self.assertFalse(f1 <= f2)
1127 self.assertTrue(r1 <= f3)
1128 self.assertTrue(r1 <= f1)
1129 self.assertFalse(r1 <= f2)
1130 self.assertTrue(r1 <= r3)
1131 self.assertTrue(r1 <= r1)
1132 self.assertFalse(r1 <= r2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001133 with self.assertRaises(TypeError):
Raymond Hettingerdd5e53a2014-05-26 00:09:04 -07001134 f1 <= l3
1135 with self.assertRaises(TypeError):
1136 f1 <= l1
1137 with self.assertRaises(TypeError):
1138 f1 <= l2
1139
1140 # proper superset
1141 self.assertTrue(f3 > f1)
1142 self.assertFalse(f1 > f1)
1143 self.assertFalse(f2 > f1)
1144 self.assertTrue(r3 > r1)
1145 self.assertFalse(f1 > r1)
1146 self.assertFalse(f2 > r1)
1147 self.assertTrue(r3 > r1)
1148 self.assertFalse(r1 > r1)
1149 self.assertFalse(r2 > r1)
1150 with self.assertRaises(TypeError):
1151 f1 > l3
1152 with self.assertRaises(TypeError):
1153 f1 > l1
1154 with self.assertRaises(TypeError):
1155 f1 > l2
1156
1157 # any superset
1158 self.assertTrue(f3 >= f1)
1159 self.assertTrue(f1 >= f1)
1160 self.assertFalse(f2 >= f1)
1161 self.assertTrue(r3 >= r1)
1162 self.assertTrue(f1 >= r1)
1163 self.assertFalse(f2 >= r1)
1164 self.assertTrue(r3 >= r1)
1165 self.assertTrue(r1 >= r1)
1166 self.assertFalse(r2 >= r1)
1167 with self.assertRaises(TypeError):
1168 f1 >= l3
1169 with self.assertRaises(TypeError):
1170 f1 >=l1
1171 with self.assertRaises(TypeError):
1172 f1 >= l2
1173
1174 # equality
1175 self.assertTrue(f1 == f1)
1176 self.assertTrue(r1 == f1)
1177 self.assertTrue(f1 == r1)
1178 self.assertFalse(f1 == f3)
1179 self.assertFalse(r1 == f3)
1180 self.assertFalse(f1 == r3)
1181 self.assertFalse(f1 == l3)
1182 self.assertFalse(f1 == l1)
1183 self.assertFalse(f1 == l2)
1184
1185 # inequality
1186 self.assertFalse(f1 != f1)
1187 self.assertFalse(r1 != f1)
1188 self.assertFalse(f1 != r1)
1189 self.assertTrue(f1 != f3)
1190 self.assertTrue(r1 != f3)
1191 self.assertTrue(f1 != r3)
1192 self.assertTrue(f1 != l3)
1193 self.assertTrue(f1 != l1)
1194 self.assertTrue(f1 != l2)
Andrew Svetlovbcac6ad2012-11-01 13:28:54 +02001195
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001196 def test_Mapping(self):
1197 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001198 self.assertIsInstance(sample(), Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001199 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001200 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1201 '__getitem__')
Raymond Hettinger57d1a882011-02-23 00:46:28 +00001202 class MyMapping(Mapping):
Benjamin Peterson4ad6bd52010-05-21 20:55:22 +00001203 def __len__(self):
1204 return 0
1205 def __getitem__(self, i):
1206 raise IndexError
1207 def __iter__(self):
1208 return iter(())
1209 self.validate_comparison(MyMapping())
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001210
1211 def test_MutableMapping(self):
1212 for sample in [dict]:
Ezio Melottie9615932010-01-24 19:26:24 +00001213 self.assertIsInstance(sample(), MutableMapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001214 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerae650182009-01-28 23:33:59 +00001215 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1216 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001217
Raymond Hettinger9117c752010-08-22 07:44:24 +00001218 def test_MutableMapping_subclass(self):
1219 # Test issue 9214
1220 mymap = UserDict()
1221 mymap['red'] = 5
1222 self.assertIsInstance(mymap.keys(), Set)
1223 self.assertIsInstance(mymap.keys(), KeysView)
1224 self.assertIsInstance(mymap.items(), Set)
1225 self.assertIsInstance(mymap.items(), ItemsView)
1226
1227 mymap = UserDict()
1228 mymap['red'] = 5
1229 z = mymap.keys() | {'orange'}
1230 self.assertIsInstance(z, set)
1231 list(z)
1232 mymap['blue'] = 7 # Shouldn't affect 'z'
1233 self.assertEqual(sorted(z), ['orange', 'red'])
1234
1235 mymap = UserDict()
1236 mymap['red'] = 5
1237 z = mymap.items() | {('orange', 3)}
1238 self.assertIsInstance(z, set)
1239 list(z)
1240 mymap['blue'] = 7 # Shouldn't affect 'z'
1241 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
1242
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001243 def test_Sequence(self):
1244 for sample in [tuple, list, bytes, str]:
Ezio Melottie9615932010-01-24 19:26:24 +00001245 self.assertIsInstance(sample(), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001246 self.assertTrue(issubclass(sample, Sequence))
Ezio Melottie9615932010-01-24 19:26:24 +00001247 self.assertIsInstance(range(10), Sequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001248 self.assertTrue(issubclass(range, Sequence))
Nick Coghlan45163cc2013-10-02 22:31:47 +10001249 self.assertIsInstance(memoryview(b""), Sequence)
1250 self.assertTrue(issubclass(memoryview, Sequence))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001251 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001252 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1253 '__getitem__')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001254
Raymond Hettingerec219ba2015-05-22 19:29:22 -07001255 def test_Sequence_mixins(self):
1256 class SequenceSubclass(Sequence):
1257 def __init__(self, seq=()):
1258 self.seq = seq
1259
1260 def __getitem__(self, index):
1261 return self.seq[index]
1262
1263 def __len__(self):
1264 return len(self.seq)
1265
1266 # Compare Sequence.index() behavior to (list|str).index() behavior
1267 def assert_index_same(seq1, seq2, index_args):
1268 try:
1269 expected = seq1.index(*index_args)
1270 except ValueError:
1271 with self.assertRaises(ValueError):
1272 seq2.index(*index_args)
1273 else:
1274 actual = seq2.index(*index_args)
1275 self.assertEqual(
1276 actual, expected, '%r.index%s' % (seq1, index_args))
1277
1278 for ty in list, str:
1279 nativeseq = ty('abracadabra')
1280 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1281 seqseq = SequenceSubclass(nativeseq)
1282 for letter in set(nativeseq) | {'z'}:
1283 assert_index_same(nativeseq, seqseq, (letter,))
1284 for start in range(-3, len(nativeseq) + 3):
1285 assert_index_same(nativeseq, seqseq, (letter, start))
1286 for stop in range(-3, len(nativeseq) + 3):
1287 assert_index_same(
1288 nativeseq, seqseq, (letter, start, stop))
1289
Guido van Rossumd05eb002007-11-21 22:26:24 +00001290 def test_ByteString(self):
1291 for sample in [bytes, bytearray]:
Ezio Melottie9615932010-01-24 19:26:24 +00001292 self.assertIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001293 self.assertTrue(issubclass(sample, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001294 for sample in [str, list, tuple]:
Ezio Melottie9615932010-01-24 19:26:24 +00001295 self.assertNotIsInstance(sample(), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001296 self.assertFalse(issubclass(sample, ByteString))
Ezio Melottie9615932010-01-24 19:26:24 +00001297 self.assertNotIsInstance(memoryview(b""), ByteString)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001298 self.assertFalse(issubclass(memoryview, ByteString))
Guido van Rossumd05eb002007-11-21 22:26:24 +00001299
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001300 def test_MutableSequence(self):
Guido van Rossumd05eb002007-11-21 22:26:24 +00001301 for sample in [tuple, str, bytes]:
Ezio Melottie9615932010-01-24 19:26:24 +00001302 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001303 self.assertFalse(issubclass(sample, MutableSequence))
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001304 for sample in [list, bytearray, deque]:
Ezio Melottie9615932010-01-24 19:26:24 +00001305 self.assertIsInstance(sample(), MutableSequence)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001306 self.assertTrue(issubclass(sample, MutableSequence))
1307 self.assertFalse(issubclass(str, MutableSequence))
Raymond Hettingerae650182009-01-28 23:33:59 +00001308 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1309 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001310
Eli Bendersky0716a572011-03-04 10:38:14 +00001311 def test_MutableSequence_mixins(self):
1312 # Test the mixins of MutableSequence by creating a miminal concrete
1313 # class inherited from it.
1314 class MutableSequenceSubclass(MutableSequence):
1315 def __init__(self):
1316 self.lst = []
1317
1318 def __setitem__(self, index, value):
1319 self.lst[index] = value
1320
1321 def __getitem__(self, index):
1322 return self.lst[index]
1323
1324 def __len__(self):
1325 return len(self.lst)
1326
1327 def __delitem__(self, index):
1328 del self.lst[index]
1329
1330 def insert(self, index, value):
1331 self.lst.insert(index, value)
1332
1333 mss = MutableSequenceSubclass()
1334 mss.append(0)
1335 mss.extend((1, 2, 3, 4))
1336 self.assertEqual(len(mss), 5)
1337 self.assertEqual(mss[3], 3)
1338 mss.reverse()
1339 self.assertEqual(mss[3], 1)
1340 mss.pop()
1341 self.assertEqual(len(mss), 4)
1342 mss.remove(3)
1343 self.assertEqual(len(mss), 3)
1344 mss += (10, 20, 30)
1345 self.assertEqual(len(mss), 6)
1346 self.assertEqual(mss[-1], 30)
1347 mss.clear()
1348 self.assertEqual(len(mss), 0)
Raymond Hettinger499e1932011-02-23 07:56:53 +00001349
1350################################################################################
1351### Counter
1352################################################################################
1353
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001354class CounterSubclassWithSetItem(Counter):
1355 # Test a counter subclass that overrides __setitem__
1356 def __init__(self, *args, **kwds):
1357 self.called = False
1358 Counter.__init__(self, *args, **kwds)
1359 def __setitem__(self, key, value):
1360 self.called = True
1361 Counter.__setitem__(self, key, value)
1362
1363class CounterSubclassWithGet(Counter):
1364 # Test a counter subclass that overrides get()
1365 def __init__(self, *args, **kwds):
1366 self.called = False
1367 Counter.__init__(self, *args, **kwds)
1368 def get(self, key, default):
1369 self.called = True
1370 return Counter.get(self, key, default)
1371
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001372class TestCounter(unittest.TestCase):
1373
1374 def test_basics(self):
1375 c = Counter('abcaba')
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001376 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
1377 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottie9615932010-01-24 19:26:24 +00001378 self.assertIsInstance(c, dict)
1379 self.assertIsInstance(c, Mapping)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001380 self.assertTrue(issubclass(Counter, dict))
1381 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001382 self.assertEqual(len(c), 3)
1383 self.assertEqual(sum(c.values()), 6)
1384 self.assertEqual(sorted(c.values()), [1, 2, 3])
1385 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
1386 self.assertEqual(sorted(c), ['a', 'b', 'c'])
1387 self.assertEqual(sorted(c.items()),
1388 [('a', 3), ('b', 2), ('c', 1)])
1389 self.assertEqual(c['b'], 2)
1390 self.assertEqual(c['z'], 0)
1391 self.assertEqual(c.__contains__('c'), True)
1392 self.assertEqual(c.__contains__('z'), False)
1393 self.assertEqual(c.get('b', 10), 2)
1394 self.assertEqual(c.get('z', 10), 10)
1395 self.assertEqual(c, dict(a=3, b=2, c=1))
1396 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
1397 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
1398 for i in range(5):
1399 self.assertEqual(c.most_common(i),
1400 [('a', 3), ('b', 2), ('c', 1)][:i])
1401 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
1402 c['a'] += 1 # increment an existing value
1403 c['b'] -= 2 # sub existing value to zero
1404 del c['c'] # remove an entry
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001405 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001406 c['d'] -= 2 # sub from a missing value
1407 c['e'] = -5 # directly assign a missing value
1408 c['f'] += 4 # add to a missing value
1409 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
1410 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
1411 self.assertEqual(c.pop('f'), 4)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001412 self.assertNotIn('f', c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001413 for i in range(3):
1414 elem, cnt = c.popitem()
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001415 self.assertNotIn(elem, c)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001416 c.clear()
1417 self.assertEqual(c, {})
1418 self.assertEqual(repr(c), 'Counter()')
1419 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
1420 self.assertRaises(TypeError, hash, c)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001421 c.update(dict(a=5, b=3))
1422 c.update(c=1)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001423 c.update(Counter('a' * 50 + 'b' * 30))
1424 c.update() # test case with no args
1425 c.__init__('a' * 500 + 'b' * 300)
1426 c.__init__('cdc')
1427 c.__init__()
1428 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
1429 self.assertEqual(c.setdefault('d', 5), 1)
1430 self.assertEqual(c['d'], 1)
1431 self.assertEqual(c.setdefault('e', 5), 5)
1432 self.assertEqual(c['e'], 5)
1433
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001434 def test_init(self):
1435 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
1436 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
1437 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
1438 self.assertRaises(TypeError, Counter, 42)
1439 self.assertRaises(TypeError, Counter, (), ())
1440 self.assertRaises(TypeError, Counter.__init__)
1441
1442 def test_update(self):
1443 c = Counter()
1444 c.update(self=42)
1445 self.assertEqual(list(c.items()), [('self', 42)])
1446 c = Counter()
1447 c.update(iterable=42)
1448 self.assertEqual(list(c.items()), [('iterable', 42)])
1449 c = Counter()
1450 c.update(iterable=None)
1451 self.assertEqual(list(c.items()), [('iterable', None)])
1452 self.assertRaises(TypeError, Counter().update, 42)
1453 self.assertRaises(TypeError, Counter().update, {}, {})
1454 self.assertRaises(TypeError, Counter.update)
1455
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001456 def test_copying(self):
1457 # Check that counters are copyable, deepcopyable, picklable, and
1458 #have a repr/eval round-trip
1459 words = Counter('which witch had which witches wrist watch'.split())
Serhiy Storchakabad12572014-12-15 14:03:42 +02001460 def check(dup):
1461 msg = "\ncopy: %s\nwords: %s" % (dup, words)
1462 self.assertIsNot(dup, words, msg)
1463 self.assertEqual(dup, words)
1464 check(words.copy())
1465 check(copy.copy(words))
1466 check(copy.deepcopy(words))
1467 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1468 with self.subTest(proto=proto):
1469 check(pickle.loads(pickle.dumps(words, proto)))
1470 check(eval(repr(words)))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001471 update_test = Counter()
1472 update_test.update(words)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001473 check(update_test)
1474 check(Counter(words))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001475
Raymond Hettinger1c746c22011-04-15 13:16:46 -07001476 def test_copy_subclass(self):
1477 class MyCounter(Counter):
1478 pass
1479 c = MyCounter('slartibartfast')
1480 d = c.copy()
1481 self.assertEqual(d, c)
1482 self.assertEqual(len(d), len(c))
1483 self.assertEqual(type(d), type(c))
1484
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001485 def test_conversions(self):
1486 # Convert to: set, list, dict
1487 s = 'she sells sea shells by the sea shore'
1488 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
1489 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
1490 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
1491 self.assertEqual(set(Counter(s)), set(s))
1492
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001493 def test_invariant_for_the_in_operator(self):
1494 c = Counter(a=10, b=-2, c=0)
1495 for elem in c:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001496 self.assertTrue(elem in c)
Benjamin Peterson577473f2010-01-19 00:09:57 +00001497 self.assertIn(elem, c)
Raymond Hettinger670eaec2009-01-21 23:14:07 +00001498
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001499 def test_multiset_operations(self):
1500 # Verify that adding a zero counter will strip zeros and negatives
1501 c = Counter(a=10, b=-2, c=0) + Counter()
1502 self.assertEqual(dict(c), dict(a=10))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001503
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001504 elements = 'abcd'
1505 for i in range(1000):
1506 # test random pairs of multisets
1507 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001508 p.update(e=1, f=-1, g=0)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001509 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001510 q.update(h=1, i=-1, j=0)
1511 for counterop, numberop in [
1512 (Counter.__add__, lambda x, y: max(0, x+y)),
1513 (Counter.__sub__, lambda x, y: max(0, x-y)),
1514 (Counter.__or__, lambda x, y: max(0,x,y)),
1515 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001516 ]:
1517 result = counterop(p, q)
1518 for x in elements:
Raymond Hettingere0d1b9f2009-01-21 20:36:27 +00001519 self.assertEqual(numberop(p[x], q[x]), result[x],
1520 (counterop, x, p, q))
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001521 # verify that results exclude non-positive counts
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001522 self.assertTrue(x>0 for x in result.values())
Raymond Hettinger4d2073a2009-01-20 03:41:22 +00001523
1524 elements = 'abcdef'
1525 for i in range(100):
1526 # verify that random multisets with no repeats are exactly like sets
1527 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1528 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1529 for counterop, setop in [
1530 (Counter.__sub__, set.__sub__),
1531 (Counter.__or__, set.__or__),
1532 (Counter.__and__, set.__and__),
1533 ]:
1534 counter_result = counterop(p, q)
1535 set_result = setop(set(p.elements()), set(q.elements()))
1536 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerb8baf632009-01-14 02:20:07 +00001537
Raymond Hettingerbecd5682011-10-19 13:40:37 -07001538 def test_inplace_operations(self):
1539 elements = 'abcd'
1540 for i in range(1000):
1541 # test random pairs of multisets
1542 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1543 p.update(e=1, f=-1, g=0)
1544 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
1545 q.update(h=1, i=-1, j=0)
1546 for inplace_op, regular_op in [
1547 (Counter.__iadd__, Counter.__add__),
1548 (Counter.__isub__, Counter.__sub__),
1549 (Counter.__ior__, Counter.__or__),
1550 (Counter.__iand__, Counter.__and__),
1551 ]:
1552 c = p.copy()
1553 c_id = id(c)
1554 regular_result = regular_op(c, q)
1555 inplace_result = inplace_op(c, q)
1556 self.assertEqual(inplace_result, regular_result)
1557 self.assertEqual(id(inplace_result), c_id)
1558
Raymond Hettinger9c01e442010-04-03 10:32:58 +00001559 def test_subtract(self):
1560 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1561 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1562 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1563 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1564 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1565 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1566 c = Counter('aaabbcd')
1567 c.subtract('aaaabbcce')
1568 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001569
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001570 c = Counter()
1571 c.subtract(self=42)
1572 self.assertEqual(list(c.items()), [('self', -42)])
1573 c = Counter()
1574 c.subtract(iterable=42)
1575 self.assertEqual(list(c.items()), [('iterable', -42)])
1576 self.assertRaises(TypeError, Counter().subtract, 42)
1577 self.assertRaises(TypeError, Counter().subtract, {}, {})
1578 self.assertRaises(TypeError, Counter.subtract)
1579
Raymond Hettingerfcb393c2011-08-09 13:00:40 -07001580 def test_unary(self):
1581 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1582 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
1583 self.assertEqual(dict(-c), dict(a=5))
1584
Raymond Hettinger4e6bf412011-11-05 13:35:26 -07001585 def test_repr_nonsortable(self):
1586 c = Counter(a=2, b=None)
1587 r = repr(c)
1588 self.assertIn("'a': 2", r)
1589 self.assertIn("'b': None", r)
Raymond Hettinger68fb89f2011-11-05 13:43:01 -07001590
Raymond Hettinger426e0522011-01-03 02:12:02 +00001591 def test_helper_function(self):
1592 # two paths, one for real dicts and one for other mappings
1593 elems = list('abracadabra')
1594
1595 d = dict()
1596 _count_elements(d, elems)
1597 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
1598
1599 m = OrderedDict()
1600 _count_elements(m, elems)
1601 self.assertEqual(m,
1602 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
1603
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001604 # test fidelity to the pure python version
1605 c = CounterSubclassWithSetItem('abracadabra')
1606 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001607 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001608 c = CounterSubclassWithGet('abracadabra')
1609 self.assertTrue(c.called)
Raymond Hettingerfacd0a32013-10-05 17:14:51 -07001610 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001611
Raymond Hettinger499e1932011-02-23 07:56:53 +00001612
1613################################################################################
1614### OrderedDict
1615################################################################################
1616
Eric Snow47db7172015-05-29 22:21:39 -06001617py_coll = import_fresh_module('collections', blocked=['_collections'])
1618c_coll = import_fresh_module('collections', fresh=['_collections'])
1619
1620
1621@contextlib.contextmanager
1622def replaced_module(name, replacement):
1623 original_module = sys.modules[name]
1624 sys.modules[name] = replacement
1625 try:
1626 yield
1627 finally:
1628 sys.modules[name] = original_module
1629
1630
1631class OrderedDictTests:
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001632
1633 def test_init(self):
Eric Snow47db7172015-05-29 22:21:39 -06001634 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001635 with self.assertRaises(TypeError):
1636 OrderedDict([('a', 1), ('b', 2)], None) # too many args
1637 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1638 self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
1639 self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
1640 self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
1641 self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
1642 c=3, e=5).items()), pairs) # mixed input
1643
1644 # make sure no positional args conflict with possible kwdargs
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001645 self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)])
1646 self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)])
1647 self.assertRaises(TypeError, OrderedDict, 42)
1648 self.assertRaises(TypeError, OrderedDict, (), ())
1649 self.assertRaises(TypeError, OrderedDict.__init__)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001650
1651 # Make sure that direct calls to __init__ do not clear previous contents
1652 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1653 d.__init__([('e', 5), ('f', 6)], g=7, d=4)
1654 self.assertEqual(list(d.items()),
1655 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1656
1657 def test_update(self):
Eric Snow47db7172015-05-29 22:21:39 -06001658 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001659 with self.assertRaises(TypeError):
1660 OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
1661 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1662 od = OrderedDict()
1663 od.update(dict(pairs))
1664 self.assertEqual(sorted(od.items()), pairs) # dict input
1665 od = OrderedDict()
1666 od.update(**dict(pairs))
1667 self.assertEqual(sorted(od.items()), pairs) # kwds input
1668 od = OrderedDict()
1669 od.update(pairs)
1670 self.assertEqual(list(od.items()), pairs) # pairs input
1671 od = OrderedDict()
1672 od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
1673 self.assertEqual(list(od.items()), pairs) # mixed input
1674
Mark Dickinsonb214e902010-07-11 18:53:06 +00001675 # Issue 9137: Named argument called 'other' or 'self'
1676 # shouldn't be treated specially.
1677 od = OrderedDict()
1678 od.update(self=23)
1679 self.assertEqual(list(od.items()), [('self', 23)])
1680 od = OrderedDict()
1681 od.update(other={})
1682 self.assertEqual(list(od.items()), [('other', {})])
1683 od = OrderedDict()
1684 od.update(red=5, blue=6, other=7, self=8)
1685 self.assertEqual(sorted(list(od.items())),
1686 [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
1687
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001688 # Make sure that direct calls to update do not clear previous contents
1689 # add that updates items are not moved to the end
1690 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1691 d.update([('e', 5), ('f', 6)], g=7, d=4)
1692 self.assertEqual(list(d.items()),
1693 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1694
Serhiy Storchakaae5cb212014-11-27 16:25:51 +02001695 self.assertRaises(TypeError, OrderedDict().update, 42)
1696 self.assertRaises(TypeError, OrderedDict().update, (), ())
1697 self.assertRaises(TypeError, OrderedDict.update)
1698
Eric Snow47db7172015-05-29 22:21:39 -06001699 self.assertRaises(TypeError, OrderedDict().update, 42)
1700 self.assertRaises(TypeError, OrderedDict().update, (), ())
1701 self.assertRaises(TypeError, OrderedDict.update)
1702
Eric Snowac02ef32015-06-02 20:42:14 -06001703 def test_fromkeys(self):
1704 OrderedDict = self.module.OrderedDict
1705 od = OrderedDict.fromkeys('abc')
1706 self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
1707 od = OrderedDict.fromkeys('abc', value=None)
1708 self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
1709 od = OrderedDict.fromkeys('abc', value=0)
1710 self.assertEqual(list(od.items()), [(c, 0) for c in 'abc'])
1711
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001712 def test_abc(self):
Eric Snow47db7172015-05-29 22:21:39 -06001713 OrderedDict = self.module.OrderedDict
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001714 self.assertIsInstance(OrderedDict(), MutableMapping)
1715 self.assertTrue(issubclass(OrderedDict, MutableMapping))
1716
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001717 def test_clear(self):
Eric Snow47db7172015-05-29 22:21:39 -06001718 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001719 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1720 shuffle(pairs)
1721 od = OrderedDict(pairs)
1722 self.assertEqual(len(od), len(pairs))
1723 od.clear()
1724 self.assertEqual(len(od), 0)
1725
1726 def test_delitem(self):
Eric Snow47db7172015-05-29 22:21:39 -06001727 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001728 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1729 od = OrderedDict(pairs)
1730 del od['a']
Benjamin Peterson577473f2010-01-19 00:09:57 +00001731 self.assertNotIn('a', od)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001732 with self.assertRaises(KeyError):
1733 del od['a']
1734 self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
1735
1736 def test_setitem(self):
Eric Snow47db7172015-05-29 22:21:39 -06001737 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001738 od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
1739 od['c'] = 10 # existing element
1740 od['f'] = 20 # new element
1741 self.assertEqual(list(od.items()),
1742 [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
1743
1744 def test_iterators(self):
Eric Snow47db7172015-05-29 22:21:39 -06001745 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001746 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1747 shuffle(pairs)
1748 od = OrderedDict(pairs)
1749 self.assertEqual(list(od), [t[0] for t in pairs])
1750 self.assertEqual(list(od.keys()), [t[0] for t in pairs])
1751 self.assertEqual(list(od.values()), [t[1] for t in pairs])
1752 self.assertEqual(list(od.items()), pairs)
1753 self.assertEqual(list(reversed(od)),
1754 [t[0] for t in reversed(pairs)])
Serhiy Storchaka578c9212014-04-04 15:19:36 +03001755 self.assertEqual(list(reversed(od.keys())),
1756 [t[0] for t in reversed(pairs)])
1757 self.assertEqual(list(reversed(od.values())),
1758 [t[1] for t in reversed(pairs)])
1759 self.assertEqual(list(reversed(od.items())), list(reversed(pairs)))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001760
Raymond Hettinger53d2c412014-05-03 21:58:45 -07001761 def test_detect_deletion_during_iteration(self):
Eric Snow47db7172015-05-29 22:21:39 -06001762 OrderedDict = self.module.OrderedDict
Raymond Hettinger53d2c412014-05-03 21:58:45 -07001763 od = OrderedDict.fromkeys('abc')
1764 it = iter(od)
1765 key = next(it)
1766 del od[key]
1767 with self.assertRaises(Exception):
1768 # Note, the exact exception raised is not guaranteed
1769 # The only guarantee that the next() will not succeed
1770 next(it)
1771
Eric Snow47db7172015-05-29 22:21:39 -06001772 def test_sorted_iterators(self):
1773 OrderedDict = self.module.OrderedDict
1774 with self.assertRaises(TypeError):
1775 OrderedDict([('a', 1), ('b', 2)], None)
1776 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1777 od = OrderedDict(pairs)
1778 self.assertEqual(sorted(od), [t[0] for t in pairs])
1779 self.assertEqual(sorted(od.keys()), [t[0] for t in pairs])
1780 self.assertEqual(sorted(od.values()), [t[1] for t in pairs])
1781 self.assertEqual(sorted(od.items()), pairs)
1782 self.assertEqual(sorted(reversed(od)),
1783 sorted([t[0] for t in reversed(pairs)]))
1784
Eric Snow67fb92e2015-05-30 11:43:36 -06001785 def test_iterators_empty(self):
1786 OrderedDict = self.module.OrderedDict
1787 od = OrderedDict()
1788 empty = []
1789 self.assertEqual(list(od), empty)
1790 self.assertEqual(list(od.keys()), empty)
1791 self.assertEqual(list(od.values()), empty)
1792 self.assertEqual(list(od.items()), empty)
1793 self.assertEqual(list(reversed(od)), empty)
1794 self.assertEqual(list(reversed(od.keys())), empty)
1795 self.assertEqual(list(reversed(od.values())), empty)
1796 self.assertEqual(list(reversed(od.items())), empty)
1797
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001798 def test_popitem(self):
Eric Snow47db7172015-05-29 22:21:39 -06001799 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001800 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1801 shuffle(pairs)
1802 od = OrderedDict(pairs)
1803 while pairs:
1804 self.assertEqual(od.popitem(), pairs.pop())
1805 with self.assertRaises(KeyError):
1806 od.popitem()
1807 self.assertEqual(len(od), 0)
1808
Eric Snow47db7172015-05-29 22:21:39 -06001809 def test_popitem_last(self):
1810 OrderedDict = self.module.OrderedDict
1811 pairs = [(i, i) for i in range(30)]
1812
1813 obj = OrderedDict(pairs)
1814 for i in range(8):
1815 obj.popitem(True)
1816 obj.popitem(True)
Eric Snowac02ef32015-06-02 20:42:14 -06001817 obj.popitem(last=True)
1818 self.assertEqual(len(obj), 20)
Eric Snow47db7172015-05-29 22:21:39 -06001819
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001820 def test_pop(self):
Eric Snow47db7172015-05-29 22:21:39 -06001821 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001822 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1823 shuffle(pairs)
1824 od = OrderedDict(pairs)
1825 shuffle(pairs)
1826 while pairs:
1827 k, v = pairs.pop()
1828 self.assertEqual(od.pop(k), v)
1829 with self.assertRaises(KeyError):
1830 od.pop('xyz')
1831 self.assertEqual(len(od), 0)
1832 self.assertEqual(od.pop(k, 12345), 12345)
1833
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001834 # make sure pop still works when __missing__ is defined
1835 class Missing(OrderedDict):
1836 def __missing__(self, key):
1837 return 0
1838 m = Missing(a=1)
1839 self.assertEqual(m.pop('b', 5), 5)
1840 self.assertEqual(m.pop('a', 6), 1)
1841 self.assertEqual(m.pop('a', 6), 6)
Eric Snowac02ef32015-06-02 20:42:14 -06001842 self.assertEqual(m.pop('a', default=6), 6)
Raymond Hettinger345c49b2011-01-01 23:51:55 +00001843 with self.assertRaises(KeyError):
1844 m.pop('a')
1845
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001846 def test_equality(self):
Eric Snow47db7172015-05-29 22:21:39 -06001847 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001848 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1849 shuffle(pairs)
1850 od1 = OrderedDict(pairs)
1851 od2 = OrderedDict(pairs)
1852 self.assertEqual(od1, od2) # same order implies equality
1853 pairs = pairs[2:] + pairs[:2]
1854 od2 = OrderedDict(pairs)
1855 self.assertNotEqual(od1, od2) # different order implies inequality
1856 # comparison to regular dict is not order sensitive
1857 self.assertEqual(od1, dict(od2))
1858 self.assertEqual(dict(od2), od1)
1859 # different length implied inequality
1860 self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
1861
1862 def test_copying(self):
Eric Snow47db7172015-05-29 22:21:39 -06001863 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001864 # Check that ordered dicts are copyable, deepcopyable, picklable,
1865 # and have a repr/eval round-trip
1866 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1867 od = OrderedDict(pairs)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001868 def check(dup):
1869 msg = "\ncopy: %s\nod: %s" % (dup, od)
1870 self.assertIsNot(dup, od, msg)
1871 self.assertEqual(dup, od)
Eric Snow47db7172015-05-29 22:21:39 -06001872 self.assertEqual(list(dup.items()), list(od.items()))
1873 self.assertEqual(len(dup), len(od))
1874 self.assertEqual(type(dup), type(od))
Serhiy Storchakabad12572014-12-15 14:03:42 +02001875 check(od.copy())
1876 check(copy.copy(od))
1877 check(copy.deepcopy(od))
Eric Snow47db7172015-05-29 22:21:39 -06001878 # pickle directly pulls the module, so we have to fake it
1879 with replaced_module('collections', self.module):
1880 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1881 with self.subTest(proto=proto):
1882 check(pickle.loads(pickle.dumps(od, proto)))
Serhiy Storchakabad12572014-12-15 14:03:42 +02001883 check(eval(repr(od)))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001884 update_test = OrderedDict()
1885 update_test.update(od)
Serhiy Storchakabad12572014-12-15 14:03:42 +02001886 check(update_test)
1887 check(OrderedDict(od))
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001888
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001889 def test_yaml_linkage(self):
Eric Snow47db7172015-05-29 22:21:39 -06001890 OrderedDict = self.module.OrderedDict
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001891 # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
1892 # In yaml, lists are native but tuples are not.
1893 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1894 od = OrderedDict(pairs)
1895 # yaml.dump(od) -->
1896 # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001897 self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
Raymond Hettinger5b26fb52009-03-03 22:38:22 +00001898
Raymond Hettingerb2121572009-03-03 22:50:04 +00001899 def test_reduce_not_too_fat(self):
Eric Snow47db7172015-05-29 22:21:39 -06001900 OrderedDict = self.module.OrderedDict
Raymond Hettingerb2121572009-03-03 22:50:04 +00001901 # do not save instance dictionary if not needed
1902 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1903 od = OrderedDict(pairs)
Serhiy Storchaka3ee6dab2013-05-21 12:47:57 +03001904 self.assertIsNone(od.__reduce__()[2])
Raymond Hettingerb2121572009-03-03 22:50:04 +00001905 od.x = 10
Serhiy Storchaka3ee6dab2013-05-21 12:47:57 +03001906 self.assertIsNotNone(od.__reduce__()[2])
1907
1908 def test_pickle_recursive(self):
Eric Snow47db7172015-05-29 22:21:39 -06001909 OrderedDict = self.module.OrderedDict
Serhiy Storchaka3ee6dab2013-05-21 12:47:57 +03001910 od = OrderedDict()
1911 od[1] = od
Eric Snow47db7172015-05-29 22:21:39 -06001912
1913 # pickle directly pulls the module, so we have to fake it
1914 with replaced_module('collections', self.module):
1915 for proto in range(-1, pickle.HIGHEST_PROTOCOL + 1):
1916 dup = pickle.loads(pickle.dumps(od, proto))
1917 self.assertIsNot(dup, od)
1918 self.assertEqual(list(dup.keys()), [1])
1919 self.assertIs(dup[1], dup)
Raymond Hettingerb2121572009-03-03 22:50:04 +00001920
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001921 def test_repr(self):
Eric Snow47db7172015-05-29 22:21:39 -06001922 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001923 od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
1924 self.assertEqual(repr(od),
1925 "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
1926 self.assertEqual(eval(repr(od)), od)
1927 self.assertEqual(repr(OrderedDict()), "OrderedDict()")
1928
Raymond Hettingerdc08a142010-09-12 05:15:22 +00001929 def test_repr_recursive(self):
Eric Snow47db7172015-05-29 22:21:39 -06001930 OrderedDict = self.module.OrderedDict
Raymond Hettingerdc08a142010-09-12 05:15:22 +00001931 # See issue #9826
1932 od = OrderedDict.fromkeys('abc')
1933 od['x'] = od
1934 self.assertEqual(repr(od),
1935 "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
1936
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001937 def test_setdefault(self):
Eric Snow47db7172015-05-29 22:21:39 -06001938 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001939 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1940 shuffle(pairs)
1941 od = OrderedDict(pairs)
1942 pair_order = list(od.items())
1943 self.assertEqual(od.setdefault('a', 10), 3)
1944 # make sure order didn't change
1945 self.assertEqual(list(od.items()), pair_order)
1946 self.assertEqual(od.setdefault('x', 10), 10)
1947 # make sure 'x' is added to the end
1948 self.assertEqual(list(od.items())[-1], ('x', 10))
Eric Snowac02ef32015-06-02 20:42:14 -06001949 self.assertEqual(od.setdefault('g', default=9), 9)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001950
Raymond Hettingera673b1f2010-12-31 23:16:17 +00001951 # make sure setdefault still works when __missing__ is defined
1952 class Missing(OrderedDict):
1953 def __missing__(self, key):
1954 return 0
1955 self.assertEqual(Missing().setdefault(5, 9), 9)
1956
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001957 def test_reinsert(self):
Eric Snow47db7172015-05-29 22:21:39 -06001958 OrderedDict = self.module.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001959 # Given insert a, insert b, delete a, re-insert a,
1960 # verify that a is now later than b.
1961 od = OrderedDict()
1962 od['a'] = 1
1963 od['b'] = 2
1964 del od['a']
Eric Snow47db7172015-05-29 22:21:39 -06001965 self.assertEqual(list(od.items()), [('b', 2)])
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001966 od['a'] = 1
1967 self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
1968
Raymond Hettingerf45abc92010-09-06 21:26:09 +00001969 def test_move_to_end(self):
Eric Snow47db7172015-05-29 22:21:39 -06001970 OrderedDict = self.module.OrderedDict
Raymond Hettingerf45abc92010-09-06 21:26:09 +00001971 od = OrderedDict.fromkeys('abcde')
1972 self.assertEqual(list(od), list('abcde'))
1973 od.move_to_end('c')
1974 self.assertEqual(list(od), list('abdec'))
1975 od.move_to_end('c', 0)
1976 self.assertEqual(list(od), list('cabde'))
1977 od.move_to_end('c', 0)
1978 self.assertEqual(list(od), list('cabde'))
1979 od.move_to_end('e')
1980 self.assertEqual(list(od), list('cabde'))
Eric Snowac02ef32015-06-02 20:42:14 -06001981 od.move_to_end('b', last=False)
1982 self.assertEqual(list(od), list('bcade'))
Raymond Hettingerf45abc92010-09-06 21:26:09 +00001983 with self.assertRaises(KeyError):
1984 od.move_to_end('x')
Eric Snow47db7172015-05-29 22:21:39 -06001985 with self.assertRaises(KeyError):
1986 od.move_to_end('x', 0)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00001987
Raymond Hettinger35c87f22010-09-16 19:10:17 +00001988 def test_sizeof(self):
Eric Snow47db7172015-05-29 22:21:39 -06001989 OrderedDict = self.module.OrderedDict
Raymond Hettinger35c87f22010-09-16 19:10:17 +00001990 # Wimpy test: Just verify the reported size is larger than a regular dict
1991 d = dict(a=1)
1992 od = OrderedDict(**d)
1993 self.assertGreater(sys.getsizeof(od), sys.getsizeof(d))
1994
Raymond Hettinger32062e92011-01-01 22:38:00 +00001995 def test_override_update(self):
Eric Snow47db7172015-05-29 22:21:39 -06001996 OrderedDict = self.module.OrderedDict
Raymond Hettinger32062e92011-01-01 22:38:00 +00001997 # Verify that subclasses can override update() without breaking __init__()
1998 class MyOD(OrderedDict):
1999 def update(self, *args, **kwds):
2000 raise Exception()
2001 items = [('a', 1), ('c', 3), ('b', 2)]
2002 self.assertEqual(list(MyOD(items).items()), items)
2003
Eric Snow47db7172015-05-29 22:21:39 -06002004
2005class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
2006
2007 module = py_coll
2008
2009
2010@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
2011class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
2012
2013 module = c_coll
2014
2015 def test_delitem_hash_collision(self):
2016 OrderedDict = self.module.OrderedDict
2017
2018 class Key:
2019 def __init__(self, hash):
2020 self._hash = hash
2021 self.value = str(id(self))
2022 def __hash__(self):
2023 return self._hash
2024 def __eq__(self, other):
2025 try:
2026 return self.value == other.value
2027 except AttributeError:
2028 return False
2029 def __repr__(self):
2030 return self.value
2031
2032 def blocking_hash(hash):
2033 # See the collision-handling in lookdict (in Objects/dictobject.c).
2034 MINSIZE = 8
2035 i = (hash & MINSIZE-1)
2036 return (i << 2) + i + hash + 1
2037
2038 COLLIDING = 1
2039
2040 key = Key(COLLIDING)
2041 colliding = Key(COLLIDING)
2042 blocking = Key(blocking_hash(COLLIDING))
2043
2044 od = OrderedDict()
2045 od[key] = ...
2046 od[blocking] = ...
2047 od[colliding] = ...
2048 od['after'] = ...
2049
2050 del od[blocking]
2051 del od[colliding]
2052 self.assertEqual(list(od.items()), [(key, ...), ('after', ...)])
2053
Eric Snow4fabf022015-06-04 00:09:56 -06002054 def test_key_change_during_iteration(self):
2055 OrderedDict = self.module.OrderedDict
2056
2057 od = OrderedDict.fromkeys('abcde')
2058 self.assertEqual(list(od), list('abcde'))
2059 with self.assertRaises(RuntimeError):
2060 for i, k in enumerate(od):
2061 od.move_to_end(k)
2062 self.assertLess(i, 5)
2063 with self.assertRaises(RuntimeError):
2064 for k in od:
2065 od['f'] = None
2066 with self.assertRaises(RuntimeError):
2067 for k in od:
2068 del od['c']
2069 self.assertEqual(list(od), list('bdeaf'))
2070
Eric Snowa762af72015-06-01 22:59:08 -06002071 def test_issue24347(self):
2072 OrderedDict = self.module.OrderedDict
2073
2074 class Key:
2075 def __hash__(self):
2076 return randrange(100000)
2077
2078 od = OrderedDict()
2079 for i in range(100):
2080 key = Key()
2081 od[key] = i
2082
2083 # These should not crash.
2084 with self.assertRaises(KeyError):
2085 repr(od)
2086 with self.assertRaises(KeyError):
2087 od.copy()
2088
Eric Snowd1719752015-06-01 23:12:13 -06002089 def test_issue24348(self):
2090 OrderedDict = self.module.OrderedDict
2091
2092 class Key:
2093 def __hash__(self):
2094 return 1
2095
2096 od = OrderedDict()
2097 od[Key()] = 0
2098 # This should not crash.
2099 od.popitem()
2100
Eric Snow8c7f9552015-08-07 17:45:12 -06002101 def test_issue24667(self):
2102 """
2103 dict resizes after a certain number of insertion operations,
2104 whether or not there were deletions that freed up slots in the
2105 hash table. During fast node lookup, OrderedDict must correctly
2106 respond to all resizes, even if the current "size" is the same
2107 as the old one. We verify that here by forcing a dict resize
2108 on a sparse odict and then perform an operation that should
2109 trigger an odict resize (e.g. popitem). One key aspect here is
2110 that we will keep the size of the odict the same at each popitem
2111 call. This verifies that we handled the dict resize properly.
2112 """
2113 OrderedDict = self.module.OrderedDict
2114
2115 od = OrderedDict()
2116 for c0 in '0123456789ABCDEF':
2117 for c1 in '0123456789ABCDEF':
2118 if len(od) == 4:
2119 # This should not raise a KeyError.
2120 od.popitem(last=False)
2121 key = c0 + c1
2122 od[key] = key
2123
Eric Snow47db7172015-05-29 22:21:39 -06002124
2125class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
2126
2127 @classmethod
2128 def setUpClass(cls):
2129 cls.type2test = py_coll.OrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002130
Raymond Hettingerdc879f02009-03-19 20:30:56 +00002131 def test_popitem(self):
2132 d = self._empty_mapping()
2133 self.assertRaises(KeyError, d.popitem)
2134
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002135
Eric Snow47db7172015-05-29 22:21:39 -06002136@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
2137class CPythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
2138
2139 @classmethod
2140 def setUpClass(cls):
2141 cls.type2test = c_coll.OrderedDict
2142
2143 def test_popitem(self):
2144 d = self._empty_mapping()
2145 self.assertRaises(KeyError, d.popitem)
2146
2147
2148class PurePythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
2149
2150 @classmethod
2151 def setUpClass(cls):
2152 class MyOrderedDict(py_coll.OrderedDict):
2153 pass
2154 cls.type2test = MyOrderedDict
2155
2156 def test_popitem(self):
2157 d = self._empty_mapping()
2158 self.assertRaises(KeyError, d.popitem)
2159
2160
2161@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
2162class CPythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
2163
2164 @classmethod
2165 def setUpClass(cls):
2166 class MyOrderedDict(c_coll.OrderedDict):
2167 pass
2168 cls.type2test = MyOrderedDict
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002169
Raymond Hettingerdc879f02009-03-19 20:30:56 +00002170 def test_popitem(self):
2171 d = self._empty_mapping()
2172 self.assertRaises(KeyError, d.popitem)
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002173
2174
Raymond Hettinger499e1932011-02-23 07:56:53 +00002175################################################################################
2176### Run tests
2177################################################################################
2178
Christian Heimes25bb7832008-01-11 16:17:00 +00002179import doctest, collections
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002180
Guido van Rossumd8faa362007-04-27 19:54:29 +00002181def test_main(verbose=None):
Benjamin Petersonad9d48d2008-04-02 21:49:44 +00002182 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerb8baf632009-01-14 02:20:07 +00002183 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerd0321312011-02-26 06:53:58 +00002184 TestCollectionABCs, TestCounter, TestChainMap,
Eric Snow47db7172015-05-29 22:21:39 -06002185 PurePythonOrderedDictTests, CPythonOrderedDictTests,
2186 PurePythonGeneralMappingTests, CPythonGeneralMappingTests,
2187 PurePythonSubclassMappingTests, CPythonSubclassMappingTests,
2188 TestUserObjects,
2189 ]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002190 support.run_unittest(*test_classes)
2191 support.run_doctest(collections, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002192
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002193
Guido van Rossumd8faa362007-04-27 19:54:29 +00002194if __name__ == "__main__":
2195 test_main(verbose=True)