blob: 6c9c407025c98fcd91a33932d0b2c87895d587dd [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
R. David Murrayf28fd242010-02-23 00:24:49 +000011import sys
Guido van Rossum64c06e32007-11-22 00:55:51 +000012from collections import Hashable, Iterable, Iterator
13from collections import Sized, Container, Callable
14from collections import Set, MutableSet
15from collections import Mapping, MutableMapping
16from collections import Sequence, MutableSequence
Victor Stinnera3acea32014-09-05 21:05:05 +020017with test_support.check_warnings(('', DeprecationWarning)):
18 import sets
Guido van Rossum64c06e32007-11-22 00:55:51 +000019
Raymond Hettingere98839a2008-06-09 01:28:30 +000020TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000021
Raymond Hettinger7393c692013-05-27 10:58:55 -070022py273_named_tuple_pickle = '''\
23ccopy_reg
24_reconstructor
25p0
26(ctest.test_collections
27TestNT
28p1
29c__builtin__
30tuple
31p2
32(I10
33I20
34I30
35tp3
36tp4
37Rp5
38ccollections
39OrderedDict
40p6
41((lp7
42(lp8
43S'x'
44p9
45aI10
46aa(lp10
47S'y'
48p11
49aI20
50aa(lp12
51S'z'
52p13
53aI30
54aatp14
55Rp15
56b.
57'''
58
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000059class TestNamedTuple(unittest.TestCase):
60
61 def test_factory(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +000062 Point = namedtuple('Point', 'x y')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000063 self.assertEqual(Point.__name__, 'Point')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000064 self.assertEqual(Point.__slots__, ())
65 self.assertEqual(Point.__module__, __name__)
66 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Raymond Hettingere0734e72008-01-04 03:22:53 +000067 self.assertEqual(Point._fields, ('x', 'y'))
Raymond Hettingerabfd8df2007-10-16 21:28:32 +000068
Raymond Hettinger01a09572007-10-23 20:37:41 +000069 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
70 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
71 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
Raymond Hettingerabfd8df2007-10-16 21:28:32 +000072
Raymond Hettinger01a09572007-10-23 20:37:41 +000073 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
74 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
75 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Raymond Hettinger42da8742007-12-14 02:49:47 +000076 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Raymond Hettinger01a09572007-10-23 20:37:41 +000077 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
Raymond Hettingerabfd8df2007-10-16 21:28:32 +000078
Raymond Hettinger01a09572007-10-23 20:37:41 +000079 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Raymond Hettinger42da8742007-12-14 02:49:47 +000080 namedtuple('_', 'a b c') # Test leading underscores in a typename
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000081
Raymond Hettinger6ee7bc02008-09-25 23:31:52 +000082 nt = namedtuple('nt', u'the quick brown fox') # check unicode input
Ezio Melottiaa980582010-01-23 23:04:36 +000083 self.assertNotIn("u'", repr(nt._fields))
Raymond Hettinger6ee7bc02008-09-25 23:31:52 +000084 nt = namedtuple('nt', (u'the', u'quick')) # check unicode input
Ezio Melottiaa980582010-01-23 23:04:36 +000085 self.assertNotIn("u'", repr(nt._fields))
Raymond Hettinger6ee7bc02008-09-25 23:31:52 +000086
Raymond Hettinger02740f72008-01-05 01:35:43 +000087 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
88 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
89
R. David Murrayf28fd242010-02-23 00:24:49 +000090 @unittest.skipIf(sys.flags.optimize >= 2,
91 "Docstrings are omitted with -O2 and above")
92 def test_factory_doc_attr(self):
93 Point = namedtuple('Point', 'x y')
94 self.assertEqual(Point.__doc__, 'Point(x, y)')
95
Raymond Hettinger322daea2009-02-10 01:24:05 +000096 def test_name_fixer(self):
97 for spec, renamed in [
Raymond Hettinger756ab672009-04-02 22:25:40 +000098 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
99 [('abc', 'class'), ('abc', '_1')], # field has keyword
100 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
101 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
102 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
103 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Raymond Hettinger322daea2009-02-10 01:24:05 +0000104 ]:
105 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
106
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000107 def test_instance(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +0000108 Point = namedtuple('Point', 'x y')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000109 p = Point(11, 22)
110 self.assertEqual(p, Point(x=11, y=22))
111 self.assertEqual(p, Point(11, y=22))
112 self.assertEqual(p, Point(y=22, x=11))
113 self.assertEqual(p, Point(*(11, 22)))
114 self.assertEqual(p, Point(**dict(x=11, y=22)))
115 self.assertRaises(TypeError, Point, 1) # too few args
116 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
117 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
118 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
119 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Ezio Melottiaa980582010-01-23 23:04:36 +0000120 self.assertNotIn('__weakref__', dir(p))
Raymond Hettinger02740f72008-01-05 01:35:43 +0000121 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Raymond Hettinger42da8742007-12-14 02:49:47 +0000122 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
123 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
124 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Raymond Hettinger7393c692013-05-27 10:58:55 -0700125 self.assertEqual(vars(p), p._asdict()) # verify that vars() works
Raymond Hettingerd36a60e2007-09-17 00:55:00 +0000126
Raymond Hettinger1b50fd72008-01-05 02:17:24 +0000127 try:
128 p._replace(x=1, error=2)
129 except ValueError:
130 pass
131 else:
132 self._fail('Did not detect an incorrect fieldname')
133
Raymond Hettingerd36a60e2007-09-17 00:55:00 +0000134 # verify that field string can have commas
Raymond Hettinger01a09572007-10-23 20:37:41 +0000135 Point = namedtuple('Point', 'x, y')
Raymond Hettingerd36a60e2007-09-17 00:55:00 +0000136 p = Point(x=11, y=22)
137 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000138
Raymond Hettinger2115bbc2007-10-08 09:14:28 +0000139 # verify that fieldspec can be a non-string sequence
Raymond Hettinger01a09572007-10-23 20:37:41 +0000140 Point = namedtuple('Point', ('x', 'y'))
Raymond Hettinger2115bbc2007-10-08 09:14:28 +0000141 p = Point(x=11, y=22)
142 self.assertEqual(repr(p), 'Point(x=11, y=22)')
143
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000144 def test_tupleness(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +0000145 Point = namedtuple('Point', 'x y')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000146 p = Point(11, 22)
147
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000148 self.assertIsInstance(p, tuple)
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000149 self.assertEqual(p, (11, 22)) # matches a real tuple
150 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
151 self.assertEqual(list(p), [11, 22]) # coercable to a list
152 self.assertEqual(max(p), 22) # iterable
153 self.assertEqual(max(*p), 22) # star-able
154 x, y = p
155 self.assertEqual(p, (x, y)) # unpacks like a tuple
156 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
157 self.assertRaises(IndexError, p.__getitem__, 3)
158
159 self.assertEqual(p.x, x)
160 self.assertEqual(p.y, y)
161 self.assertRaises(AttributeError, eval, 'p.z', locals())
162
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000163 def test_odd_sizes(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +0000164 Zero = namedtuple('Zero', '')
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000165 self.assertEqual(Zero(), ())
Raymond Hettinger02740f72008-01-05 01:35:43 +0000166 self.assertEqual(Zero._make([]), ())
Raymond Hettinger88880b22007-12-18 00:13:45 +0000167 self.assertEqual(repr(Zero()), 'Zero()')
168 self.assertEqual(Zero()._asdict(), {})
169 self.assertEqual(Zero()._fields, ())
170
Raymond Hettinger01a09572007-10-23 20:37:41 +0000171 Dot = namedtuple('Dot', 'd')
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000172 self.assertEqual(Dot(1), (1,))
Raymond Hettinger02740f72008-01-05 01:35:43 +0000173 self.assertEqual(Dot._make([1]), (1,))
Raymond Hettinger88880b22007-12-18 00:13:45 +0000174 self.assertEqual(Dot(1).d, 1)
175 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
176 self.assertEqual(Dot(1)._asdict(), {'d':1})
177 self.assertEqual(Dot(1)._replace(d=999), (999,))
178 self.assertEqual(Dot(1)._fields, ('d',))
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000179
Raymond Hettingere98839a2008-06-09 01:28:30 +0000180 n = 5000
Raymond Hettinger88880b22007-12-18 00:13:45 +0000181 import string, random
Georg Brandl0bb02992008-05-18 10:39:26 +0000182 names = list(set(''.join([random.choice(string.ascii_letters)
183 for j in range(10)]) for i in range(n)))
184 n = len(names)
Raymond Hettinger88880b22007-12-18 00:13:45 +0000185 Big = namedtuple('Big', names)
186 b = Big(*range(n))
187 self.assertEqual(b, tuple(range(n)))
Raymond Hettinger02740f72008-01-05 01:35:43 +0000188 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Raymond Hettinger88880b22007-12-18 00:13:45 +0000189 for pos, name in enumerate(names):
190 self.assertEqual(getattr(b, name), pos)
191 repr(b) # make sure repr() doesn't blow-up
192 d = b._asdict()
193 d_expected = dict(zip(names, range(n)))
194 self.assertEqual(d, d_expected)
195 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
196 b2_expected = range(n)
197 b2_expected[1] = 999
198 b2_expected[-5] = 42
199 self.assertEqual(b2, tuple(b2_expected))
200 self.assertEqual(b._fields, tuple(names))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000201
Raymond Hettingere98839a2008-06-09 01:28:30 +0000202 def test_pickle(self):
203 p = TestNT(x=10, y=20, z=30)
204 for module in pickle, cPickle:
205 loads = getattr(module, 'loads')
206 dumps = getattr(module, 'dumps')
207 for protocol in -1, 0, 1, 2:
208 q = loads(dumps(p, protocol))
209 self.assertEqual(p, q)
210 self.assertEqual(p._fields, q._fields)
211
212 def test_copy(self):
213 p = TestNT(x=10, y=20, z=30)
214 for copier in copy.copy, copy.deepcopy:
215 q = copier(p)
216 self.assertEqual(p, q)
217 self.assertEqual(p._fields, q._fields)
218
Raymond Hettingera68cad12009-05-27 02:24:45 +0000219 def test_name_conflicts(self):
220 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
221 # failed when used as field names. Test to make sure these now work.
222 T = namedtuple('T', 'itemgetter property self cls tuple')
223 t = T(1, 2, 3, 4, 5)
224 self.assertEqual(t, (1,2,3,4,5))
225 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
226 self.assertEqual(newt, (10,20,30,40,50))
227
228 # Broader test of all interesting names in a template
229 with test_support.captured_stdout() as template:
230 T = namedtuple('T', 'x', verbose=True)
231 words = set(re.findall('[A-Za-z]+', template.getvalue()))
232 words -= set(keyword.kwlist)
233 T = namedtuple('T', words)
234 # test __new__
235 values = tuple(range(len(words)))
236 t = T(*values)
237 self.assertEqual(t, values)
238 t = T(**dict(zip(T._fields, values)))
239 self.assertEqual(t, values)
240 # test _make
241 t = T._make(values)
242 self.assertEqual(t, values)
243 # exercise __repr__
244 repr(t)
245 # test _asdict
246 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
247 # test _replace
248 t = T._make(values)
249 newvalues = tuple(v*10 for v in values)
250 newt = t._replace(**dict(zip(T._fields, newvalues)))
251 self.assertEqual(newt, newvalues)
252 # test _fields
253 self.assertEqual(T._fields, tuple(words))
254 # test __getnewargs__
255 self.assertEqual(t.__getnewargs__(), values)
256
Raymond Hettinger7393c692013-05-27 10:58:55 -0700257 def test_pickling_bug_18015(self):
258 # http://bugs.python.org/issue18015
259 pt = pickle.loads(py273_named_tuple_pickle)
260 self.assertEqual(pt.x, 10)
261
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000262class ABCTestCase(unittest.TestCase):
263
264 def validate_abstract_methods(self, abc, *names):
265 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
266
267 # everything should work will all required methods are present
268 C = type('C', (abc,), methodstubs)
269 C()
270
271 # instantiation should fail if a required method is missing
272 for name in names:
273 stubs = methodstubs.copy()
274 del stubs[name]
275 C = type('C', (abc,), stubs)
276 self.assertRaises(TypeError, C, name)
277
Florent Xicluna47627d52010-03-08 15:20:28 +0000278 def validate_isinstance(self, abc, name):
279 stub = lambda s, *args: 0
280
281 # new-style class
282 C = type('C', (object,), {name: stub})
283 self.assertIsInstance(C(), abc)
284 self.assertTrue(issubclass(C, abc))
285 # old-style class
286 class C: pass
287 setattr(C, name, stub)
288 self.assertIsInstance(C(), abc)
289 self.assertTrue(issubclass(C, abc))
290
291 # new-style class
292 C = type('C', (object,), {'__hash__': None})
293 self.assertNotIsInstance(C(), abc)
294 self.assertFalse(issubclass(C, abc))
295 # old-style class
296 class C: pass
297 self.assertNotIsInstance(C(), abc)
298 self.assertFalse(issubclass(C, abc))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000299
Benjamin Petersoneb318d32010-05-21 20:51:45 +0000300 def validate_comparison(self, instance):
301 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
302 operators = {}
303 for op in ops:
304 name = '__' + op + '__'
305 operators[name] = getattr(operator, name)
306
307 class Other:
308 def __init__(self):
309 self.right_side = False
310 def __eq__(self, other):
311 self.right_side = True
312 return True
313 __lt__ = __eq__
314 __gt__ = __eq__
315 __le__ = __eq__
316 __ge__ = __eq__
317 __ne__ = __eq__
318 __ror__ = __eq__
319 __rand__ = __eq__
320 __rxor__ = __eq__
321 __rsub__ = __eq__
322
323 for name, op in operators.items():
324 if not hasattr(instance, name):
325 continue
326 other = Other()
327 op(instance, other)
328 self.assertTrue(other.right_side,'Right side not called for %s.%s'
329 % (type(instance), name))
330
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000331class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossum64c06e32007-11-22 00:55:51 +0000332
333 def test_Hashable(self):
334 # Check some non-hashables
335 non_samples = [list(), set(), dict()]
336 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000337 self.assertNotIsInstance(x, Hashable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000338 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000339 # Check some hashables
340 samples = [None,
341 int(), float(), complex(),
342 str(),
343 tuple(), frozenset(),
344 int, list, object, type,
345 ]
346 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000347 self.assertIsInstance(x, Hashable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000348 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000349 self.assertRaises(TypeError, Hashable)
350 # Check direct subclassing
351 class H(Hashable):
352 def __hash__(self):
353 return super(H, self).__hash__()
Nick Coghlan48361f52008-08-11 15:45:58 +0000354 __eq__ = Hashable.__eq__ # Silence Py3k warning
Guido van Rossum64c06e32007-11-22 00:55:51 +0000355 self.assertEqual(hash(H()), 0)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000356 self.assertFalse(issubclass(int, H))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000357 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000358 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000359
360 def test_Iterable(self):
361 # Check some non-iterables
362 non_samples = [None, 42, 3.14, 1j]
363 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000364 self.assertNotIsInstance(x, Iterable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000365 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000366 # Check some iterables
367 samples = [str(),
368 tuple(), list(), set(), frozenset(), dict(),
369 dict().keys(), dict().items(), dict().values(),
370 (lambda: (yield))(),
371 (x for x in []),
372 ]
373 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000374 self.assertIsInstance(x, Iterable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000375 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000376 # Check direct subclassing
377 class I(Iterable):
378 def __iter__(self):
379 return super(I, self).__iter__()
380 self.assertEqual(list(I()), [])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000381 self.assertFalse(issubclass(str, I))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000382 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000383 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000384
385 def test_Iterator(self):
386 non_samples = [None, 42, 3.14, 1j, "".encode('ascii'), "", (), [],
387 {}, set()]
388 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000389 self.assertNotIsInstance(x, Iterator)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000390 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000391 samples = [iter(str()),
392 iter(tuple()), iter(list()), iter(dict()),
393 iter(set()), iter(frozenset()),
394 iter(dict().keys()), iter(dict().items()),
395 iter(dict().values()),
396 (lambda: (yield))(),
397 (x for x in []),
398 ]
399 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000400 self.assertIsInstance(x, Iterator)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000401 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Alexander Belopolsky1fea5c42010-11-30 01:18:17 +0000402 self.validate_abstract_methods(Iterator, 'next', '__iter__')
403
404 # Issue 10565
405 class NextOnly:
406 def __next__(self):
407 yield 1
408 raise StopIteration
409 self.assertNotIsInstance(NextOnly(), Iterator)
410 class NextOnlyNew(object):
411 def __next__(self):
412 yield 1
413 raise StopIteration
414 self.assertNotIsInstance(NextOnlyNew(), Iterator)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000415
416 def test_Sized(self):
417 non_samples = [None, 42, 3.14, 1j,
418 (lambda: (yield))(),
419 (x for x in []),
420 ]
421 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000422 self.assertNotIsInstance(x, Sized)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000423 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000424 samples = [str(),
425 tuple(), list(), set(), frozenset(), dict(),
426 dict().keys(), dict().items(), dict().values(),
427 ]
428 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000429 self.assertIsInstance(x, Sized)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000430 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000431 self.validate_abstract_methods(Sized, '__len__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000432 self.validate_isinstance(Sized, '__len__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000433
434 def test_Container(self):
435 non_samples = [None, 42, 3.14, 1j,
436 (lambda: (yield))(),
437 (x for x in []),
438 ]
439 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000440 self.assertNotIsInstance(x, Container)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000441 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000442 samples = [str(),
443 tuple(), list(), set(), frozenset(), dict(),
444 dict().keys(), dict().items(),
445 ]
446 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000447 self.assertIsInstance(x, Container)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000448 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000449 self.validate_abstract_methods(Container, '__contains__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000450 self.validate_isinstance(Container, '__contains__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000451
452 def test_Callable(self):
453 non_samples = [None, 42, 3.14, 1j,
454 "", "".encode('ascii'), (), [], {}, set(),
455 (lambda: (yield))(),
456 (x for x in []),
457 ]
458 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000459 self.assertNotIsInstance(x, Callable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000460 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000461 samples = [lambda: None,
462 type, int, object,
463 len,
464 list.append, [].append,
465 ]
466 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000467 self.assertIsInstance(x, Callable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000468 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000469 self.validate_abstract_methods(Callable, '__call__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000470 self.validate_isinstance(Callable, '__call__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000471
472 def test_direct_subclassing(self):
473 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
474 class C(B):
475 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000476 self.assertTrue(issubclass(C, B))
477 self.assertFalse(issubclass(int, C))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000478
479 def test_registration(self):
480 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
481 class C:
482 __metaclass__ = type
483 __hash__ = None # Make sure it isn't hashable by default
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000484 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000485 B.register(C)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000486 self.assertTrue(issubclass(C, B))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000487
Raymond Hettinger66c4a6b2009-04-01 18:50:56 +0000488class WithSet(MutableSet):
489
490 def __init__(self, it=()):
491 self.data = set(it)
492
493 def __len__(self):
494 return len(self.data)
495
496 def __iter__(self):
497 return iter(self.data)
498
499 def __contains__(self, item):
500 return item in self.data
501
502 def add(self, item):
503 self.data.add(item)
504
505 def discard(self, item):
506 self.data.discard(item)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000507
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000508class TestCollectionABCs(ABCTestCase):
Guido van Rossum64c06e32007-11-22 00:55:51 +0000509
510 # XXX For now, we only test some virtual inheritance properties.
511 # We should also test the proper behavior of the collection ABCs
512 # as real base classes or mix-in classes.
513
514 def test_Set(self):
515 for sample in [set, frozenset]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000516 self.assertIsInstance(sample(), Set)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000517 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000518 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Petersoneb318d32010-05-21 20:51:45 +0000519 class MySet(Set):
520 def __contains__(self, x):
521 return False
522 def __len__(self):
523 return 0
524 def __iter__(self):
525 return iter([])
526 self.validate_comparison(MySet())
Guido van Rossum64c06e32007-11-22 00:55:51 +0000527
Raymond Hettinger4c52f522008-06-23 03:29:28 +0000528 def test_hash_Set(self):
529 class OneTwoThreeSet(Set):
530 def __init__(self):
531 self.contents = [1, 2, 3]
532 def __contains__(self, x):
533 return x in self.contents
534 def __len__(self):
535 return len(self.contents)
536 def __iter__(self):
537 return iter(self.contents)
538 def __hash__(self):
539 return self._hash()
540 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000541 self.assertTrue(hash(a) == hash(b))
Raymond Hettinger4c52f522008-06-23 03:29:28 +0000542
Guido van Rossum64c06e32007-11-22 00:55:51 +0000543 def test_MutableSet(self):
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000544 self.assertIsInstance(set(), MutableSet)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000545 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000546 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000547 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000548 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
549 'add', 'discard')
550
Raymond Hettinger66c4a6b2009-04-01 18:50:56 +0000551 def test_issue_5647(self):
552 # MutableSet.__iand__ mutated the set during iteration
553 s = WithSet('abcd')
554 s &= WithSet('cdef') # This used to fail
555 self.assertEqual(set(s), set('cd'))
556
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000557 def test_issue_4920(self):
558 # MutableSet.pop() method did not work
559 class MySet(collections.MutableSet):
560 __slots__=['__s']
561 def __init__(self,items=None):
562 if items is None:
563 items=[]
564 self.__s=set(items)
565 def __contains__(self,v):
566 return v in self.__s
567 def __iter__(self):
568 return iter(self.__s)
569 def __len__(self):
570 return len(self.__s)
571 def add(self,v):
572 result=v not in self.__s
573 self.__s.add(v)
574 return result
575 def discard(self,v):
576 result=v in self.__s
577 self.__s.discard(v)
578 return result
579 def __repr__(self):
580 return "MySet(%s)" % repr(list(self))
581 s = MySet([5,43,2,1])
582 self.assertEqual(s.pop(), 1)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000583
Daniel Stutzbach91287322010-08-24 21:09:30 +0000584 def test_issue8750(self):
585 empty = WithSet()
586 full = WithSet(range(10))
587 s = WithSet(full)
588 s -= s
589 self.assertEqual(s, empty)
590 s = WithSet(full)
591 s ^= s
592 self.assertEqual(s, empty)
593 s = WithSet(full)
594 s &= s
595 self.assertEqual(s, full)
596 s |= s
597 self.assertEqual(s, full)
598
Serhiy Storchaka7c573852013-12-06 23:23:15 +0200599 def test_issue16373(self):
600 # Recursion error comparing comparable and noncomparable
601 # Set instances
602 class MyComparableSet(Set):
603 def __contains__(self, x):
604 return False
605 def __len__(self):
606 return 0
607 def __iter__(self):
608 return iter([])
609 class MyNonComparableSet(Set):
610 def __contains__(self, x):
611 return False
612 def __len__(self):
613 return 0
614 def __iter__(self):
615 return iter([])
616 def __le__(self, x):
617 return NotImplemented
618 def __lt__(self, x):
619 return NotImplemented
620
621 cs = MyComparableSet()
622 ncs = MyNonComparableSet()
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700623
624 # Run all the variants to make sure they don't mutually recurse
625 ncs < cs
626 ncs <= cs
627 ncs > cs
628 ncs >= cs
629 cs < ncs
630 cs <= ncs
631 cs > ncs
632 cs >= ncs
633
634 def assertSameSet(self, s1, s2):
635 # coerce both to a real set then check equality
636 self.assertEqual(set(s1), set(s2))
637
638 def test_Set_interoperability_with_real_sets(self):
639 # Issue: 8743
640 class ListSet(Set):
641 def __init__(self, elements=()):
642 self.data = []
643 for elem in elements:
644 if elem not in self.data:
645 self.data.append(elem)
646 def __contains__(self, elem):
647 return elem in self.data
648 def __iter__(self):
649 return iter(self.data)
650 def __len__(self):
651 return len(self.data)
652 def __repr__(self):
653 return 'Set({!r})'.format(self.data)
654
655 r1 = set('abc')
656 r2 = set('bcd')
657 r3 = set('abcde')
658 f1 = ListSet('abc')
659 f2 = ListSet('bcd')
660 f3 = ListSet('abcde')
661 l1 = list('abccba')
662 l2 = list('bcddcb')
663 l3 = list('abcdeedcba')
664 p1 = sets.Set('abc')
665 p2 = sets.Set('bcd')
666 p3 = sets.Set('abcde')
667
668 target = r1 & r2
669 self.assertSameSet(f1 & f2, target)
670 self.assertSameSet(f1 & r2, target)
671 self.assertSameSet(r2 & f1, target)
672 self.assertSameSet(f1 & p2, target)
673 self.assertSameSet(p2 & f1, target)
674 self.assertSameSet(f1 & l2, target)
675
676 target = r1 | r2
677 self.assertSameSet(f1 | f2, target)
678 self.assertSameSet(f1 | r2, target)
679 self.assertSameSet(r2 | f1, target)
680 self.assertSameSet(f1 | p2, target)
681 self.assertSameSet(p2 | f1, target)
682 self.assertSameSet(f1 | l2, target)
683
684 fwd_target = r1 - r2
685 rev_target = r2 - r1
686 self.assertSameSet(f1 - f2, fwd_target)
687 self.assertSameSet(f2 - f1, rev_target)
688 self.assertSameSet(f1 - r2, fwd_target)
689 self.assertSameSet(f2 - r1, rev_target)
690 self.assertSameSet(r1 - f2, fwd_target)
691 self.assertSameSet(r2 - f1, rev_target)
692 self.assertSameSet(f1 - p2, fwd_target)
693 self.assertSameSet(f2 - p1, rev_target)
694 self.assertSameSet(p1 - f2, fwd_target)
695 self.assertSameSet(p2 - f1, rev_target)
696 self.assertSameSet(f1 - l2, fwd_target)
697 self.assertSameSet(f2 - l1, rev_target)
698
699 target = r1 ^ r2
700 self.assertSameSet(f1 ^ f2, target)
701 self.assertSameSet(f1 ^ r2, target)
702 self.assertSameSet(r2 ^ f1, target)
703 self.assertSameSet(f1 ^ p2, target)
704 self.assertSameSet(p2 ^ f1, target)
705 self.assertSameSet(f1 ^ l2, target)
706
707 # proper subset
708 self.assertTrue(f1 < f3)
709 self.assertFalse(f1 < f1)
710 self.assertFalse(f1 < f2)
711 self.assertTrue(r1 < f3)
712 self.assertFalse(r1 < f1)
713 self.assertFalse(r1 < f2)
714 self.assertTrue(r1 < r3)
715 self.assertFalse(r1 < r1)
716 self.assertFalse(r1 < r2)
Victor Stinnera3acea32014-09-05 21:05:05 +0200717
718 with test_support.check_py3k_warnings():
719 # python 2 only, cross-type compares will succeed
720 f1 < l3
721 f1 < l1
722 f1 < l2
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700723
724 # any subset
725 self.assertTrue(f1 <= f3)
726 self.assertTrue(f1 <= f1)
727 self.assertFalse(f1 <= f2)
728 self.assertTrue(r1 <= f3)
729 self.assertTrue(r1 <= f1)
730 self.assertFalse(r1 <= f2)
731 self.assertTrue(r1 <= r3)
732 self.assertTrue(r1 <= r1)
733 self.assertFalse(r1 <= r2)
Victor Stinnera3acea32014-09-05 21:05:05 +0200734
735 with test_support.check_py3k_warnings():
736 # python 2 only, cross-type compares will succeed
737 f1 <= l3
738 f1 <= l1
739 f1 <= l2
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700740
741 # proper superset
742 self.assertTrue(f3 > f1)
743 self.assertFalse(f1 > f1)
744 self.assertFalse(f2 > f1)
745 self.assertTrue(r3 > r1)
746 self.assertFalse(f1 > r1)
747 self.assertFalse(f2 > r1)
748 self.assertTrue(r3 > r1)
749 self.assertFalse(r1 > r1)
750 self.assertFalse(r2 > r1)
Victor Stinnera3acea32014-09-05 21:05:05 +0200751
752 with test_support.check_py3k_warnings():
753 # python 2 only, cross-type compares will succeed
754 f1 > l3
755 f1 > l1
756 f1 > l2
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700757
758 # any superset
759 self.assertTrue(f3 >= f1)
760 self.assertTrue(f1 >= f1)
761 self.assertFalse(f2 >= f1)
762 self.assertTrue(r3 >= r1)
763 self.assertTrue(f1 >= r1)
764 self.assertFalse(f2 >= r1)
765 self.assertTrue(r3 >= r1)
766 self.assertTrue(r1 >= r1)
767 self.assertFalse(r2 >= r1)
Victor Stinnera3acea32014-09-05 21:05:05 +0200768
769 with test_support.check_py3k_warnings():
770 # python 2 only, cross-type compares will succeed
771 f1 >= l3
772 f1 >=l1
773 f1 >= l2
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700774
775 # equality
776 self.assertTrue(f1 == f1)
777 self.assertTrue(r1 == f1)
778 self.assertTrue(f1 == r1)
779 self.assertFalse(f1 == f3)
780 self.assertFalse(r1 == f3)
781 self.assertFalse(f1 == r3)
782 # python 2 only, cross-type compares will succeed
783 f1 == l3
784 f1 == l1
785 f1 == l2
786
787 # inequality
788 self.assertFalse(f1 != f1)
789 self.assertFalse(r1 != f1)
790 self.assertFalse(f1 != r1)
791 self.assertTrue(f1 != f3)
792 self.assertTrue(r1 != f3)
793 self.assertTrue(f1 != r3)
794 # python 2 only, cross-type compares will succeed
795 f1 != l3
796 f1 != l1
797 f1 != l2
Serhiy Storchaka7c573852013-12-06 23:23:15 +0200798
Guido van Rossum64c06e32007-11-22 00:55:51 +0000799 def test_Mapping(self):
800 for sample in [dict]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000801 self.assertIsInstance(sample(), Mapping)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000802 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000803 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
804 '__getitem__')
Benjamin Petersoneb318d32010-05-21 20:51:45 +0000805 class MyMapping(collections.Mapping):
806 def __len__(self):
807 return 0
808 def __getitem__(self, i):
809 raise IndexError
810 def __iter__(self):
811 return iter(())
812 self.validate_comparison(MyMapping())
Guido van Rossum64c06e32007-11-22 00:55:51 +0000813
814 def test_MutableMapping(self):
815 for sample in [dict]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000816 self.assertIsInstance(sample(), MutableMapping)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000817 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000818 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
819 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000820
821 def test_Sequence(self):
822 for sample in [tuple, list, str]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000823 self.assertIsInstance(sample(), Sequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000824 self.assertTrue(issubclass(sample, Sequence))
825 self.assertTrue(issubclass(basestring, Sequence))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000826 self.assertIsInstance(range(10), Sequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000827 self.assertTrue(issubclass(xrange, Sequence))
828 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000829 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
830 '__getitem__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000831
832 def test_MutableSequence(self):
833 for sample in [tuple, str]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000834 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000835 self.assertFalse(issubclass(sample, MutableSequence))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000836 for sample in [list]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000837 self.assertIsInstance(sample(), MutableSequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000838 self.assertTrue(issubclass(sample, MutableSequence))
839 self.assertFalse(issubclass(basestring, MutableSequence))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000840 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
841 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000842
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000843class TestCounter(unittest.TestCase):
844
845 def test_basics(self):
846 c = Counter('abcaba')
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000847 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
848 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000849 self.assertIsInstance(c, dict)
850 self.assertIsInstance(c, Mapping)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000851 self.assertTrue(issubclass(Counter, dict))
852 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000853 self.assertEqual(len(c), 3)
854 self.assertEqual(sum(c.values()), 6)
855 self.assertEqual(sorted(c.values()), [1, 2, 3])
856 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
857 self.assertEqual(sorted(c), ['a', 'b', 'c'])
858 self.assertEqual(sorted(c.items()),
859 [('a', 3), ('b', 2), ('c', 1)])
860 self.assertEqual(c['b'], 2)
861 self.assertEqual(c['z'], 0)
Florent Xicluna47627d52010-03-08 15:20:28 +0000862 with test_support.check_py3k_warnings():
863 self.assertEqual(c.has_key('c'), True)
864 self.assertEqual(c.has_key('z'), False)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000865 self.assertEqual(c.__contains__('c'), True)
866 self.assertEqual(c.__contains__('z'), False)
867 self.assertEqual(c.get('b', 10), 2)
868 self.assertEqual(c.get('z', 10), 10)
869 self.assertEqual(c, dict(a=3, b=2, c=1))
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000870 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000871 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
872 for i in range(5):
873 self.assertEqual(c.most_common(i),
874 [('a', 3), ('b', 2), ('c', 1)][:i])
875 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
876 c['a'] += 1 # increment an existing value
877 c['b'] -= 2 # sub existing value to zero
878 del c['c'] # remove an entry
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000879 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000880 c['d'] -= 2 # sub from a missing value
881 c['e'] = -5 # directly assign a missing value
882 c['f'] += 4 # add to a missing value
883 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
884 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
885 self.assertEqual(c.pop('f'), 4)
Ezio Melottiaa980582010-01-23 23:04:36 +0000886 self.assertNotIn('f', c)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000887 for i in range(3):
888 elem, cnt = c.popitem()
Ezio Melottiaa980582010-01-23 23:04:36 +0000889 self.assertNotIn(elem, c)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000890 c.clear()
891 self.assertEqual(c, {})
892 self.assertEqual(repr(c), 'Counter()')
893 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
894 self.assertRaises(TypeError, hash, c)
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000895 c.update(dict(a=5, b=3))
896 c.update(c=1)
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000897 c.update(Counter('a' * 50 + 'b' * 30))
Raymond Hettingerafd112b2009-01-14 01:15:06 +0000898 c.update() # test case with no args
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000899 c.__init__('a' * 500 + 'b' * 300)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000900 c.__init__('cdc')
Raymond Hettingerafd112b2009-01-14 01:15:06 +0000901 c.__init__()
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000902 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
903 self.assertEqual(c.setdefault('d', 5), 1)
904 self.assertEqual(c['d'], 1)
905 self.assertEqual(c.setdefault('e', 5), 5)
906 self.assertEqual(c['e'], 5)
907
908 def test_copying(self):
909 # Check that counters are copyable, deepcopyable, picklable, and
910 #have a repr/eval round-trip
911 words = Counter('which witch had which witches wrist watch'.split())
912 update_test = Counter()
913 update_test.update(words)
914 for i, dup in enumerate([
915 words.copy(),
916 copy.copy(words),
917 copy.deepcopy(words),
918 pickle.loads(pickle.dumps(words, 0)),
919 pickle.loads(pickle.dumps(words, 1)),
920 pickle.loads(pickle.dumps(words, 2)),
921 pickle.loads(pickle.dumps(words, -1)),
922 cPickle.loads(cPickle.dumps(words, 0)),
923 cPickle.loads(cPickle.dumps(words, 1)),
924 cPickle.loads(cPickle.dumps(words, 2)),
925 cPickle.loads(cPickle.dumps(words, -1)),
926 eval(repr(words)),
927 update_test,
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000928 Counter(words),
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000929 ]):
930 msg = (i, dup, words)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000931 self.assertTrue(dup is not words)
Ezio Melotti2623a372010-11-21 13:34:58 +0000932 self.assertEqual(dup, words)
933 self.assertEqual(len(dup), len(words))
934 self.assertEqual(type(dup), type(words))
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000935
Raymond Hettinger37c0fe52011-04-15 13:12:21 -0700936 def test_copy_subclass(self):
937 class MyCounter(Counter):
938 pass
939 c = MyCounter('slartibartfast')
940 d = c.copy()
941 self.assertEqual(d, c)
942 self.assertEqual(len(d), len(c))
943 self.assertEqual(type(d), type(c))
944
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000945 def test_conversions(self):
946 # Convert to: set, list, dict
947 s = 'she sells sea shells by the sea shore'
948 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
949 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
950 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
951 self.assertEqual(set(Counter(s)), set(s))
952
Raymond Hettinger0a1f7b82009-01-21 23:12:51 +0000953 def test_invariant_for_the_in_operator(self):
954 c = Counter(a=10, b=-2, c=0)
955 for elem in c:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000956 self.assertTrue(elem in c)
Ezio Melottiaa980582010-01-23 23:04:36 +0000957 self.assertIn(elem, c)
Raymond Hettinger0a1f7b82009-01-21 23:12:51 +0000958
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000959 def test_multiset_operations(self):
960 # Verify that adding a zero counter will strip zeros and negatives
961 c = Counter(a=10, b=-2, c=0) + Counter()
962 self.assertEqual(dict(c), dict(a=10))
963
964 elements = 'abcd'
965 for i in range(1000):
966 # test random pairs of multisets
967 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettinger4571f342009-01-21 20:31:50 +0000968 p.update(e=1, f=-1, g=0)
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000969 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettinger4571f342009-01-21 20:31:50 +0000970 q.update(h=1, i=-1, j=0)
971 for counterop, numberop in [
972 (Counter.__add__, lambda x, y: max(0, x+y)),
973 (Counter.__sub__, lambda x, y: max(0, x-y)),
974 (Counter.__or__, lambda x, y: max(0,x,y)),
975 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000976 ]:
977 result = counterop(p, q)
978 for x in elements:
Raymond Hettinger4571f342009-01-21 20:31:50 +0000979 self.assertEqual(numberop(p[x], q[x]), result[x],
980 (counterop, x, p, q))
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000981 # verify that results exclude non-positive counts
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000982 self.assertTrue(x>0 for x in result.values())
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000983
984 elements = 'abcdef'
985 for i in range(100):
986 # verify that random multisets with no repeats are exactly like sets
987 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
988 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
989 for counterop, setop in [
990 (Counter.__sub__, set.__sub__),
991 (Counter.__or__, set.__or__),
992 (Counter.__and__, set.__and__),
993 ]:
994 counter_result = counterop(p, q)
995 set_result = setop(set(p.elements()), set(q.elements()))
996 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000997
Raymond Hettinger34c35b22010-04-03 10:22:00 +0000998 def test_subtract(self):
999 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1000 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1001 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1002 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1003 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1004 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1005 c = Counter('aaabbcd')
1006 c.subtract('aaaabbcce')
1007 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
1008
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001009class TestOrderedDict(unittest.TestCase):
1010
1011 def test_init(self):
1012 with self.assertRaises(TypeError):
1013 OrderedDict([('a', 1), ('b', 2)], None) # too many args
1014 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1015 self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input
1016 self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input
1017 self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input
1018 self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
1019 c=3, e=5).items()), pairs) # mixed input
1020
1021 # make sure no positional args conflict with possible kwdargs
1022 self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args,
1023 ['self'])
1024
1025 # Make sure that direct calls to __init__ do not clear previous contents
1026 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1027 d.__init__([('e', 5), ('f', 6)], g=7, d=4)
1028 self.assertEqual(list(d.items()),
1029 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1030
1031 def test_update(self):
1032 with self.assertRaises(TypeError):
1033 OrderedDict().update([('a', 1), ('b', 2)], None) # too many args
1034 pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
1035 od = OrderedDict()
1036 od.update(dict(pairs))
1037 self.assertEqual(sorted(od.items()), pairs) # dict input
1038 od = OrderedDict()
1039 od.update(**dict(pairs))
1040 self.assertEqual(sorted(od.items()), pairs) # kwds input
1041 od = OrderedDict()
1042 od.update(pairs)
1043 self.assertEqual(list(od.items()), pairs) # pairs input
1044 od = OrderedDict()
1045 od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
1046 self.assertEqual(list(od.items()), pairs) # mixed input
1047
Mark Dickinson42add992010-07-11 19:17:28 +00001048 # Issue 9137: Named argument called 'other' or 'self'
1049 # shouldn't be treated specially.
1050 od = OrderedDict()
1051 od.update(self=23)
1052 self.assertEqual(list(od.items()), [('self', 23)])
1053 od = OrderedDict()
1054 od.update(other={})
1055 self.assertEqual(list(od.items()), [('other', {})])
1056 od = OrderedDict()
1057 od.update(red=5, blue=6, other=7, self=8)
1058 self.assertEqual(sorted(list(od.items())),
1059 [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
1060
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001061 # Make sure that direct calls to update do not clear previous contents
1062 # add that updates items are not moved to the end
1063 d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
1064 d.update([('e', 5), ('f', 6)], g=7, d=4)
1065 self.assertEqual(list(d.items()),
1066 [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
1067
Raymond Hettinger8ebebd82011-01-02 01:03:26 +00001068 def test_abc(self):
1069 self.assertIsInstance(OrderedDict(), MutableMapping)
1070 self.assertTrue(issubclass(OrderedDict, MutableMapping))
1071
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001072 def test_clear(self):
1073 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1074 shuffle(pairs)
1075 od = OrderedDict(pairs)
1076 self.assertEqual(len(od), len(pairs))
1077 od.clear()
1078 self.assertEqual(len(od), 0)
1079
1080 def test_delitem(self):
1081 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1082 od = OrderedDict(pairs)
1083 del od['a']
Ezio Melottiaa980582010-01-23 23:04:36 +00001084 self.assertNotIn('a', od)
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001085 with self.assertRaises(KeyError):
1086 del od['a']
1087 self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
1088
1089 def test_setitem(self):
1090 od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
1091 od['c'] = 10 # existing element
1092 od['f'] = 20 # new element
1093 self.assertEqual(list(od.items()),
1094 [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
1095
1096 def test_iterators(self):
1097 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1098 shuffle(pairs)
1099 od = OrderedDict(pairs)
1100 self.assertEqual(list(od), [t[0] for t in pairs])
Raymond Hettingerf17f81d2009-03-03 07:12:09 +00001101 self.assertEqual(od.keys()[:], [t[0] for t in pairs])
1102 self.assertEqual(od.values()[:], [t[1] for t in pairs])
1103 self.assertEqual(od.items()[:], pairs)
1104 self.assertEqual(list(od.iterkeys()), [t[0] for t in pairs])
1105 self.assertEqual(list(od.itervalues()), [t[1] for t in pairs])
1106 self.assertEqual(list(od.iteritems()), pairs)
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001107 self.assertEqual(list(reversed(od)),
1108 [t[0] for t in reversed(pairs)])
1109
1110 def test_popitem(self):
1111 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1112 shuffle(pairs)
1113 od = OrderedDict(pairs)
1114 while pairs:
1115 self.assertEqual(od.popitem(), pairs.pop())
1116 with self.assertRaises(KeyError):
1117 od.popitem()
1118 self.assertEqual(len(od), 0)
1119
1120 def test_pop(self):
1121 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1122 shuffle(pairs)
1123 od = OrderedDict(pairs)
1124 shuffle(pairs)
1125 while pairs:
1126 k, v = pairs.pop()
1127 self.assertEqual(od.pop(k), v)
1128 with self.assertRaises(KeyError):
1129 od.pop('xyz')
1130 self.assertEqual(len(od), 0)
1131 self.assertEqual(od.pop(k, 12345), 12345)
1132
Raymond Hettinger8ebebd82011-01-02 01:03:26 +00001133 # make sure pop still works when __missing__ is defined
1134 class Missing(OrderedDict):
1135 def __missing__(self, key):
1136 return 0
1137 m = Missing(a=1)
1138 self.assertEqual(m.pop('b', 5), 5)
1139 self.assertEqual(m.pop('a', 6), 1)
1140 self.assertEqual(m.pop('a', 6), 6)
1141 with self.assertRaises(KeyError):
1142 m.pop('a')
1143
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001144 def test_equality(self):
1145 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1146 shuffle(pairs)
1147 od1 = OrderedDict(pairs)
1148 od2 = OrderedDict(pairs)
1149 self.assertEqual(od1, od2) # same order implies equality
1150 pairs = pairs[2:] + pairs[:2]
1151 od2 = OrderedDict(pairs)
1152 self.assertNotEqual(od1, od2) # different order implies inequality
1153 # comparison to regular dict is not order sensitive
1154 self.assertEqual(od1, dict(od2))
1155 self.assertEqual(dict(od2), od1)
1156 # different length implied inequality
1157 self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
1158
1159 def test_copying(self):
1160 # Check that ordered dicts are copyable, deepcopyable, picklable,
1161 # and have a repr/eval round-trip
1162 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1163 od = OrderedDict(pairs)
1164 update_test = OrderedDict()
1165 update_test.update(od)
1166 for i, dup in enumerate([
1167 od.copy(),
1168 copy.copy(od),
1169 copy.deepcopy(od),
1170 pickle.loads(pickle.dumps(od, 0)),
1171 pickle.loads(pickle.dumps(od, 1)),
1172 pickle.loads(pickle.dumps(od, 2)),
1173 pickle.loads(pickle.dumps(od, -1)),
1174 eval(repr(od)),
1175 update_test,
1176 OrderedDict(od),
1177 ]):
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001178 self.assertTrue(dup is not od)
Ezio Melotti2623a372010-11-21 13:34:58 +00001179 self.assertEqual(dup, od)
1180 self.assertEqual(list(dup.items()), list(od.items()))
1181 self.assertEqual(len(dup), len(od))
1182 self.assertEqual(type(dup), type(od))
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001183
Raymond Hettinger131af652009-03-03 22:59:25 +00001184 def test_yaml_linkage(self):
1185 # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
1186 # In yaml, lists are native but tuples are not.
1187 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1188 od = OrderedDict(pairs)
1189 # yaml.dump(od) -->
1190 # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001191 self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
Raymond Hettinger131af652009-03-03 22:59:25 +00001192
1193 def test_reduce_not_too_fat(self):
1194 # do not save instance dictionary if not needed
1195 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1196 od = OrderedDict(pairs)
Alexandre Vassalotticb73bda2009-06-12 23:03:35 +00001197 self.assertEqual(len(od.__reduce__()), 2)
Raymond Hettinger131af652009-03-03 22:59:25 +00001198 od.x = 10
Alexandre Vassalotticb73bda2009-06-12 23:03:35 +00001199 self.assertEqual(len(od.__reduce__()), 3)
Raymond Hettinger131af652009-03-03 22:59:25 +00001200
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001201 def test_repr(self):
1202 od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
1203 self.assertEqual(repr(od),
1204 "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
1205 self.assertEqual(eval(repr(od)), od)
1206 self.assertEqual(repr(OrderedDict()), "OrderedDict()")
1207
Raymond Hettinger74f869e2010-09-13 22:14:36 +00001208 def test_repr_recursive(self):
1209 # See issue #9826
1210 od = OrderedDict.fromkeys('abc')
1211 od['x'] = od
1212 self.assertEqual(repr(od),
1213 "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
1214
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001215 def test_setdefault(self):
1216 pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
1217 shuffle(pairs)
1218 od = OrderedDict(pairs)
1219 pair_order = list(od.items())
1220 self.assertEqual(od.setdefault('a', 10), 3)
1221 # make sure order didn't change
1222 self.assertEqual(list(od.items()), pair_order)
1223 self.assertEqual(od.setdefault('x', 10), 10)
1224 # make sure 'x' is added to the end
1225 self.assertEqual(list(od.items())[-1], ('x', 10))
1226
Raymond Hettinger8ebebd82011-01-02 01:03:26 +00001227 # make sure setdefault still works when __missing__ is defined
1228 class Missing(OrderedDict):
1229 def __missing__(self, key):
1230 return 0
1231 self.assertEqual(Missing().setdefault(5, 9), 9)
1232
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001233 def test_reinsert(self):
1234 # Given insert a, insert b, delete a, re-insert a,
1235 # verify that a is now later than b.
1236 od = OrderedDict()
1237 od['a'] = 1
1238 od['b'] = 2
1239 del od['a']
1240 od['a'] = 1
1241 self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
1242
Raymond Hettingera54b2da2010-08-17 19:03:06 +00001243 def test_views(self):
1244 s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split()
1245 od = OrderedDict.fromkeys(s)
1246 self.assertEqual(list(od.viewkeys()), s)
1247 self.assertEqual(list(od.viewvalues()), [None for k in s])
1248 self.assertEqual(list(od.viewitems()), [(k, None) for k in s])
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001249
Raymond Hettinger8ebebd82011-01-02 01:03:26 +00001250 def test_override_update(self):
1251 # Verify that subclasses can override update() without breaking __init__()
1252 class MyOD(OrderedDict):
1253 def update(self, *args, **kwds):
1254 raise Exception()
1255 items = [('a', 1), ('c', 3), ('b', 2)]
1256 self.assertEqual(list(MyOD(items).items()), items)
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001257
1258class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
1259 type2test = OrderedDict
1260
Raymond Hettinger24122992009-03-19 19:59:58 +00001261 def test_popitem(self):
1262 d = self._empty_mapping()
1263 self.assertRaises(KeyError, d.popitem)
1264
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001265class MyOrderedDict(OrderedDict):
1266 pass
1267
1268class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
1269 type2test = MyOrderedDict
1270
Raymond Hettinger24122992009-03-19 19:59:58 +00001271 def test_popitem(self):
1272 d = self._empty_mapping()
1273 self.assertRaises(KeyError, d.popitem)
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001274
Georg Brandla4f46e12010-02-07 17:03:15 +00001275import collections
Guido van Rossum64c06e32007-11-22 00:55:51 +00001276
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00001277def test_main(verbose=None):
Amaury Forgeot d'Arccb0f2ad2008-04-02 00:55:04 +00001278 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +00001279 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Raymond Hettingerbc512d32009-03-03 04:45:34 +00001280 TestCollectionABCs, TestCounter,
1281 TestOrderedDict, GeneralMappingTests, SubclassMappingTests]
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00001282 test_support.run_unittest(*test_classes)
Amaury Forgeot d'Arccb0f2ad2008-04-02 00:55:04 +00001283 test_support.run_doctest(collections, verbose)
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00001284
1285if __name__ == "__main__":
1286 test_main(verbose=True)