blob: 125a68ff46d3c3342edcec22ecd31fc365a65234 [file] [log] [blame]
Serhiy Storchaka282e8312015-11-25 17:19:27 +02001import collections
2import copy
3import doctest
Raymond Hettingera68cad12009-05-27 02:24:45 +00004import keyword
Serhiy Storchaka282e8312015-11-25 17:19:27 +02005import operator
6import pickle
7import cPickle
8from random import choice, randrange
Raymond Hettingera68cad12009-05-27 02:24:45 +00009import re
Serhiy Storchaka282e8312015-11-25 17:19:27 +020010import string
R. David Murrayf28fd242010-02-23 00:24:49 +000011import sys
Serhiy Storchaka282e8312015-11-25 17:19:27 +020012from test import test_support
13import unittest
14
15from collections import namedtuple, Counter, OrderedDict
Guido van Rossum64c06e32007-11-22 00:55:51 +000016from collections import Hashable, Iterable, Iterator
17from collections import Sized, Container, Callable
18from collections import Set, MutableSet
19from collections import Mapping, MutableMapping
20from collections import Sequence, MutableSequence
Serhiy Storchaka282e8312015-11-25 17:19:27 +020021
Victor Stinner749022d2014-09-05 21:41:25 +020022# Silence deprecation warning
23sets = test_support.import_module('sets', deprecated=True)
Guido van Rossum64c06e32007-11-22 00:55:51 +000024
Raymond Hettingere98839a2008-06-09 01:28:30 +000025TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000026
Raymond Hettinger7393c692013-05-27 10:58:55 -070027py273_named_tuple_pickle = '''\
28ccopy_reg
29_reconstructor
30p0
31(ctest.test_collections
32TestNT
33p1
34c__builtin__
35tuple
36p2
37(I10
38I20
39I30
40tp3
41tp4
42Rp5
43ccollections
44OrderedDict
45p6
46((lp7
47(lp8
48S'x'
49p9
50aI10
51aa(lp10
52S'y'
53p11
54aI20
55aa(lp12
56S'z'
57p13
58aI30
59aatp14
60Rp15
61b.
62'''
63
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000064class TestNamedTuple(unittest.TestCase):
65
66 def test_factory(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +000067 Point = namedtuple('Point', 'x y')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000068 self.assertEqual(Point.__name__, 'Point')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000069 self.assertEqual(Point.__slots__, ())
70 self.assertEqual(Point.__module__, __name__)
71 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Raymond Hettingere0734e72008-01-04 03:22:53 +000072 self.assertEqual(Point._fields, ('x', 'y'))
Raymond Hettingerabfd8df2007-10-16 21:28:32 +000073
Raymond Hettinger01a09572007-10-23 20:37:41 +000074 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
75 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
76 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
Raymond Hettingerabfd8df2007-10-16 21:28:32 +000077
Raymond Hettinger01a09572007-10-23 20:37:41 +000078 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
79 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
80 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
Raymond Hettinger42da8742007-12-14 02:49:47 +000081 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
Raymond Hettinger01a09572007-10-23 20:37:41 +000082 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
Raymond Hettingerabfd8df2007-10-16 21:28:32 +000083
Raymond Hettinger01a09572007-10-23 20:37:41 +000084 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Raymond Hettinger42da8742007-12-14 02:49:47 +000085 namedtuple('_', 'a b c') # Test leading underscores in a typename
Raymond Hettingerc37e5e02007-03-01 06:16:43 +000086
Raymond Hettinger6ee7bc02008-09-25 23:31:52 +000087 nt = namedtuple('nt', u'the quick brown fox') # check unicode input
Ezio Melottiaa980582010-01-23 23:04:36 +000088 self.assertNotIn("u'", repr(nt._fields))
Raymond Hettinger6ee7bc02008-09-25 23:31:52 +000089 nt = namedtuple('nt', (u'the', u'quick')) # check unicode input
Ezio Melottiaa980582010-01-23 23:04:36 +000090 self.assertNotIn("u'", repr(nt._fields))
Raymond Hettinger6ee7bc02008-09-25 23:31:52 +000091
Raymond Hettinger02740f72008-01-05 01:35:43 +000092 self.assertRaises(TypeError, Point._make, [11]) # catch too few args
93 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
94
R. David Murrayf28fd242010-02-23 00:24:49 +000095 @unittest.skipIf(sys.flags.optimize >= 2,
96 "Docstrings are omitted with -O2 and above")
97 def test_factory_doc_attr(self):
98 Point = namedtuple('Point', 'x y')
99 self.assertEqual(Point.__doc__, 'Point(x, y)')
100
Raymond Hettinger322daea2009-02-10 01:24:05 +0000101 def test_name_fixer(self):
102 for spec, renamed in [
Raymond Hettinger756ab672009-04-02 22:25:40 +0000103 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
104 [('abc', 'class'), ('abc', '_1')], # field has keyword
105 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
106 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
107 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
108 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
Raymond Hettinger322daea2009-02-10 01:24:05 +0000109 ]:
110 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
111
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000112 def test_instance(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +0000113 Point = namedtuple('Point', 'x y')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000114 p = Point(11, 22)
115 self.assertEqual(p, Point(x=11, y=22))
116 self.assertEqual(p, Point(11, y=22))
117 self.assertEqual(p, Point(y=22, x=11))
118 self.assertEqual(p, Point(*(11, 22)))
119 self.assertEqual(p, Point(**dict(x=11, y=22)))
120 self.assertRaises(TypeError, Point, 1) # too few args
121 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
122 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
123 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
124 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Ezio Melottiaa980582010-01-23 23:04:36 +0000125 self.assertNotIn('__weakref__', dir(p))
Raymond Hettinger02740f72008-01-05 01:35:43 +0000126 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
Raymond Hettinger42da8742007-12-14 02:49:47 +0000127 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
128 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
129 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
Raymond Hettinger7393c692013-05-27 10:58:55 -0700130 self.assertEqual(vars(p), p._asdict()) # verify that vars() works
Raymond Hettingerd36a60e2007-09-17 00:55:00 +0000131
Raymond Hettinger1b50fd72008-01-05 02:17:24 +0000132 try:
133 p._replace(x=1, error=2)
134 except ValueError:
135 pass
136 else:
137 self._fail('Did not detect an incorrect fieldname')
138
Raymond Hettingerd36a60e2007-09-17 00:55:00 +0000139 # verify that field string can have commas
Raymond Hettinger01a09572007-10-23 20:37:41 +0000140 Point = namedtuple('Point', 'x, y')
Raymond Hettingerd36a60e2007-09-17 00:55:00 +0000141 p = Point(x=11, y=22)
142 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000143
Raymond Hettinger2115bbc2007-10-08 09:14:28 +0000144 # verify that fieldspec can be a non-string sequence
Raymond Hettinger01a09572007-10-23 20:37:41 +0000145 Point = namedtuple('Point', ('x', 'y'))
Raymond Hettinger2115bbc2007-10-08 09:14:28 +0000146 p = Point(x=11, y=22)
147 self.assertEqual(repr(p), 'Point(x=11, y=22)')
148
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000149 def test_tupleness(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +0000150 Point = namedtuple('Point', 'x y')
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000151 p = Point(11, 22)
152
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000153 self.assertIsInstance(p, tuple)
Raymond Hettingerc37e5e02007-03-01 06:16:43 +0000154 self.assertEqual(p, (11, 22)) # matches a real tuple
155 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
156 self.assertEqual(list(p), [11, 22]) # coercable to a list
157 self.assertEqual(max(p), 22) # iterable
158 self.assertEqual(max(*p), 22) # star-able
159 x, y = p
160 self.assertEqual(p, (x, y)) # unpacks like a tuple
161 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
162 self.assertRaises(IndexError, p.__getitem__, 3)
163
164 self.assertEqual(p.x, x)
165 self.assertEqual(p.y, y)
166 self.assertRaises(AttributeError, eval, 'p.z', locals())
167
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000168 def test_odd_sizes(self):
Raymond Hettinger01a09572007-10-23 20:37:41 +0000169 Zero = namedtuple('Zero', '')
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000170 self.assertEqual(Zero(), ())
Raymond Hettinger02740f72008-01-05 01:35:43 +0000171 self.assertEqual(Zero._make([]), ())
Raymond Hettinger88880b22007-12-18 00:13:45 +0000172 self.assertEqual(repr(Zero()), 'Zero()')
173 self.assertEqual(Zero()._asdict(), {})
174 self.assertEqual(Zero()._fields, ())
175
Raymond Hettinger01a09572007-10-23 20:37:41 +0000176 Dot = namedtuple('Dot', 'd')
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000177 self.assertEqual(Dot(1), (1,))
Raymond Hettinger02740f72008-01-05 01:35:43 +0000178 self.assertEqual(Dot._make([1]), (1,))
Raymond Hettinger88880b22007-12-18 00:13:45 +0000179 self.assertEqual(Dot(1).d, 1)
180 self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
181 self.assertEqual(Dot(1)._asdict(), {'d':1})
182 self.assertEqual(Dot(1)._replace(d=999), (999,))
183 self.assertEqual(Dot(1)._fields, ('d',))
Raymond Hettinger2b03d452007-09-18 03:33:19 +0000184
Raymond Hettingere98839a2008-06-09 01:28:30 +0000185 n = 5000
Serhiy Storchaka282e8312015-11-25 17:19:27 +0200186 names = list(set(''.join([choice(string.ascii_letters)
Georg Brandl0bb02992008-05-18 10:39:26 +0000187 for j in range(10)]) for i in range(n)))
188 n = len(names)
Raymond Hettinger88880b22007-12-18 00:13:45 +0000189 Big = namedtuple('Big', names)
190 b = Big(*range(n))
191 self.assertEqual(b, tuple(range(n)))
Raymond Hettinger02740f72008-01-05 01:35:43 +0000192 self.assertEqual(Big._make(range(n)), tuple(range(n)))
Raymond Hettinger88880b22007-12-18 00:13:45 +0000193 for pos, name in enumerate(names):
194 self.assertEqual(getattr(b, name), pos)
195 repr(b) # make sure repr() doesn't blow-up
196 d = b._asdict()
197 d_expected = dict(zip(names, range(n)))
198 self.assertEqual(d, d_expected)
199 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
200 b2_expected = range(n)
201 b2_expected[1] = 999
202 b2_expected[-5] = 42
203 self.assertEqual(b2, tuple(b2_expected))
204 self.assertEqual(b._fields, tuple(names))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000205
Raymond Hettingere98839a2008-06-09 01:28:30 +0000206 def test_pickle(self):
207 p = TestNT(x=10, y=20, z=30)
208 for module in pickle, cPickle:
209 loads = getattr(module, 'loads')
210 dumps = getattr(module, 'dumps')
211 for protocol in -1, 0, 1, 2:
212 q = loads(dumps(p, protocol))
213 self.assertEqual(p, q)
214 self.assertEqual(p._fields, q._fields)
215
216 def test_copy(self):
217 p = TestNT(x=10, y=20, z=30)
218 for copier in copy.copy, copy.deepcopy:
219 q = copier(p)
220 self.assertEqual(p, q)
221 self.assertEqual(p._fields, q._fields)
222
Raymond Hettingera68cad12009-05-27 02:24:45 +0000223 def test_name_conflicts(self):
224 # Some names like "self", "cls", "tuple", "itemgetter", and "property"
225 # failed when used as field names. Test to make sure these now work.
226 T = namedtuple('T', 'itemgetter property self cls tuple')
227 t = T(1, 2, 3, 4, 5)
228 self.assertEqual(t, (1,2,3,4,5))
229 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
230 self.assertEqual(newt, (10,20,30,40,50))
231
232 # Broader test of all interesting names in a template
233 with test_support.captured_stdout() as template:
234 T = namedtuple('T', 'x', verbose=True)
235 words = set(re.findall('[A-Za-z]+', template.getvalue()))
236 words -= set(keyword.kwlist)
237 T = namedtuple('T', words)
238 # test __new__
239 values = tuple(range(len(words)))
240 t = T(*values)
241 self.assertEqual(t, values)
242 t = T(**dict(zip(T._fields, values)))
243 self.assertEqual(t, values)
244 # test _make
245 t = T._make(values)
246 self.assertEqual(t, values)
247 # exercise __repr__
248 repr(t)
249 # test _asdict
250 self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
251 # test _replace
252 t = T._make(values)
253 newvalues = tuple(v*10 for v in values)
254 newt = t._replace(**dict(zip(T._fields, newvalues)))
255 self.assertEqual(newt, newvalues)
256 # test _fields
257 self.assertEqual(T._fields, tuple(words))
258 # test __getnewargs__
259 self.assertEqual(t.__getnewargs__(), values)
260
Raymond Hettinger7393c692013-05-27 10:58:55 -0700261 def test_pickling_bug_18015(self):
262 # http://bugs.python.org/issue18015
263 pt = pickle.loads(py273_named_tuple_pickle)
264 self.assertEqual(pt.x, 10)
265
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000266class ABCTestCase(unittest.TestCase):
267
268 def validate_abstract_methods(self, abc, *names):
269 methodstubs = dict.fromkeys(names, lambda s, *args: 0)
270
271 # everything should work will all required methods are present
272 C = type('C', (abc,), methodstubs)
273 C()
274
275 # instantiation should fail if a required method is missing
276 for name in names:
277 stubs = methodstubs.copy()
278 del stubs[name]
279 C = type('C', (abc,), stubs)
280 self.assertRaises(TypeError, C, name)
281
Florent Xicluna47627d52010-03-08 15:20:28 +0000282 def validate_isinstance(self, abc, name):
283 stub = lambda s, *args: 0
284
285 # new-style class
286 C = type('C', (object,), {name: stub})
287 self.assertIsInstance(C(), abc)
288 self.assertTrue(issubclass(C, abc))
289 # old-style class
290 class C: pass
291 setattr(C, name, stub)
292 self.assertIsInstance(C(), abc)
293 self.assertTrue(issubclass(C, abc))
294
295 # new-style class
296 C = type('C', (object,), {'__hash__': None})
297 self.assertNotIsInstance(C(), abc)
298 self.assertFalse(issubclass(C, abc))
299 # old-style class
300 class C: pass
301 self.assertNotIsInstance(C(), abc)
302 self.assertFalse(issubclass(C, abc))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000303
Benjamin Petersoneb318d32010-05-21 20:51:45 +0000304 def validate_comparison(self, instance):
305 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
306 operators = {}
307 for op in ops:
308 name = '__' + op + '__'
309 operators[name] = getattr(operator, name)
310
311 class Other:
312 def __init__(self):
313 self.right_side = False
314 def __eq__(self, other):
315 self.right_side = True
316 return True
317 __lt__ = __eq__
318 __gt__ = __eq__
319 __le__ = __eq__
320 __ge__ = __eq__
321 __ne__ = __eq__
322 __ror__ = __eq__
323 __rand__ = __eq__
324 __rxor__ = __eq__
325 __rsub__ = __eq__
326
327 for name, op in operators.items():
328 if not hasattr(instance, name):
329 continue
330 other = Other()
331 op(instance, other)
332 self.assertTrue(other.right_side,'Right side not called for %s.%s'
333 % (type(instance), name))
334
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000335class TestOneTrickPonyABCs(ABCTestCase):
Guido van Rossum64c06e32007-11-22 00:55:51 +0000336
337 def test_Hashable(self):
338 # Check some non-hashables
339 non_samples = [list(), set(), dict()]
340 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000341 self.assertNotIsInstance(x, Hashable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000342 self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000343 # Check some hashables
344 samples = [None,
345 int(), float(), complex(),
346 str(),
347 tuple(), frozenset(),
348 int, list, object, type,
349 ]
350 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000351 self.assertIsInstance(x, Hashable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000352 self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000353 self.assertRaises(TypeError, Hashable)
354 # Check direct subclassing
355 class H(Hashable):
356 def __hash__(self):
357 return super(H, self).__hash__()
Nick Coghlan48361f52008-08-11 15:45:58 +0000358 __eq__ = Hashable.__eq__ # Silence Py3k warning
Guido van Rossum64c06e32007-11-22 00:55:51 +0000359 self.assertEqual(hash(H()), 0)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000360 self.assertFalse(issubclass(int, H))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000361 self.validate_abstract_methods(Hashable, '__hash__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000362 self.validate_isinstance(Hashable, '__hash__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000363
364 def test_Iterable(self):
365 # Check some non-iterables
366 non_samples = [None, 42, 3.14, 1j]
367 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000368 self.assertNotIsInstance(x, Iterable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000369 self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000370 # Check some iterables
371 samples = [str(),
372 tuple(), list(), set(), frozenset(), dict(),
373 dict().keys(), dict().items(), dict().values(),
374 (lambda: (yield))(),
375 (x for x in []),
376 ]
377 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000378 self.assertIsInstance(x, Iterable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000379 self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000380 # Check direct subclassing
381 class I(Iterable):
382 def __iter__(self):
383 return super(I, self).__iter__()
384 self.assertEqual(list(I()), [])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000385 self.assertFalse(issubclass(str, I))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000386 self.validate_abstract_methods(Iterable, '__iter__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000387 self.validate_isinstance(Iterable, '__iter__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000388
389 def test_Iterator(self):
390 non_samples = [None, 42, 3.14, 1j, "".encode('ascii'), "", (), [],
391 {}, set()]
392 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000393 self.assertNotIsInstance(x, Iterator)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000394 self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000395 samples = [iter(str()),
396 iter(tuple()), iter(list()), iter(dict()),
397 iter(set()), iter(frozenset()),
398 iter(dict().keys()), iter(dict().items()),
399 iter(dict().values()),
400 (lambda: (yield))(),
401 (x for x in []),
402 ]
403 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000404 self.assertIsInstance(x, Iterator)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000405 self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
Alexander Belopolsky1fea5c42010-11-30 01:18:17 +0000406 self.validate_abstract_methods(Iterator, 'next', '__iter__')
407
408 # Issue 10565
409 class NextOnly:
410 def __next__(self):
411 yield 1
412 raise StopIteration
413 self.assertNotIsInstance(NextOnly(), Iterator)
414 class NextOnlyNew(object):
415 def __next__(self):
416 yield 1
417 raise StopIteration
418 self.assertNotIsInstance(NextOnlyNew(), Iterator)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000419
420 def test_Sized(self):
421 non_samples = [None, 42, 3.14, 1j,
422 (lambda: (yield))(),
423 (x for x in []),
424 ]
425 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000426 self.assertNotIsInstance(x, Sized)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000427 self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000428 samples = [str(),
429 tuple(), list(), set(), frozenset(), dict(),
430 dict().keys(), dict().items(), dict().values(),
431 ]
432 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000433 self.assertIsInstance(x, Sized)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000434 self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000435 self.validate_abstract_methods(Sized, '__len__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000436 self.validate_isinstance(Sized, '__len__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000437
438 def test_Container(self):
439 non_samples = [None, 42, 3.14, 1j,
440 (lambda: (yield))(),
441 (x for x in []),
442 ]
443 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000444 self.assertNotIsInstance(x, Container)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000445 self.assertFalse(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000446 samples = [str(),
447 tuple(), list(), set(), frozenset(), dict(),
448 dict().keys(), dict().items(),
449 ]
450 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000451 self.assertIsInstance(x, Container)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000452 self.assertTrue(issubclass(type(x), Container), repr(type(x)))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000453 self.validate_abstract_methods(Container, '__contains__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000454 self.validate_isinstance(Container, '__contains__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000455
456 def test_Callable(self):
457 non_samples = [None, 42, 3.14, 1j,
458 "", "".encode('ascii'), (), [], {}, set(),
459 (lambda: (yield))(),
460 (x for x in []),
461 ]
462 for x in non_samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000463 self.assertNotIsInstance(x, Callable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000464 self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000465 samples = [lambda: None,
466 type, int, object,
467 len,
468 list.append, [].append,
469 ]
470 for x in samples:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000471 self.assertIsInstance(x, Callable)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000472 self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000473 self.validate_abstract_methods(Callable, '__call__')
Florent Xicluna47627d52010-03-08 15:20:28 +0000474 self.validate_isinstance(Callable, '__call__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000475
476 def test_direct_subclassing(self):
477 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
478 class C(B):
479 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000480 self.assertTrue(issubclass(C, B))
481 self.assertFalse(issubclass(int, C))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000482
483 def test_registration(self):
484 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
485 class C:
486 __metaclass__ = type
487 __hash__ = None # Make sure it isn't hashable by default
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000488 self.assertFalse(issubclass(C, B), B.__name__)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000489 B.register(C)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000490 self.assertTrue(issubclass(C, B))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000491
Raymond Hettinger66c4a6b2009-04-01 18:50:56 +0000492class WithSet(MutableSet):
493
494 def __init__(self, it=()):
495 self.data = set(it)
496
497 def __len__(self):
498 return len(self.data)
499
500 def __iter__(self):
501 return iter(self.data)
502
503 def __contains__(self, item):
504 return item in self.data
505
506 def add(self, item):
507 self.data.add(item)
508
509 def discard(self, item):
510 self.data.discard(item)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000511
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000512class TestCollectionABCs(ABCTestCase):
Guido van Rossum64c06e32007-11-22 00:55:51 +0000513
514 # XXX For now, we only test some virtual inheritance properties.
515 # We should also test the proper behavior of the collection ABCs
516 # as real base classes or mix-in classes.
517
518 def test_Set(self):
519 for sample in [set, frozenset]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000520 self.assertIsInstance(sample(), Set)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000521 self.assertTrue(issubclass(sample, Set))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000522 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
Benjamin Petersoneb318d32010-05-21 20:51:45 +0000523 class MySet(Set):
524 def __contains__(self, x):
525 return False
526 def __len__(self):
527 return 0
528 def __iter__(self):
529 return iter([])
530 self.validate_comparison(MySet())
Guido van Rossum64c06e32007-11-22 00:55:51 +0000531
Raymond Hettinger4c52f522008-06-23 03:29:28 +0000532 def test_hash_Set(self):
533 class OneTwoThreeSet(Set):
534 def __init__(self):
535 self.contents = [1, 2, 3]
536 def __contains__(self, x):
537 return x in self.contents
538 def __len__(self):
539 return len(self.contents)
540 def __iter__(self):
541 return iter(self.contents)
542 def __hash__(self):
543 return self._hash()
544 a, b = OneTwoThreeSet(), OneTwoThreeSet()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000545 self.assertTrue(hash(a) == hash(b))
Raymond Hettinger4c52f522008-06-23 03:29:28 +0000546
Guido van Rossum64c06e32007-11-22 00:55:51 +0000547 def test_MutableSet(self):
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000548 self.assertIsInstance(set(), MutableSet)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000549 self.assertTrue(issubclass(set, MutableSet))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000550 self.assertNotIsInstance(frozenset(), MutableSet)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000551 self.assertFalse(issubclass(frozenset, MutableSet))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000552 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
553 'add', 'discard')
554
Raymond Hettinger66c4a6b2009-04-01 18:50:56 +0000555 def test_issue_5647(self):
556 # MutableSet.__iand__ mutated the set during iteration
557 s = WithSet('abcd')
558 s &= WithSet('cdef') # This used to fail
559 self.assertEqual(set(s), set('cd'))
560
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000561 def test_issue_4920(self):
562 # MutableSet.pop() method did not work
Serhiy Storchaka282e8312015-11-25 17:19:27 +0200563 class MySet(MutableSet):
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000564 __slots__=['__s']
565 def __init__(self,items=None):
566 if items is None:
567 items=[]
568 self.__s=set(items)
569 def __contains__(self,v):
570 return v in self.__s
571 def __iter__(self):
572 return iter(self.__s)
573 def __len__(self):
574 return len(self.__s)
575 def add(self,v):
576 result=v not in self.__s
577 self.__s.add(v)
578 return result
579 def discard(self,v):
580 result=v in self.__s
581 self.__s.discard(v)
582 return result
583 def __repr__(self):
584 return "MySet(%s)" % repr(list(self))
585 s = MySet([5,43,2,1])
586 self.assertEqual(s.pop(), 1)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000587
Daniel Stutzbach91287322010-08-24 21:09:30 +0000588 def test_issue8750(self):
589 empty = WithSet()
590 full = WithSet(range(10))
591 s = WithSet(full)
592 s -= s
593 self.assertEqual(s, empty)
594 s = WithSet(full)
595 s ^= s
596 self.assertEqual(s, empty)
597 s = WithSet(full)
598 s &= s
599 self.assertEqual(s, full)
600 s |= s
601 self.assertEqual(s, full)
602
Serhiy Storchaka7c573852013-12-06 23:23:15 +0200603 def test_issue16373(self):
604 # Recursion error comparing comparable and noncomparable
605 # Set instances
606 class MyComparableSet(Set):
607 def __contains__(self, x):
608 return False
609 def __len__(self):
610 return 0
611 def __iter__(self):
612 return iter([])
613 class MyNonComparableSet(Set):
614 def __contains__(self, x):
615 return False
616 def __len__(self):
617 return 0
618 def __iter__(self):
619 return iter([])
620 def __le__(self, x):
621 return NotImplemented
622 def __lt__(self, x):
623 return NotImplemented
624
625 cs = MyComparableSet()
626 ncs = MyNonComparableSet()
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700627
628 # Run all the variants to make sure they don't mutually recurse
629 ncs < cs
630 ncs <= cs
631 ncs > cs
632 ncs >= cs
633 cs < ncs
634 cs <= ncs
635 cs > ncs
636 cs >= ncs
637
638 def assertSameSet(self, s1, s2):
639 # coerce both to a real set then check equality
640 self.assertEqual(set(s1), set(s2))
641
642 def test_Set_interoperability_with_real_sets(self):
643 # Issue: 8743
644 class ListSet(Set):
645 def __init__(self, elements=()):
646 self.data = []
647 for elem in elements:
648 if elem not in self.data:
649 self.data.append(elem)
650 def __contains__(self, elem):
651 return elem in self.data
652 def __iter__(self):
653 return iter(self.data)
654 def __len__(self):
655 return len(self.data)
656 def __repr__(self):
657 return 'Set({!r})'.format(self.data)
658
659 r1 = set('abc')
660 r2 = set('bcd')
661 r3 = set('abcde')
662 f1 = ListSet('abc')
663 f2 = ListSet('bcd')
664 f3 = ListSet('abcde')
665 l1 = list('abccba')
666 l2 = list('bcddcb')
667 l3 = list('abcdeedcba')
668 p1 = sets.Set('abc')
669 p2 = sets.Set('bcd')
670 p3 = sets.Set('abcde')
671
672 target = r1 & r2
673 self.assertSameSet(f1 & f2, target)
674 self.assertSameSet(f1 & r2, target)
675 self.assertSameSet(r2 & f1, target)
676 self.assertSameSet(f1 & p2, target)
677 self.assertSameSet(p2 & f1, target)
678 self.assertSameSet(f1 & l2, target)
679
680 target = r1 | r2
681 self.assertSameSet(f1 | f2, target)
682 self.assertSameSet(f1 | r2, target)
683 self.assertSameSet(r2 | f1, target)
684 self.assertSameSet(f1 | p2, target)
685 self.assertSameSet(p2 | f1, target)
686 self.assertSameSet(f1 | l2, target)
687
688 fwd_target = r1 - r2
689 rev_target = r2 - r1
690 self.assertSameSet(f1 - f2, fwd_target)
691 self.assertSameSet(f2 - f1, rev_target)
692 self.assertSameSet(f1 - r2, fwd_target)
693 self.assertSameSet(f2 - r1, rev_target)
694 self.assertSameSet(r1 - f2, fwd_target)
695 self.assertSameSet(r2 - f1, rev_target)
696 self.assertSameSet(f1 - p2, fwd_target)
697 self.assertSameSet(f2 - p1, rev_target)
698 self.assertSameSet(p1 - f2, fwd_target)
699 self.assertSameSet(p2 - f1, rev_target)
700 self.assertSameSet(f1 - l2, fwd_target)
701 self.assertSameSet(f2 - l1, rev_target)
702
703 target = r1 ^ r2
704 self.assertSameSet(f1 ^ f2, target)
705 self.assertSameSet(f1 ^ r2, target)
706 self.assertSameSet(r2 ^ f1, target)
707 self.assertSameSet(f1 ^ p2, target)
708 self.assertSameSet(p2 ^ f1, target)
709 self.assertSameSet(f1 ^ l2, target)
710
711 # proper subset
712 self.assertTrue(f1 < f3)
713 self.assertFalse(f1 < f1)
714 self.assertFalse(f1 < f2)
715 self.assertTrue(r1 < f3)
716 self.assertFalse(r1 < f1)
717 self.assertFalse(r1 < f2)
718 self.assertTrue(r1 < r3)
719 self.assertFalse(r1 < r1)
720 self.assertFalse(r1 < r2)
Victor Stinnera3acea32014-09-05 21:05:05 +0200721
722 with test_support.check_py3k_warnings():
723 # python 2 only, cross-type compares will succeed
724 f1 < l3
725 f1 < l1
726 f1 < l2
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700727
728 # any subset
729 self.assertTrue(f1 <= f3)
730 self.assertTrue(f1 <= f1)
731 self.assertFalse(f1 <= f2)
732 self.assertTrue(r1 <= f3)
733 self.assertTrue(r1 <= f1)
734 self.assertFalse(r1 <= f2)
735 self.assertTrue(r1 <= r3)
736 self.assertTrue(r1 <= r1)
737 self.assertFalse(r1 <= r2)
Victor Stinnera3acea32014-09-05 21:05:05 +0200738
739 with test_support.check_py3k_warnings():
740 # python 2 only, cross-type compares will succeed
741 f1 <= l3
742 f1 <= l1
743 f1 <= l2
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700744
745 # proper superset
746 self.assertTrue(f3 > f1)
747 self.assertFalse(f1 > f1)
748 self.assertFalse(f2 > f1)
749 self.assertTrue(r3 > r1)
750 self.assertFalse(f1 > r1)
751 self.assertFalse(f2 > r1)
752 self.assertTrue(r3 > r1)
753 self.assertFalse(r1 > r1)
754 self.assertFalse(r2 > r1)
Victor Stinnera3acea32014-09-05 21:05:05 +0200755
756 with test_support.check_py3k_warnings():
757 # python 2 only, cross-type compares will succeed
758 f1 > l3
759 f1 > l1
760 f1 > l2
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700761
762 # any superset
763 self.assertTrue(f3 >= f1)
764 self.assertTrue(f1 >= f1)
765 self.assertFalse(f2 >= f1)
766 self.assertTrue(r3 >= r1)
767 self.assertTrue(f1 >= r1)
768 self.assertFalse(f2 >= r1)
769 self.assertTrue(r3 >= r1)
770 self.assertTrue(r1 >= r1)
771 self.assertFalse(r2 >= r1)
Victor Stinnera3acea32014-09-05 21:05:05 +0200772
773 with test_support.check_py3k_warnings():
774 # python 2 only, cross-type compares will succeed
775 f1 >= l3
776 f1 >=l1
777 f1 >= l2
Raymond Hettingerf643b9a2014-05-25 22:13:41 -0700778
779 # equality
780 self.assertTrue(f1 == f1)
781 self.assertTrue(r1 == f1)
782 self.assertTrue(f1 == r1)
783 self.assertFalse(f1 == f3)
784 self.assertFalse(r1 == f3)
785 self.assertFalse(f1 == r3)
786 # python 2 only, cross-type compares will succeed
787 f1 == l3
788 f1 == l1
789 f1 == l2
790
791 # inequality
792 self.assertFalse(f1 != f1)
793 self.assertFalse(r1 != f1)
794 self.assertFalse(f1 != r1)
795 self.assertTrue(f1 != f3)
796 self.assertTrue(r1 != f3)
797 self.assertTrue(f1 != r3)
798 # python 2 only, cross-type compares will succeed
799 f1 != l3
800 f1 != l1
801 f1 != l2
Serhiy Storchaka7c573852013-12-06 23:23:15 +0200802
Guido van Rossum64c06e32007-11-22 00:55:51 +0000803 def test_Mapping(self):
804 for sample in [dict]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000805 self.assertIsInstance(sample(), Mapping)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000806 self.assertTrue(issubclass(sample, Mapping))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000807 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
808 '__getitem__')
Serhiy Storchaka282e8312015-11-25 17:19:27 +0200809 class MyMapping(Mapping):
Benjamin Petersoneb318d32010-05-21 20:51:45 +0000810 def __len__(self):
811 return 0
812 def __getitem__(self, i):
813 raise IndexError
814 def __iter__(self):
815 return iter(())
816 self.validate_comparison(MyMapping())
Guido van Rossum64c06e32007-11-22 00:55:51 +0000817
818 def test_MutableMapping(self):
819 for sample in [dict]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000820 self.assertIsInstance(sample(), MutableMapping)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000821 self.assertTrue(issubclass(sample, MutableMapping))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000822 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
823 '__getitem__', '__setitem__', '__delitem__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000824
825 def test_Sequence(self):
826 for sample in [tuple, list, str]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000827 self.assertIsInstance(sample(), Sequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000828 self.assertTrue(issubclass(sample, Sequence))
829 self.assertTrue(issubclass(basestring, Sequence))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000830 self.assertIsInstance(range(10), Sequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000831 self.assertTrue(issubclass(xrange, Sequence))
832 self.assertTrue(issubclass(str, Sequence))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000833 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
834 '__getitem__')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000835
836 def test_MutableSequence(self):
837 for sample in [tuple, str]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000838 self.assertNotIsInstance(sample(), MutableSequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000839 self.assertFalse(issubclass(sample, MutableSequence))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000840 for sample in [list]:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000841 self.assertIsInstance(sample(), MutableSequence)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000842 self.assertTrue(issubclass(sample, MutableSequence))
843 self.assertFalse(issubclass(basestring, MutableSequence))
Raymond Hettingerf779e6f2009-01-28 23:02:26 +0000844 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
845 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
Guido van Rossum64c06e32007-11-22 00:55:51 +0000846
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000847class TestCounter(unittest.TestCase):
848
849 def test_basics(self):
850 c = Counter('abcaba')
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000851 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
852 self.assertEqual(c, Counter(a=3, b=2, c=1))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000853 self.assertIsInstance(c, dict)
854 self.assertIsInstance(c, Mapping)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000855 self.assertTrue(issubclass(Counter, dict))
856 self.assertTrue(issubclass(Counter, Mapping))
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000857 self.assertEqual(len(c), 3)
858 self.assertEqual(sum(c.values()), 6)
859 self.assertEqual(sorted(c.values()), [1, 2, 3])
860 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
861 self.assertEqual(sorted(c), ['a', 'b', 'c'])
862 self.assertEqual(sorted(c.items()),
863 [('a', 3), ('b', 2), ('c', 1)])
864 self.assertEqual(c['b'], 2)
865 self.assertEqual(c['z'], 0)
Florent Xicluna47627d52010-03-08 15:20:28 +0000866 with test_support.check_py3k_warnings():
867 self.assertEqual(c.has_key('c'), True)
868 self.assertEqual(c.has_key('z'), False)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000869 self.assertEqual(c.__contains__('c'), True)
870 self.assertEqual(c.__contains__('z'), False)
871 self.assertEqual(c.get('b', 10), 2)
872 self.assertEqual(c.get('z', 10), 10)
873 self.assertEqual(c, dict(a=3, b=2, c=1))
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000874 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000875 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
876 for i in range(5):
877 self.assertEqual(c.most_common(i),
878 [('a', 3), ('b', 2), ('c', 1)][:i])
879 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
880 c['a'] += 1 # increment an existing value
881 c['b'] -= 2 # sub existing value to zero
882 del c['c'] # remove an entry
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000883 del c['c'] # make sure that del doesn't raise KeyError
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000884 c['d'] -= 2 # sub from a missing value
885 c['e'] = -5 # directly assign a missing value
886 c['f'] += 4 # add to a missing value
887 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
888 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
889 self.assertEqual(c.pop('f'), 4)
Ezio Melottiaa980582010-01-23 23:04:36 +0000890 self.assertNotIn('f', c)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000891 for i in range(3):
892 elem, cnt = c.popitem()
Ezio Melottiaa980582010-01-23 23:04:36 +0000893 self.assertNotIn(elem, c)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000894 c.clear()
895 self.assertEqual(c, {})
896 self.assertEqual(repr(c), 'Counter()')
897 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
898 self.assertRaises(TypeError, hash, c)
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000899 c.update(dict(a=5, b=3))
900 c.update(c=1)
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000901 c.update(Counter('a' * 50 + 'b' * 30))
Raymond Hettingerafd112b2009-01-14 01:15:06 +0000902 c.update() # test case with no args
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000903 c.__init__('a' * 500 + 'b' * 300)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000904 c.__init__('cdc')
Raymond Hettingerafd112b2009-01-14 01:15:06 +0000905 c.__init__()
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000906 self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
907 self.assertEqual(c.setdefault('d', 5), 1)
908 self.assertEqual(c['d'], 1)
909 self.assertEqual(c.setdefault('e', 5), 5)
910 self.assertEqual(c['e'], 5)
911
Serhiy Storchaka20994f12014-11-27 19:02:56 +0200912 def test_init(self):
913 self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
914 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
915 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
916 self.assertRaises(TypeError, Counter, 42)
917 self.assertRaises(TypeError, Counter, (), ())
918 self.assertRaises(TypeError, Counter.__init__)
919
920 def test_update(self):
921 c = Counter()
922 c.update(self=42)
923 self.assertEqual(list(c.items()), [('self', 42)])
924 c = Counter()
925 c.update(iterable=42)
926 self.assertEqual(list(c.items()), [('iterable', 42)])
927 c = Counter()
928 c.update(iterable=None)
929 self.assertEqual(list(c.items()), [('iterable', None)])
930 self.assertRaises(TypeError, Counter().update, 42)
931 self.assertRaises(TypeError, Counter().update, {}, {})
932 self.assertRaises(TypeError, Counter.update)
933
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000934 def test_copying(self):
935 # Check that counters are copyable, deepcopyable, picklable, and
936 #have a repr/eval round-trip
937 words = Counter('which witch had which witches wrist watch'.split())
938 update_test = Counter()
939 update_test.update(words)
940 for i, dup in enumerate([
941 words.copy(),
942 copy.copy(words),
943 copy.deepcopy(words),
944 pickle.loads(pickle.dumps(words, 0)),
945 pickle.loads(pickle.dumps(words, 1)),
946 pickle.loads(pickle.dumps(words, 2)),
947 pickle.loads(pickle.dumps(words, -1)),
948 cPickle.loads(cPickle.dumps(words, 0)),
949 cPickle.loads(cPickle.dumps(words, 1)),
950 cPickle.loads(cPickle.dumps(words, 2)),
951 cPickle.loads(cPickle.dumps(words, -1)),
952 eval(repr(words)),
953 update_test,
Raymond Hettingeraaa6e632009-01-13 01:05:03 +0000954 Counter(words),
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000955 ]):
956 msg = (i, dup, words)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000957 self.assertTrue(dup is not words)
Ezio Melotti2623a372010-11-21 13:34:58 +0000958 self.assertEqual(dup, words)
959 self.assertEqual(len(dup), len(words))
960 self.assertEqual(type(dup), type(words))
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000961
Raymond Hettinger37c0fe52011-04-15 13:12:21 -0700962 def test_copy_subclass(self):
963 class MyCounter(Counter):
964 pass
965 c = MyCounter('slartibartfast')
966 d = c.copy()
967 self.assertEqual(d, c)
968 self.assertEqual(len(d), len(c))
969 self.assertEqual(type(d), type(c))
970
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +0000971 def test_conversions(self):
972 # Convert to: set, list, dict
973 s = 'she sells sea shells by the sea shore'
974 self.assertEqual(sorted(Counter(s).elements()), sorted(s))
975 self.assertEqual(sorted(Counter(s)), sorted(set(s)))
976 self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
977 self.assertEqual(set(Counter(s)), set(s))
978
Raymond Hettinger0a1f7b82009-01-21 23:12:51 +0000979 def test_invariant_for_the_in_operator(self):
980 c = Counter(a=10, b=-2, c=0)
981 for elem in c:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000982 self.assertTrue(elem in c)
Ezio Melottiaa980582010-01-23 23:04:36 +0000983 self.assertIn(elem, c)
Raymond Hettinger0a1f7b82009-01-21 23:12:51 +0000984
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000985 def test_multiset_operations(self):
986 # Verify that adding a zero counter will strip zeros and negatives
987 c = Counter(a=10, b=-2, c=0) + Counter()
988 self.assertEqual(dict(c), dict(a=10))
989
990 elements = 'abcd'
991 for i in range(1000):
992 # test random pairs of multisets
993 p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettinger4571f342009-01-21 20:31:50 +0000994 p.update(e=1, f=-1, g=0)
Raymond Hettingerbad1eb22009-01-20 01:19:26 +0000995 q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
Raymond Hettinger4571f342009-01-21 20:31:50 +0000996 q.update(h=1, i=-1, j=0)
997 for counterop, numberop in [
998 (Counter.__add__, lambda x, y: max(0, x+y)),
999 (Counter.__sub__, lambda x, y: max(0, x-y)),
1000 (Counter.__or__, lambda x, y: max(0,x,y)),
1001 (Counter.__and__, lambda x, y: max(0, min(x,y))),
Raymond Hettingerbad1eb22009-01-20 01:19:26 +00001002 ]:
1003 result = counterop(p, q)
1004 for x in elements:
Raymond Hettinger4571f342009-01-21 20:31:50 +00001005 self.assertEqual(numberop(p[x], q[x]), result[x],
1006 (counterop, x, p, q))
Raymond Hettingerbad1eb22009-01-20 01:19:26 +00001007 # verify that results exclude non-positive counts
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001008 self.assertTrue(x>0 for x in result.values())
Raymond Hettingerbad1eb22009-01-20 01:19:26 +00001009
1010 elements = 'abcdef'
1011 for i in range(100):
1012 # verify that random multisets with no repeats are exactly like sets
1013 p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1014 q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
1015 for counterop, setop in [
1016 (Counter.__sub__, set.__sub__),
1017 (Counter.__or__, set.__or__),
1018 (Counter.__and__, set.__and__),
1019 ]:
1020 counter_result = counterop(p, q)
1021 set_result = setop(set(p.elements()), set(q.elements()))
1022 self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +00001023
Raymond Hettinger34c35b22010-04-03 10:22:00 +00001024 def test_subtract(self):
1025 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1026 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
1027 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1028 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
1029 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
1030 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
1031 c = Counter('aaabbcd')
1032 c.subtract('aaaabbcce')
1033 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
1034
Serhiy Storchaka20994f12014-11-27 19:02:56 +02001035 c = Counter()
1036 c.subtract(self=42)
1037 self.assertEqual(list(c.items()), [('self', -42)])
1038 c = Counter()
1039 c.subtract(iterable=42)
1040 self.assertEqual(list(c.items()), [('iterable', -42)])
1041 self.assertRaises(TypeError, Counter().subtract, 42)
1042 self.assertRaises(TypeError, Counter().subtract, {}, {})
1043 self.assertRaises(TypeError, Counter.subtract)
1044
Guido van Rossum64c06e32007-11-22 00:55:51 +00001045
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00001046def test_main(verbose=None):
Amaury Forgeot d'Arccb0f2ad2008-04-02 00:55:04 +00001047 NamedTupleDocs = doctest.DocTestSuite(module=collections)
Raymond Hettingerf94d7fa2009-01-12 22:58:41 +00001048 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
Serhiy Storchaka282e8312015-11-25 17:19:27 +02001049 TestCollectionABCs, TestCounter]
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00001050 test_support.run_unittest(*test_classes)
Amaury Forgeot d'Arccb0f2ad2008-04-02 00:55:04 +00001051 test_support.run_doctest(collections, verbose)
Raymond Hettingerc37e5e02007-03-01 06:16:43 +00001052
1053if __name__ == "__main__":
1054 test_main(verbose=True)