blob: de4ba86df844f57cf5b900b9695bfd7d99f0d8ed [file] [log] [blame]
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001
Benjamin Petersoneb318d32010-05-21 20:51:45 +00002import unittest, doctest, operator
Raymond Hettingerbc512d32009-03-03 04:45:34 +00003import inspect
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00004from test import test_support
Raymond Hettingerbc512d32009-03-03 04:45:34 +00005from collections import namedtuple, Counter, OrderedDict
6from test import mapping_tests
Raymond Hettingere98839a2008-06-09 01:28:30 +00007import pickle, cPickle, copy
Raymond Hettingerbc512d32009-03-03 04:45:34 +00008from random import randrange, shuffle
Raymond Hettingera68cad12009-05-27 02:24:45 +00009import keyword
10import re
Raymond Hettingerf643b9a2014-05-25 22:13:41 -070011import sets
R. David Murrayf28fd242010-02-23 00:24:49 +000012import sys
Guido van Rossum64c06e32007-11-22 00:55:51 +000013from collections import Hashable, Iterable, Iterator
14from collections import Sized, Container, Callable
15from collections import Set, MutableSet
16from collections import Mapping, MutableMapping
17from collections import Sequence, MutableSequence
18
Raymond Hettingere98839a2008-06-09 01:28:30 +000019TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000020
Raymond Hettinger7393c692013-05-27 10:58:55 -070021py273_named_tuple_pickle = '''\
22ccopy_reg
23_reconstructor
24p0
25(ctest.test_collections
26TestNT
27p1
28c__builtin__
29tuple
30p2
31(I10
32I20
33I30
34tp3
35tp4
36Rp5
37ccollections
38OrderedDict
39p6
40((lp7
41(lp8
42S'x'
43p9
44aI10
45aa(lp10
46S'y'
47p11
48aI20
49aa(lp12
50S'z'
51p13
52aI30
53aatp14
54Rp15
55b.
56'''
57
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000058class TestNamedTuple(unittest.TestCase):
59
60 def test_factory(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +000061 Point = namedtuple('Point', 'x y')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000062 self.assertEqual(Point.__name__, 'Point')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000063 self.assertEqual(Point.__slots__, ())
64 self.assertEqual(Point.__module__, __name__)
65 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Raymond Hettingere0734e72008-01-04 03:22:53 +000066 self.assertEqual(Point._fields, ('x', 'y'))
Raymond Hettingerabfd8df2007-10-16 21:28:32 +000067
Raymond Hettinger01a09572007-10-23 20:37:41 +000068 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
69 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
70 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
Raymond Hettingerabfd8df2007-10-16 21:28:32 +000071
Raymond Hettinger01a09572007-10-23 20:37:41 +000072 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
73 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
74 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Raymond Hettinger42da8742007-12-14 02:49:47 +000075 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Raymond Hettinger01a09572007-10-23 20:37:41 +000076 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
Raymond Hettingerabfd8df2007-10-16 21:28:32 +000077
Raymond Hettinger01a09572007-10-23 20:37:41 +000078 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Raymond Hettinger42da8742007-12-14 02:49:47 +000079 namedtuple('_', 'a b c') # Test leading underscores in a typename
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000080
Raymond Hettinger6ee7bc02008-09-25 23:31:52 +000081 nt = namedtuple('nt', u'the quick brown fox') # check unicode input
Ezio Melottiaa980582010-01-23 23:04:36 +000082 self.assertNotIn("u'", repr(nt._fields))
Raymond Hettinger6ee7bc02008-09-25 23:31:52 +000083 nt = namedtuple('nt', (u'the', u'quick')) # check unicode input
Ezio Melottiaa980582010-01-23 23:04:36 +000084 self.assertNotIn("u'", repr(nt._fields))
Raymond Hettinger6ee7bc02008-09-25 23:31:52 +000085
Raymond Hettinger02740f72008-01-05 01:35:43 +000086 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
87 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
88
R. David Murrayf28fd242010-02-23 00:24:49 +000089 @unittest.skipIf(sys.flags.optimize >= 2,
90 "Docstrings are omitted with -O2 and above")
91 def test_factory_doc_attr(self):
92 Point = namedtuple('Point', 'x y')
93 self.assertEqual(Point.__doc__, 'Point(x, y)')
94
Raymond Hettinger322daea2009-02-10 01:24:05 +000095 def test_name_fixer(self):
96 for spec, renamed in [
Raymond Hettinger756ab672009-04-02 22:25:40 +000097 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
98 [('abc', 'class'), ('abc', '_1')], # field has keyword
99 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
100 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
101 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
102 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Raymond Hettinger322daea2009-02-10 01:24:05 +0000103 ]:
104 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
105
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000106 def test_instance(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +0000107 Point = namedtuple('Point', 'x y')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000108 p = Point(11, 22)
109 self.assertEqual(p, Point(x=11, y=22))
110 self.assertEqual(p, Point(11, y=22))
111 self.assertEqual(p, Point(y=22, x=11))
112 self.assertEqual(p, Point(*(11, 22)))
113 self.assertEqual(p, Point(**dict(x=11, y=22)))
114 self.assertRaises(TypeError, Point, 1) # too few args
115 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
116 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
117 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
118 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Ezio Melottiaa980582010-01-23 23:04:36 +0000119 self.assertNotIn('__weakref__', dir(p))
Raymond Hettinger02740f72008-01-05 01:35:43 +0000120 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Raymond Hettinger42da8742007-12-14 02:49:47 +0000121 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
122 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
123 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Raymond Hettinger7393c692013-05-27 10:58:55 -0700124 self.assertEqual(vars(p), p._asdict()) # verify that vars() works
Raymond Hettingerd36a60e2007-09-17 00:55:00 +0000125
Raymond Hettinger1b50fd72008-01-05 02:17:24 +0000126 try:
127 p._replace(x=1, error=2)
128 except ValueError:
129 pass
130 else:
131 self._fail('Did not detect an incorrect fieldname')
132
Raymond Hettingerd36a60e2007-09-17 00:55:00 +0000133 # verify that field string can have commas
Raymond Hettinger01a09572007-10-23 20:37:41 +0000134 Point = namedtuple('Point', 'x, y')
Raymond Hettingerd36a60e2007-09-17 00:55:00 +0000135 p = Point(x=11, y=22)
136 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000137
Raymond Hettinger2115bbc2007-10-08 09:14:28 +0000138 # verify that fieldspec can be a non-string sequence
Raymond Hettinger01a09572007-10-23 20:37:41 +0000139 Point = namedtuple('Point', ('x', 'y'))
Raymond Hettinger2115bbc2007-10-08 09:14:28 +0000140 p = Point(x=11, y=22)
141 self.assertEqual(repr(p), 'Point(x=11, y=22)')
142
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000143 def test_tupleness(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +0000144 Point = namedtuple('Point', 'x y')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000145 p = Point(11, 22)
146
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000147 self.assertIsInstance(p, tuple)
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000148 self.assertEqual(p, (11, 22)) # matches a real tuple
149 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
150 self.assertEqual(list(p), [11, 22]) # coercable to a list
151 self.assertEqual(max(p), 22) # iterable
152 self.assertEqual(max(*p), 22) # star-able
153 x, y = p
154 self.assertEqual(p, (x, y)) # unpacks like a tuple
155 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
156 self.assertRaises(IndexError, p.__getitem__, 3)
157
158 self.assertEqual(p.x, x)
159 self.assertEqual(p.y, y)
160 self.assertRaises(AttributeError, eval, 'p.z', locals())
161
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000162 def test_odd_sizes(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +0000163 Zero = namedtuple('Zero', '')
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000164 self.assertEqual(Zero(), ())
Raymond Hettinger02740f72008-01-05 01:35:43 +0000165 self.assertEqual(Zero._make([]), ())
Raymond Hettinger88880b22007-12-18 00:13:45 +0000166 self.assertEqual(repr(Zero()), 'Zero()')
167 self.assertEqual(Zero()._asdict(), {})
168 self.assertEqual(Zero()._fields, ())
169
Raymond Hettinger01a09572007-10-23 20:37:41 +0000170 Dot = namedtuple('Dot', 'd')
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000171 self.assertEqual(Dot(1), (1,))
Raymond Hettinger02740f72008-01-05 01:35:43 +0000172 self.assertEqual(Dot._make([1]), (1,))
Raymond Hettinger88880b22007-12-18 00:13:45 +0000173 self.assertEqual(Dot(1).d, 1)
174 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
175 self.assertEqual(Dot(1)._asdict(), {'d':1})
176 self.assertEqual(Dot(1)._replace(d=999), (999,))
177 self.assertEqual(Dot(1)._fields, ('d',))
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000178
Raymond Hettingere98839a2008-06-09 01:28:30 +0000179 n = 5000
Raymond Hettinger88880b22007-12-18 00:13:45 +0000180 import string, random
Georg Brandl0bb02992008-05-18 10:39:26 +0000181 names = list(set(''.join([random.choice(string.ascii_letters)
182 for j in range(10)]) for i in range(n)))
183 n = len(names)
Raymond Hettinger88880b22007-12-18 00:13:45 +0000184 Big = namedtuple('Big', names)
185 b = Big(*range(n))
186 self.assertEqual(b, tuple(range(n)))
Raymond Hettinger02740f72008-01-05 01:35:43 +0000187 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Raymond Hettinger88880b22007-12-18 00:13:45 +0000188 for pos, name in enumerate(names):
189 self.assertEqual(getattr(b, name), pos)
190 repr(b) # make sure repr() doesn't blow-up
191 d = b._asdict()
192 d_expected = dict(zip(names, range(n)))
193 self.assertEqual(d, d_expected)
194 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
195 b2_expected = range(n)
196 b2_expected[1] = 999
197 b2_expected[-5] = 42
198 self.assertEqual(b2, tuple(b2_expected))
199 self.assertEqual(b._fields, tuple(names))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000200
Raymond Hettingere98839a2008-06-09 01:28:30 +0000201 def test_pickle(self):
202 p = TestNT(x=10, y=20, z=30)
203 for module in pickle, cPickle:
204 loads = getattr(module, 'loads')
205 dumps = getattr(module, 'dumps')
206 for protocol in -1, 0, 1, 2:
207 q = loads(dumps(p, protocol))
208 self.assertEqual(p, q)
209 self.assertEqual(p._fields, q._fields)
210
211 def test_copy(self):
212 p = TestNT(x=10, y=20, z=30)
213 for copier in copy.copy, copy.deepcopy:
214 q = copier(p)
215 self.assertEqual(p, q)
216 self.assertEqual(p._fields, q._fields)
217
Raymond Hettingera68cad12009-05-27 02:24:45 +0000218 def test_name_conflicts(self):
219 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
220 # failed when used as field names. Test to make sure these now work.
221 T = namedtuple('T', 'itemgetter property self cls tuple')
222 t = T(1, 2, 3, 4, 5)
223 self.assertEqual(t, (1,2,3,4,5))
224 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
225 self.assertEqual(newt, (10,20,30,40,50))
226
227 # Broader test of all interesting names in a template
228 with test_support.captured_stdout() as template:
229 T = namedtuple('T', 'x', verbose=True)
230 words = set(re.findall('[A-Za-z]+', template.getvalue()))
231 words -= set(keyword.kwlist)
232 T = namedtuple('T', words)
233 # test __new__
234 values = tuple(range(len(words)))
235 t = T(*values)
236 self.assertEqual(t, values)
237 t = T(**dict(zip(T._fields, values)))
238 self.assertEqual(t, values)
239 # test _make
240 t = T._make(values)
241 self.assertEqual(t, values)
242 # exercise __repr__
243 repr(t)
244 # test _asdict
245 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
246 # test _replace
247 t = T._make(values)
248 newvalues = tuple(v*10 for v in values)
249 newt = t._replace(**dict(zip(T._fields, newvalues)))
250 self.assertEqual(newt, newvalues)
251 # test _fields
252 self.assertEqual(T._fields, tuple(words))
253 # test __getnewargs__
254 self.assertEqual(t.__getnewargs__(), values)
255
Raymond Hettinger7393c692013-05-27 10:58:55 -0700256 def test_pickling_bug_18015(self):
257 # http://bugs.python.org/issue18015
258 pt = pickle.loads(py273_named_tuple_pickle)
259 self.assertEqual(pt.x, 10)
260
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000261class ABCTestCase(unittest.TestCase):
262
263 def validate_abstract_methods(self, abc, *names):
264 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
265
266 # everything should work will all required methods are present
267 C = type('C', (abc,), methodstubs)
268 C()
269
270 # instantiation should fail if a required method is missing
271 for name in names:
272 stubs = methodstubs.copy()
273 del stubs[name]
274 C = type('C', (abc,), stubs)
275 self.assertRaises(TypeError, C, name)
276
Florent Xicluna47627d52010-03-08 15:20:28 +0000277 def validate_isinstance(self, abc, name):
278 stub = lambda s, *args: 0
279
280 # new-style class
281 C = type('C', (object,), {name: stub})
282 self.assertIsInstance(C(), abc)
283 self.assertTrue(issubclass(C, abc))
284 # old-style class
285 class C: pass
286 setattr(C, name, stub)
287 self.assertIsInstance(C(), abc)
288 self.assertTrue(issubclass(C, abc))
289
290 # new-style class
291 C = type('C', (object,), {'__hash__': None})
292 self.assertNotIsInstance(C(), abc)
293 self.assertFalse(issubclass(C, abc))
294 # old-style class
295 class C: pass
296 self.assertNotIsInstance(C(), abc)
297 self.assertFalse(issubclass(C, abc))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000298
Benjamin Petersoneb318d32010-05-21 20:51:45 +0000299 def validate_comparison(self, instance):
300 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
301 operators = {}
302 for op in ops:
303 name = '__' + op + '__'
304 operators[name] = getattr(operator, name)
305
306 class Other:
307 def __init__(self):
308 self.right_side = False
309 def __eq__(self, other):
310 self.right_side = True
311 return True
312 __lt__ = __eq__
313 __gt__ = __eq__
314 __le__ = __eq__
315 __ge__ = __eq__
316 __ne__ = __eq__
317 __ror__ = __eq__
318 __rand__ = __eq__
319 __rxor__ = __eq__
320 __rsub__ = __eq__
321
322 for name, op in operators.items():
323 if not hasattr(instance, name):
324 continue
325 other = Other()
326 op(instance, other)
327 self.assertTrue(other.right_side,'Right side not called for %s.%s'
328 % (type(instance), name))
329
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000330class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossum64c06e32007-11-22 00:55:51 +0000331
332 def test_Hashable(self):
333 # Check some non-hashables
334 non_samples = [list(), set(), dict()]
335 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000336 self.assertNotIsInstance(x, Hashable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000337 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000338 # Check some hashables
339 samples = [None,
340 int(), float(), complex(),
341 str(),
342 tuple(), frozenset(),
343 int, list, object, type,
344 ]
345 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000346 self.assertIsInstance(x, Hashable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000347 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000348 self.assertRaises(TypeError, Hashable)
349 # Check direct subclassing
350 class H(Hashable):
351 def __hash__(self):
352 return super(H, self).__hash__()
Nick Coghlan48361f52008-08-11 15:45:58 +0000353 __eq__ = Hashable.__eq__ # Silence Py3k warning
Guido van Rossum64c06e32007-11-22 00:55:51 +0000354 self.assertEqual(hash(H()), 0)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000355 self.assertFalse(issubclass(int, H))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000356 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000357 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000358
359 def test_Iterable(self):
360 # Check some non-iterables
361 non_samples = [None, 42, 3.14, 1j]
362 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000363 self.assertNotIsInstance(x, Iterable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000364 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000365 # Check some iterables
366 samples = [str(),
367 tuple(), list(), set(), frozenset(), dict(),
368 dict().keys(), dict().items(), dict().values(),
369 (lambda: (yield))(),
370 (x for x in []),
371 ]
372 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000373 self.assertIsInstance(x, Iterable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000374 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000375 # Check direct subclassing
376 class I(Iterable):
377 def __iter__(self):
378 return super(I, self).__iter__()
379 self.assertEqual(list(I()), [])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000380 self.assertFalse(issubclass(str, I))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000381 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000382 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000383
384 def test_Iterator(self):
385 non_samples = [None, 42, 3.14, 1j, "".encode('ascii'), "", (), [],
386 {}, set()]
387 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000388 self.assertNotIsInstance(x, Iterator)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000389 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000390 samples = [iter(str()),
391 iter(tuple()), iter(list()), iter(dict()),
392 iter(set()), iter(frozenset()),
393 iter(dict().keys()), iter(dict().items()),
394 iter(dict().values()),
395 (lambda: (yield))(),
396 (x for x in []),
397 ]
398 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000399 self.assertIsInstance(x, Iterator)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000400 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Alexander Belopolsky1fea5c42010-11-30 01:18:17 +0000401 self.validate_abstract_methods(Iterator, 'next', '__iter__')
402
403 # Issue 10565
404 class NextOnly:
405 def __next__(self):
406 yield 1
407 raise StopIteration
408 self.assertNotIsInstance(NextOnly(), Iterator)
409 class NextOnlyNew(object):
410 def __next__(self):
411 yield 1
412 raise StopIteration
413 self.assertNotIsInstance(NextOnlyNew(), Iterator)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000414
415 def test_Sized(self):
416 non_samples = [None, 42, 3.14, 1j,
417 (lambda: (yield))(),
418 (x for x in []),
419 ]
420 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000421 self.assertNotIsInstance(x, Sized)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000422 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000423 samples = [str(),
424 tuple(), list(), set(), frozenset(), dict(),
425 dict().keys(), dict().items(), dict().values(),
426 ]
427 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000428 self.assertIsInstance(x, Sized)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000429 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000430 self.validate_abstract_methods(Sized, '__len__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000431 self.validate_isinstance(Sized, '__len__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000432
433 def test_Container(self):
434 non_samples = [None, 42, 3.14, 1j,
435 (lambda: (yield))(),
436 (x for x in []),
437 ]
438 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000439 self.assertNotIsInstance(x, Container)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000440 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000441 samples = [str(),
442 tuple(), list(), set(), frozenset(), dict(),
443 dict().keys(), dict().items(),
444 ]
445 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000446 self.assertIsInstance(x, Container)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000447 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000448 self.validate_abstract_methods(Container, '__contains__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000449 self.validate_isinstance(Container, '__contains__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000450
451 def test_Callable(self):
452 non_samples = [None, 42, 3.14, 1j,
453 "", "".encode('ascii'), (), [], {}, set(),
454 (lambda: (yield))(),
455 (x for x in []),
456 ]
457 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000458 self.assertNotIsInstance(x, Callable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000459 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000460 samples = [lambda: None,
461 type, int, object,
462 len,
463 list.append, [].append,
464 ]
465 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000466 self.assertIsInstance(x, Callable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000467 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000468 self.validate_abstract_methods(Callable, '__call__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000469 self.validate_isinstance(Callable, '__call__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000470
471 def test_direct_subclassing(self):
472 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
473 class C(B):
474 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000475 self.assertTrue(issubclass(C, B))
476 self.assertFalse(issubclass(int, C))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000477
478 def test_registration(self):
479 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
480 class C:
481 __metaclass__ = type
482 __hash__ = None # Make sure it isn't hashable by default
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000483 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000484 B.register(C)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000485 self.assertTrue(issubclass(C, B))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000486
Raymond Hettinger66c4a6b2009-04-01 18:50:56 +0000487class WithSet(MutableSet):
488
489 def __init__(self, it=()):
490 self.data = set(it)
491
492 def __len__(self):
493 return len(self.data)
494
495 def __iter__(self):
496 return iter(self.data)
497
498 def __contains__(self, item):
499 return item in self.data
500
501 def add(self, item):
502 self.data.add(item)
503
504 def discard(self, item):
505 self.data.discard(item)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000506
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000507class TestCollectionABCs(ABCTestCase):
Guido van Rossum64c06e32007-11-22 00:55:51 +0000508
509 # XXX For now, we only test some virtual inheritance properties.
510 # We should also test the proper behavior of the collection ABCs
511 # as real base classes or mix-in classes.
512
513 def test_Set(self):
514 for sample in [set, frozenset]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000515 self.assertIsInstance(sample(), Set)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000516 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000517 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Petersoneb318d32010-05-21 20:51:45 +0000518 class MySet(Set):
519 def __contains__(self, x):
520 return False
521 def __len__(self):
522 return 0
523 def __iter__(self):
524 return iter([])
525 self.validate_comparison(MySet())
Guido van Rossum64c06e32007-11-22 00:55:51 +0000526
Raymond Hettinger4c52f522008-06-23 03:29:28 +0000527 def test_hash_Set(self):
528 class OneTwoThreeSet(Set):
529 def __init__(self):
530 self.contents = [1, 2, 3]
531 def __contains__(self, x):
532 return x in self.contents
533 def __len__(self):
534 return len(self.contents)
535 def __iter__(self):
536 return iter(self.contents)
537 def __hash__(self):
538 return self._hash()
539 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000540 self.assertTrue(hash(a) == hash(b))
Raymond Hettinger4c52f522008-06-23 03:29:28 +0000541
Guido van Rossum64c06e32007-11-22 00:55:51 +0000542 def test_MutableSet(self):
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000543 self.assertIsInstance(set(), MutableSet)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000544 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000545 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000546 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000547 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
548 'add', 'discard')
549
Raymond Hettinger66c4a6b2009-04-01 18:50:56 +0000550 def test_issue_5647(self):
551 # MutableSet.__iand__ mutated the set during iteration
552 s = WithSet('abcd')
553 s &= WithSet('cdef') # This used to fail
554 self.assertEqual(set(s), set('cd'))
555
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000556 def test_issue_4920(self):
557 # MutableSet.pop() method did not work
558 class MySet(collections.MutableSet):
559 __slots__=['__s']
560 def __init__(self,items=None):
561 if items is None:
562 items=[]
563 self.__s=set(items)
564 def __contains__(self,v):
565 return v in self.__s
566 def __iter__(self):
567 return iter(self.__s)
568 def __len__(self):
569 return len(self.__s)
570 def add(self,v):
571 result=v not in self.__s
572 self.__s.add(v)
573 return result
574 def discard(self,v):
575 result=v in self.__s
576 self.__s.discard(v)
577 return result
578 def __repr__(self):
579 return "MySet(%s)" % repr(list(self))
580 s = MySet([5,43,2,1])
581 self.assertEqual(s.pop(), 1)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000582
Daniel Stutzbach91287322010-08-24 21:09:30 +0000583 def test_issue8750(self):
584 empty = WithSet()
585 full = WithSet(range(10))
586 s = WithSet(full)
587 s -= s
588 self.assertEqual(s, empty)
589 s = WithSet(full)
590 s ^= s
591 self.assertEqual(s, empty)
592 s = WithSet(full)
593 s &= s
594 self.assertEqual(s, full)
595 s |= s
596 self.assertEqual(s, full)
597
Serhiy Storchaka7c573852013-12-06 23:23:15 +0200598 def test_issue16373(self):
599 # Recursion error comparing comparable and noncomparable
600 # Set instances
601 class MyComparableSet(Set):
602 def __contains__(self, x):
603 return False
604 def __len__(self):
605 return 0
606 def __iter__(self):
607 return iter([])
608 class MyNonComparableSet(Set):
609 def __contains__(self, x):
610 return False
611 def __len__(self):
612 return 0
613 def __iter__(self):
614 return iter([])
615 def __le__(self, x):
616 return NotImplemented
617 def __lt__(self, x):
618 return NotImplemented
619
620 cs = MyComparableSet()
621 ncs = MyNonComparableSet()
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700622
623 # Run all the variants to make sure they don't mutually recurse
624 ncs < cs
625 ncs <= cs
626 ncs > cs
627 ncs >= cs
628 cs < ncs
629 cs <= ncs
630 cs > ncs
631 cs >= ncs
632
633 def assertSameSet(self, s1, s2):
634 # coerce both to a real set then check equality
635 self.assertEqual(set(s1), set(s2))
636
637 def test_Set_interoperability_with_real_sets(self):
638 # Issue: 8743
639 class ListSet(Set):
640 def __init__(self, elements=()):
641 self.data = []
642 for elem in elements:
643 if elem not in self.data:
644 self.data.append(elem)
645 def __contains__(self, elem):
646 return elem in self.data
647 def __iter__(self):
648 return iter(self.data)
649 def __len__(self):
650 return len(self.data)
651 def __repr__(self):
652 return 'Set({!r})'.format(self.data)
653
654 r1 = set('abc')
655 r2 = set('bcd')
656 r3 = set('abcde')
657 f1 = ListSet('abc')
658 f2 = ListSet('bcd')
659 f3 = ListSet('abcde')
660 l1 = list('abccba')
661 l2 = list('bcddcb')
662 l3 = list('abcdeedcba')
663 p1 = sets.Set('abc')
664 p2 = sets.Set('bcd')
665 p3 = sets.Set('abcde')
666
667 target = r1 & r2
668 self.assertSameSet(f1 & f2, target)
669 self.assertSameSet(f1 & r2, target)
670 self.assertSameSet(r2 & f1, target)
671 self.assertSameSet(f1 & p2, target)
672 self.assertSameSet(p2 & f1, target)
673 self.assertSameSet(f1 & l2, target)
674
675 target = r1 | r2
676 self.assertSameSet(f1 | f2, target)
677 self.assertSameSet(f1 | r2, target)
678 self.assertSameSet(r2 | f1, target)
679 self.assertSameSet(f1 | p2, target)
680 self.assertSameSet(p2 | f1, target)
681 self.assertSameSet(f1 | l2, target)
682
683 fwd_target = r1 - r2
684 rev_target = r2 - r1
685 self.assertSameSet(f1 - f2, fwd_target)
686 self.assertSameSet(f2 - f1, rev_target)
687 self.assertSameSet(f1 - r2, fwd_target)
688 self.assertSameSet(f2 - r1, rev_target)
689 self.assertSameSet(r1 - f2, fwd_target)
690 self.assertSameSet(r2 - f1, rev_target)
691 self.assertSameSet(f1 - p2, fwd_target)
692 self.assertSameSet(f2 - p1, rev_target)
693 self.assertSameSet(p1 - f2, fwd_target)
694 self.assertSameSet(p2 - f1, rev_target)
695 self.assertSameSet(f1 - l2, fwd_target)
696 self.assertSameSet(f2 - l1, rev_target)
697
698 target = r1 ^ r2
699 self.assertSameSet(f1 ^ f2, target)
700 self.assertSameSet(f1 ^ r2, target)
701 self.assertSameSet(r2 ^ f1, target)
702 self.assertSameSet(f1 ^ p2, target)
703 self.assertSameSet(p2 ^ f1, target)
704 self.assertSameSet(f1 ^ l2, target)
705
706 # proper subset
707 self.assertTrue(f1 < f3)
708 self.assertFalse(f1 < f1)
709 self.assertFalse(f1 < f2)
710 self.assertTrue(r1 < f3)
711 self.assertFalse(r1 < f1)
712 self.assertFalse(r1 < f2)
713 self.assertTrue(r1 < r3)
714 self.assertFalse(r1 < r1)
715 self.assertFalse(r1 < r2)
716 # python 2 only, cross-type compares will succeed
717 f1 < l3
718 f1 < l1
719 f1 < l2
720
721 # any subset
722 self.assertTrue(f1 <= f3)
723 self.assertTrue(f1 <= f1)
724 self.assertFalse(f1 <= f2)
725 self.assertTrue(r1 <= f3)
726 self.assertTrue(r1 <= f1)
727 self.assertFalse(r1 <= f2)
728 self.assertTrue(r1 <= r3)
729 self.assertTrue(r1 <= r1)
730 self.assertFalse(r1 <= r2)
731 # python 2 only, cross-type compares will succeed
732 f1 <= l3
733 f1 <= l1
734 f1 <= l2
735
736 # proper superset
737 self.assertTrue(f3 > f1)
738 self.assertFalse(f1 > f1)
739 self.assertFalse(f2 > f1)
740 self.assertTrue(r3 > r1)
741 self.assertFalse(f1 > r1)
742 self.assertFalse(f2 > r1)
743 self.assertTrue(r3 > r1)
744 self.assertFalse(r1 > r1)
745 self.assertFalse(r2 > r1)
746 # python 2 only, cross-type compares will succeed
747 f1 > l3
748 f1 > l1
749 f1 > l2
750
751 # any superset
752 self.assertTrue(f3 >= f1)
753 self.assertTrue(f1 >= f1)
754 self.assertFalse(f2 >= f1)
755 self.assertTrue(r3 >= r1)
756 self.assertTrue(f1 >= r1)
757 self.assertFalse(f2 >= r1)
758 self.assertTrue(r3 >= r1)
759 self.assertTrue(r1 >= r1)
760 self.assertFalse(r2 >= r1)
761 # python 2 only, cross-type compares will succeed
762 f1 >= l3
763 f1 >=l1
764 f1 >= l2
765
766 # equality
767 self.assertTrue(f1 == f1)
768 self.assertTrue(r1 == f1)
769 self.assertTrue(f1 == r1)
770 self.assertFalse(f1 == f3)
771 self.assertFalse(r1 == f3)
772 self.assertFalse(f1 == r3)
773 # python 2 only, cross-type compares will succeed
774 f1 == l3
775 f1 == l1
776 f1 == l2
777
778 # inequality
779 self.assertFalse(f1 != f1)
780 self.assertFalse(r1 != f1)
781 self.assertFalse(f1 != r1)
782 self.assertTrue(f1 != f3)
783 self.assertTrue(r1 != f3)
784 self.assertTrue(f1 != r3)
785 # python 2 only, cross-type compares will succeed
786 f1 != l3
787 f1 != l1
788 f1 != l2
Serhiy Storchaka7c573852013-12-06 23:23:15 +0200789
Guido van Rossum64c06e32007-11-22 00:55:51 +0000790 def test_Mapping(self):
791 for sample in [dict]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000792 self.assertIsInstance(sample(), Mapping)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000793 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000794 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
795 '__getitem__')
Benjamin Petersoneb318d32010-05-21 20:51:45 +0000796 class MyMapping(collections.Mapping):
797 def __len__(self):
798 return 0
799 def __getitem__(self, i):
800 raise IndexError
801 def __iter__(self):
802 return iter(())
803 self.validate_comparison(MyMapping())
Guido van Rossum64c06e32007-11-22 00:55:51 +0000804
805 def test_MutableMapping(self):
806 for sample in [dict]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000807 self.assertIsInstance(sample(), MutableMapping)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000808 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000809 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
810 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000811
812 def test_Sequence(self):
813 for sample in [tuple, list, str]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000814 self.assertIsInstance(sample(), Sequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000815 self.assertTrue(issubclass(sample, Sequence))
816 self.assertTrue(issubclass(basestring, Sequence))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000817 self.assertIsInstance(range(10), Sequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000818 self.assertTrue(issubclass(xrange, Sequence))
819 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000820 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
821 '__getitem__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000822
823 def test_MutableSequence(self):
824 for sample in [tuple, str]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000825 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000826 self.assertFalse(issubclass(sample, MutableSequence))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000827 for sample in [list]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000828 self.assertIsInstance(sample(), MutableSequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000829 self.assertTrue(issubclass(sample, MutableSequence))
830 self.assertFalse(issubclass(basestring, MutableSequence))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000831 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
832 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000833
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000834class TestCounter(unittest.TestCase):
835
836 def test_basics(self):
837 c = Counter('abcaba')
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000838 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
839 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000840 self.assertIsInstance(c, dict)
841 self.assertIsInstance(c, Mapping)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000842 self.assertTrue(issubclass(Counter, dict))
843 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000844 self.assertEqual(len(c), 3)
845 self.assertEqual(sum(c.values()), 6)
846 self.assertEqual(sorted(c.values()), [1, 2, 3])
847 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
848 self.assertEqual(sorted(c), ['a', 'b', 'c'])
849 self.assertEqual(sorted(c.items()),
850 [('a', 3), ('b', 2), ('c', 1)])
851 self.assertEqual(c['b'], 2)
852 self.assertEqual(c['z'], 0)
Florent Xicluna47627d52010-03-08 15:20:28 +0000853 with test_support.check_py3k_warnings():
854 self.assertEqual(c.has_key('c'), True)
855 self.assertEqual(c.has_key('z'), False)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000856 self.assertEqual(c.__contains__('c'), True)
857 self.assertEqual(c.__contains__('z'), False)
858 self.assertEqual(c.get('b', 10), 2)
859 self.assertEqual(c.get('z', 10), 10)
860 self.assertEqual(c, dict(a=3, b=2, c=1))
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000861 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000862 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
863 for i in range(5):
864 self.assertEqual(c.most_common(i),
865 [('a', 3), ('b', 2), ('c', 1)][:i])
866 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
867 c['a'] += 1 # increment an existing value
868 c['b'] -= 2 # sub existing value to zero
869 del c['c'] # remove an entry
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000870 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000871 c['d'] -= 2 # sub from a missing value
872 c['e'] = -5 # directly assign a missing value
873 c['f'] += 4 # add to a missing value
874 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
875 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
876 self.assertEqual(c.pop('f'), 4)
Ezio Melottiaa980582010-01-23 23:04:36 +0000877 self.assertNotIn('f', c)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000878 for i in range(3):
879 elem, cnt = c.popitem()
Ezio Melottiaa980582010-01-23 23:04:36 +0000880 self.assertNotIn(elem, c)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000881 c.clear()
882 self.assertEqual(c, {})
883 self.assertEqual(repr(c), 'Counter()')
884 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
885 self.assertRaises(TypeError, hash, c)
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000886 c.update(dict(a=5, b=3))
887 c.update(c=1)
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000888 c.update(Counter('a' * 50 + 'b' * 30))
Raymond Hettingerafd112b2009-01-14 01:15:06 +0000889 c.update() # test case with no args
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000890 c.__init__('a' * 500 + 'b' * 300)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000891 c.__init__('cdc')
Raymond Hettingerafd112b2009-01-14 01:15:06 +0000892 c.__init__()
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000893 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
894 self.assertEqual(c.setdefault('d', 5), 1)
895 self.assertEqual(c['d'], 1)
896 self.assertEqual(c.setdefault('e', 5), 5)
897 self.assertEqual(c['e'], 5)
898
899 def test_copying(self):
900 # Check that counters are copyable, deepcopyable, picklable, and
901 #have a repr/eval round-trip
902 words = Counter('which witch had which witches wrist watch'.split())
903 update_test = Counter()
904 update_test.update(words)
905 for i, dup in enumerate([
906 words.copy(),
907 copy.copy(words),
908 copy.deepcopy(words),
909 pickle.loads(pickle.dumps(words, 0)),
910 pickle.loads(pickle.dumps(words, 1)),
911 pickle.loads(pickle.dumps(words, 2)),
912 pickle.loads(pickle.dumps(words, -1)),
913 cPickle.loads(cPickle.dumps(words, 0)),
914 cPickle.loads(cPickle.dumps(words, 1)),
915 cPickle.loads(cPickle.dumps(words, 2)),
916 cPickle.loads(cPickle.dumps(words, -1)),
917 eval(repr(words)),
918 update_test,
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000919 Counter(words),
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000920 ]):
921 msg = (i, dup, words)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000922 self.assertTrue(dup is not words)
Ezio Melotti2623a372010-11-21 13:34:58 +0000923 self.assertEqual(dup, words)
924 self.assertEqual(len(dup), len(words))
925 self.assertEqual(type(dup), type(words))
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000926
Raymond Hettinger37c0fe52011-04-15 13:12:21 -0700927 def test_copy_subclass(self):
928 class MyCounter(Counter):
929 pass
930 c = MyCounter('slartibartfast')
931 d = c.copy()
932 self.assertEqual(d, c)
933 self.assertEqual(len(d), len(c))
934 self.assertEqual(type(d), type(c))
935
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000936 def test_conversions(self):
937 # Convert to: set, list, dict
938 s = 'she sells sea shells by the sea shore'
939 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
940 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
941 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
942 self.assertEqual(set(Counter(s)), set(s))
943
Raymond Hettinger0a1f7b82009-01-21 23:12:51 +0000944 def test_invariant_for_the_in_operator(self):
945 c = Counter(a=10, b=-2, c=0)
946 for elem in c:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000947 self.assertTrue(elem in c)
Ezio Melottiaa980582010-01-23 23:04:36 +0000948 self.assertIn(elem, c)
Raymond Hettinger0a1f7b82009-01-21 23:12:51 +0000949
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000950 def test_multiset_operations(self):
951 # Verify that adding a zero counter will strip zeros and negatives
952 c = Counter(a=10, b=-2, c=0) + Counter()
953 self.assertEqual(dict(c), dict(a=10))
954
955 elements = 'abcd'
956 for i in range(1000):
957 # test random pairs of multisets
958 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettinger4571f342009-01-21 20:31:50 +0000959 p.update(e=1, f=-1, g=0)
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000960 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettinger4571f342009-01-21 20:31:50 +0000961 q.update(h=1, i=-1, j=0)
962 for counterop, numberop in [
963 (Counter.__add__, lambda x, y: max(0, x+y)),
964 (Counter.__sub__, lambda x, y: max(0, x-y)),
965 (Counter.__or__, lambda x, y: max(0,x,y)),
966 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000967 ]:
968 result = counterop(p, q)
969 for x in elements:
Raymond Hettinger4571f342009-01-21 20:31:50 +0000970 self.assertEqual(numberop(p[x], q[x]), result[x],
971 (counterop, x, p, q))
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000972 # verify that results exclude non-positive counts
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000973 self.assertTrue(x>0 for x in result.values())
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000974
975 elements = 'abcdef'
976 for i in range(100):
977 # verify that random multisets with no repeats are exactly like sets
978 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
979 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
980 for counterop, setop in [
981 (Counter.__sub__, set.__sub__),
982 (Counter.__or__, set.__or__),
983 (Counter.__and__, set.__and__),
984 ]:
985 counter_result = counterop(p, q)
986 set_result = setop(set(p.elements()), set(q.elements()))
987 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000988
Raymond Hettinger34c35b22010-04-03 10:22:00 +0000989 def test_subtract(self):
990 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
991 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
992 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
993 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
994 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
995 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
996 c = Counter('aaabbcd')
997 c.subtract('aaaabbcce')
998 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
999
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001000class TestOrderedDict(unittest.TestCase):
1001
1002 def test_init(self):
1003 with self.assertRaises(TypeError):
1004 OrderedDict([('a', 1), ('b', 2)], None) # too many args
1005 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1006 self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
1007 self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
1008 self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
1009 self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
1010 c=3, e=5).items()), pairs) # mixed input
1011
1012 # make sure no positional args conflict with possible kwdargs
1013 self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args,
1014 ['self'])
1015
1016 # Make sure that direct calls to __init__ do not clear previous contents
1017 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1018 d.__init__([('e', 5), ('f', 6)], g=7, d=4)
1019 self.assertEqual(list(d.items()),
1020 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1021
1022 def test_update(self):
1023 with self.assertRaises(TypeError):
1024 OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
1025 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1026 od = OrderedDict()
1027 od.update(dict(pairs))
1028 self.assertEqual(sorted(od.items()), pairs) # dict input
1029 od = OrderedDict()
1030 od.update(**dict(pairs))
1031 self.assertEqual(sorted(od.items()), pairs) # kwds input
1032 od = OrderedDict()
1033 od.update(pairs)
1034 self.assertEqual(list(od.items()), pairs) # pairs input
1035 od = OrderedDict()
1036 od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
1037 self.assertEqual(list(od.items()), pairs) # mixed input
1038
Mark Dickinson42add992010-07-11 19:17:28 +00001039 # Issue 9137: Named argument called 'other' or 'self'
1040 # shouldn't be treated specially.
1041 od = OrderedDict()
1042 od.update(self=23)
1043 self.assertEqual(list(od.items()), [('self', 23)])
1044 od = OrderedDict()
1045 od.update(other={})
1046 self.assertEqual(list(od.items()), [('other', {})])
1047 od = OrderedDict()
1048 od.update(red=5, blue=6, other=7, self=8)
1049 self.assertEqual(sorted(list(od.items())),
1050 [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
1051
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001052 # Make sure that direct calls to update do not clear previous contents
1053 # add that updates items are not moved to the end
1054 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1055 d.update([('e', 5), ('f', 6)], g=7, d=4)
1056 self.assertEqual(list(d.items()),
1057 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1058
Raymond Hettinger8ebebd82011-01-02 01:03:26 +00001059 def test_abc(self):
1060 self.assertIsInstance(OrderedDict(), MutableMapping)
1061 self.assertTrue(issubclass(OrderedDict, MutableMapping))
1062
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001063 def test_clear(self):
1064 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1065 shuffle(pairs)
1066 od = OrderedDict(pairs)
1067 self.assertEqual(len(od), len(pairs))
1068 od.clear()
1069 self.assertEqual(len(od), 0)
1070
1071 def test_delitem(self):
1072 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1073 od = OrderedDict(pairs)
1074 del od['a']
Ezio Melottiaa980582010-01-23 23:04:36 +00001075 self.assertNotIn('a', od)
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001076 with self.assertRaises(KeyError):
1077 del od['a']
1078 self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
1079
1080 def test_setitem(self):
1081 od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
1082 od['c'] = 10 # existing element
1083 od['f'] = 20 # new element
1084 self.assertEqual(list(od.items()),
1085 [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
1086
1087 def test_iterators(self):
1088 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1089 shuffle(pairs)
1090 od = OrderedDict(pairs)
1091 self.assertEqual(list(od), [t[0] for t in pairs])
Raymond Hettingerf17f81d2009-03-03 07:12:09 +00001092 self.assertEqual(od.keys()[:], [t[0] for t in pairs])
1093 self.assertEqual(od.values()[:], [t[1] for t in pairs])
1094 self.assertEqual(od.items()[:], pairs)
1095 self.assertEqual(list(od.iterkeys()), [t[0] for t in pairs])
1096 self.assertEqual(list(od.itervalues()), [t[1] for t in pairs])
1097 self.assertEqual(list(od.iteritems()), pairs)
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001098 self.assertEqual(list(reversed(od)),
1099 [t[0] for t in reversed(pairs)])
1100
1101 def test_popitem(self):
1102 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1103 shuffle(pairs)
1104 od = OrderedDict(pairs)
1105 while pairs:
1106 self.assertEqual(od.popitem(), pairs.pop())
1107 with self.assertRaises(KeyError):
1108 od.popitem()
1109 self.assertEqual(len(od), 0)
1110
1111 def test_pop(self):
1112 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1113 shuffle(pairs)
1114 od = OrderedDict(pairs)
1115 shuffle(pairs)
1116 while pairs:
1117 k, v = pairs.pop()
1118 self.assertEqual(od.pop(k), v)
1119 with self.assertRaises(KeyError):
1120 od.pop('xyz')
1121 self.assertEqual(len(od), 0)
1122 self.assertEqual(od.pop(k, 12345), 12345)
1123
Raymond Hettinger8ebebd82011-01-02 01:03:26 +00001124 # make sure pop still works when __missing__ is defined
1125 class Missing(OrderedDict):
1126 def __missing__(self, key):
1127 return 0
1128 m = Missing(a=1)
1129 self.assertEqual(m.pop('b', 5), 5)
1130 self.assertEqual(m.pop('a', 6), 1)
1131 self.assertEqual(m.pop('a', 6), 6)
1132 with self.assertRaises(KeyError):
1133 m.pop('a')
1134
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001135 def test_equality(self):
1136 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1137 shuffle(pairs)
1138 od1 = OrderedDict(pairs)
1139 od2 = OrderedDict(pairs)
1140 self.assertEqual(od1, od2) # same order implies equality
1141 pairs = pairs[2:] + pairs[:2]
1142 od2 = OrderedDict(pairs)
1143 self.assertNotEqual(od1, od2) # different order implies inequality
1144 # comparison to regular dict is not order sensitive
1145 self.assertEqual(od1, dict(od2))
1146 self.assertEqual(dict(od2), od1)
1147 # different length implied inequality
1148 self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
1149
1150 def test_copying(self):
1151 # Check that ordered dicts are copyable, deepcopyable, picklable,
1152 # and have a repr/eval round-trip
1153 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1154 od = OrderedDict(pairs)
1155 update_test = OrderedDict()
1156 update_test.update(od)
1157 for i, dup in enumerate([
1158 od.copy(),
1159 copy.copy(od),
1160 copy.deepcopy(od),
1161 pickle.loads(pickle.dumps(od, 0)),
1162 pickle.loads(pickle.dumps(od, 1)),
1163 pickle.loads(pickle.dumps(od, 2)),
1164 pickle.loads(pickle.dumps(od, -1)),
1165 eval(repr(od)),
1166 update_test,
1167 OrderedDict(od),
1168 ]):
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001169 self.assertTrue(dup is not od)
Ezio Melotti2623a372010-11-21 13:34:58 +00001170 self.assertEqual(dup, od)
1171 self.assertEqual(list(dup.items()), list(od.items()))
1172 self.assertEqual(len(dup), len(od))
1173 self.assertEqual(type(dup), type(od))
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001174
Raymond Hettinger131af652009-03-03 22:59:25 +00001175 def test_yaml_linkage(self):
1176 # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
1177 # In yaml, lists are native but tuples are not.
1178 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1179 od = OrderedDict(pairs)
1180 # yaml.dump(od) -->
1181 # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001182 self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
Raymond Hettinger131af652009-03-03 22:59:25 +00001183
1184 def test_reduce_not_too_fat(self):
1185 # do not save instance dictionary if not needed
1186 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1187 od = OrderedDict(pairs)
Alexandre Vassalotticb73bda2009-06-12 23:03:35 +00001188 self.assertEqual(len(od.__reduce__()), 2)
Raymond Hettinger131af652009-03-03 22:59:25 +00001189 od.x = 10
Alexandre Vassalotticb73bda2009-06-12 23:03:35 +00001190 self.assertEqual(len(od.__reduce__()), 3)
Raymond Hettinger131af652009-03-03 22:59:25 +00001191
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001192 def test_repr(self):
1193 od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
1194 self.assertEqual(repr(od),
1195 "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
1196 self.assertEqual(eval(repr(od)), od)
1197 self.assertEqual(repr(OrderedDict()), "OrderedDict()")
1198
Raymond Hettinger74f869e2010-09-13 22:14:36 +00001199 def test_repr_recursive(self):
1200 # See issue #9826
1201 od = OrderedDict.fromkeys('abc')
1202 od['x'] = od
1203 self.assertEqual(repr(od),
1204 "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
1205
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001206 def test_setdefault(self):
1207 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1208 shuffle(pairs)
1209 od = OrderedDict(pairs)
1210 pair_order = list(od.items())
1211 self.assertEqual(od.setdefault('a', 10), 3)
1212 # make sure order didn't change
1213 self.assertEqual(list(od.items()), pair_order)
1214 self.assertEqual(od.setdefault('x', 10), 10)
1215 # make sure 'x' is added to the end
1216 self.assertEqual(list(od.items())[-1], ('x', 10))
1217
Raymond Hettinger8ebebd82011-01-02 01:03:26 +00001218 # make sure setdefault still works when __missing__ is defined
1219 class Missing(OrderedDict):
1220 def __missing__(self, key):
1221 return 0
1222 self.assertEqual(Missing().setdefault(5, 9), 9)
1223
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001224 def test_reinsert(self):
1225 # Given insert a, insert b, delete a, re-insert a,
1226 # verify that a is now later than b.
1227 od = OrderedDict()
1228 od['a'] = 1
1229 od['b'] = 2
1230 del od['a']
1231 od['a'] = 1
1232 self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
1233
Raymond Hettingera54b2da2010-08-17 19:03:06 +00001234 def test_views(self):
1235 s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split()
1236 od = OrderedDict.fromkeys(s)
1237 self.assertEqual(list(od.viewkeys()), s)
1238 self.assertEqual(list(od.viewvalues()), [None for k in s])
1239 self.assertEqual(list(od.viewitems()), [(k, None) for k in s])
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001240
Raymond Hettinger8ebebd82011-01-02 01:03:26 +00001241 def test_override_update(self):
1242 # Verify that subclasses can override update() without breaking __init__()
1243 class MyOD(OrderedDict):
1244 def update(self, *args, **kwds):
1245 raise Exception()
1246 items = [('a', 1), ('c', 3), ('b', 2)]
1247 self.assertEqual(list(MyOD(items).items()), items)
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001248
1249class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
1250 type2test = OrderedDict
1251
Raymond Hettinger24122992009-03-19 19:59:58 +00001252 def test_popitem(self):
1253 d = self._empty_mapping()
1254 self.assertRaises(KeyError, d.popitem)
1255
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001256class MyOrderedDict(OrderedDict):
1257 pass
1258
1259class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
1260 type2test = MyOrderedDict
1261
Raymond Hettinger24122992009-03-19 19:59:58 +00001262 def test_popitem(self):
1263 d = self._empty_mapping()
1264 self.assertRaises(KeyError, d.popitem)
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001265
Georg Brandla4f46e12010-02-07 17:03:15 +00001266import collections
Guido van Rossum64c06e32007-11-22 00:55:51 +00001267
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00001268def test_main(verbose=None):
Amaury Forgeot d'Arccb0f2ad2008-04-02 00:55:04 +00001269 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +00001270 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001271 TestCollectionABCs, TestCounter,
1272 TestOrderedDict, GeneralMappingTests, SubclassMappingTests]
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00001273 test_support.run_unittest(*test_classes)
Amaury Forgeot d'Arccb0f2ad2008-04-02 00:55:04 +00001274 test_support.run_doctest(collections, verbose)
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00001275
1276if __name__ == "__main__":
1277 test_main(verbose=True)