1import collections
2import copy
3import doctest
4import keyword
5import operator
6import pickle
7import cPickle
8from random import choice, randrange
9import re
10import string
11import sys
12from test import test_support
13import unittest
14
15from collections import namedtuple, Counter, OrderedDict
16from 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
21
22# Silence deprecation warning
23sets = test_support.import_module('sets', deprecated=True)
24
25TestNT = namedtuple('TestNT', 'x y z')    # type used for pickle tests
26
27py273_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
64class TestNamedTuple(unittest.TestCase):
65
66    def test_factory(self):
67        Point = namedtuple('Point', 'x y')
68        self.assertEqual(Point.__name__, 'Point')
69        self.assertEqual(Point.__slots__, ())
70        self.assertEqual(Point.__module__, __name__)
71        self.assertEqual(Point.__getitem__, tuple.__getitem__)
72        self.assertEqual(Point._fields, ('x', 'y'))
73
74        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
77
78        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
81        self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi')       # field with leading underscore
82        self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi')    # duplicate field
83
84        namedtuple('Point0', 'x1 y2')   # Verify that numbers are allowed in names
85        namedtuple('_', 'a b c')        # Test leading underscores in a typename
86
87        nt = namedtuple('nt', u'the quick brown fox')                       # check unicode input
88        self.assertNotIn("u'", repr(nt._fields))
89        nt = namedtuple('nt', (u'the', u'quick'))                           # check unicode input
90        self.assertNotIn("u'", repr(nt._fields))
91
92        self.assertRaises(TypeError, Point._make, [11])                     # catch too few args
93        self.assertRaises(TypeError, Point._make, [11, 22, 33])             # catch too many args
94
95    @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
101    def test_name_fixer(self):
102        for spec, renamed in [
103            [('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
109        ]:
110            self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
111
112    def test_instance(self):
113        Point = namedtuple('Point', 'x y')
114        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)')
125        self.assertNotIn('__weakref__', dir(p))
126        self.assertEqual(p, Point._make([11, 22]))                          # test _make classmethod
127        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
130        self.assertEqual(vars(p), p._asdict())                              # verify that vars() works
131
132        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
139        # verify that field string can have commas
140        Point = namedtuple('Point', 'x, y')
141        p = Point(x=11, y=22)
142        self.assertEqual(repr(p), 'Point(x=11, y=22)')
143
144        # verify that fieldspec can be a non-string sequence
145        Point = namedtuple('Point', ('x', 'y'))
146        p = Point(x=11, y=22)
147        self.assertEqual(repr(p), 'Point(x=11, y=22)')
148
149    def test_tupleness(self):
150        Point = namedtuple('Point', 'x y')
151        p = Point(11, 22)
152
153        self.assertIsInstance(p, tuple)
154        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
168    def test_odd_sizes(self):
169        Zero = namedtuple('Zero', '')
170        self.assertEqual(Zero(), ())
171        self.assertEqual(Zero._make([]), ())
172        self.assertEqual(repr(Zero()), 'Zero()')
173        self.assertEqual(Zero()._asdict(), {})
174        self.assertEqual(Zero()._fields, ())
175
176        Dot = namedtuple('Dot', 'd')
177        self.assertEqual(Dot(1), (1,))
178        self.assertEqual(Dot._make([1]), (1,))
179        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',))
184
185        n = 5000
186        names = list(set(''.join([choice(string.ascii_letters)
187                                  for j in range(10)]) for i in range(n)))
188        n = len(names)
189        Big = namedtuple('Big', names)
190        b = Big(*range(n))
191        self.assertEqual(b, tuple(range(n)))
192        self.assertEqual(Big._make(range(n)), tuple(range(n)))
193        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))
205
206    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
223    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
261    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
266class 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
282    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))
303
304    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
335class TestOneTrickPonyABCs(ABCTestCase):
336
337    def test_Hashable(self):
338        # Check some non-hashables
339        non_samples = [list(), set(), dict()]
340        for x in non_samples:
341            self.assertNotIsInstance(x, Hashable)
342            self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
343        # 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:
351            self.assertIsInstance(x, Hashable)
352            self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
353        self.assertRaises(TypeError, Hashable)
354        # Check direct subclassing
355        class H(Hashable):
356            def __hash__(self):
357                return super(H, self).__hash__()
358            __eq__ = Hashable.__eq__ # Silence Py3k warning
359        self.assertEqual(hash(H()), 0)
360        self.assertFalse(issubclass(int, H))
361        self.validate_abstract_methods(Hashable, '__hash__')
362        self.validate_isinstance(Hashable, '__hash__')
363
364    def test_Iterable(self):
365        # Check some non-iterables
366        non_samples = [None, 42, 3.14, 1j]
367        for x in non_samples:
368            self.assertNotIsInstance(x, Iterable)
369            self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
370        # 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:
378            self.assertIsInstance(x, Iterable)
379            self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
380        # Check direct subclassing
381        class I(Iterable):
382            def __iter__(self):
383                return super(I, self).__iter__()
384        self.assertEqual(list(I()), [])
385        self.assertFalse(issubclass(str, I))
386        self.validate_abstract_methods(Iterable, '__iter__')
387        self.validate_isinstance(Iterable, '__iter__')
388
389    def test_Iterator(self):
390        non_samples = [None, 42, 3.14, 1j, "".encode('ascii'), "", (), [],
391            {}, set()]
392        for x in non_samples:
393            self.assertNotIsInstance(x, Iterator)
394            self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
395        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:
404            self.assertIsInstance(x, Iterator)
405            self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
406        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)
419
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:
426            self.assertNotIsInstance(x, Sized)
427            self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
428        samples = [str(),
429                   tuple(), list(), set(), frozenset(), dict(),
430                   dict().keys(), dict().items(), dict().values(),
431                   ]
432        for x in samples:
433            self.assertIsInstance(x, Sized)
434            self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
435        self.validate_abstract_methods(Sized, '__len__')
436        self.validate_isinstance(Sized, '__len__')
437
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:
444            self.assertNotIsInstance(x, Container)
445            self.assertFalse(issubclass(type(x), Container), repr(type(x)))
446        samples = [str(),
447                   tuple(), list(), set(), frozenset(), dict(),
448                   dict().keys(), dict().items(),
449                   ]
450        for x in samples:
451            self.assertIsInstance(x, Container)
452            self.assertTrue(issubclass(type(x), Container), repr(type(x)))
453        self.validate_abstract_methods(Container, '__contains__')
454        self.validate_isinstance(Container, '__contains__')
455
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:
463            self.assertNotIsInstance(x, Callable)
464            self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
465        samples = [lambda: None,
466                   type, int, object,
467                   len,
468                   list.append, [].append,
469                   ]
470        for x in samples:
471            self.assertIsInstance(x, Callable)
472            self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
473        self.validate_abstract_methods(Callable, '__call__')
474        self.validate_isinstance(Callable, '__call__')
475
476    def test_direct_subclassing(self):
477        for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
478            class C(B):
479                pass
480            self.assertTrue(issubclass(C, B))
481            self.assertFalse(issubclass(int, C))
482
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
488            self.assertFalse(issubclass(C, B), B.__name__)
489            B.register(C)
490            self.assertTrue(issubclass(C, B))
491
492class 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)
511
512class TestCollectionABCs(ABCTestCase):
513
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]:
520            self.assertIsInstance(sample(), Set)
521            self.assertTrue(issubclass(sample, Set))
522        self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
523        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())
531
532    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()
545        self.assertTrue(hash(a) == hash(b))
546
547    def test_MutableSet(self):
548        self.assertIsInstance(set(), MutableSet)
549        self.assertTrue(issubclass(set, MutableSet))
550        self.assertNotIsInstance(frozenset(), MutableSet)
551        self.assertFalse(issubclass(frozenset, MutableSet))
552        self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
553            'add', 'discard')
554
555    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
561    def test_issue_4920(self):
562        # MutableSet.pop() method did not work
563        class MySet(MutableSet):
564            __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)
587
588    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
603    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()
627
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)
721
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
727
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)
738
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
744
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)
755
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
761
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)
772
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
778
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
802
803    def test_Mapping(self):
804        for sample in [dict]:
805            self.assertIsInstance(sample(), Mapping)
806            self.assertTrue(issubclass(sample, Mapping))
807        self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
808            '__getitem__')
809        class MyMapping(Mapping):
810            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())
817
818    def test_MutableMapping(self):
819        for sample in [dict]:
820            self.assertIsInstance(sample(), MutableMapping)
821            self.assertTrue(issubclass(sample, MutableMapping))
822        self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
823            '__getitem__', '__setitem__', '__delitem__')
824
825    def test_Sequence(self):
826        for sample in [tuple, list, str]:
827            self.assertIsInstance(sample(), Sequence)
828            self.assertTrue(issubclass(sample, Sequence))
829        self.assertTrue(issubclass(basestring, Sequence))
830        self.assertIsInstance(range(10), Sequence)
831        self.assertTrue(issubclass(xrange, Sequence))
832        self.assertTrue(issubclass(str, Sequence))
833        self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
834            '__getitem__')
835
836    def test_MutableSequence(self):
837        for sample in [tuple, str]:
838            self.assertNotIsInstance(sample(), MutableSequence)
839            self.assertFalse(issubclass(sample, MutableSequence))
840        for sample in [list]:
841            self.assertIsInstance(sample(), MutableSequence)
842            self.assertTrue(issubclass(sample, MutableSequence))
843        self.assertFalse(issubclass(basestring, MutableSequence))
844        self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
845            '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
846
847class TestCounter(unittest.TestCase):
848
849    def test_basics(self):
850        c = Counter('abcaba')
851        self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
852        self.assertEqual(c, Counter(a=3, b=2, c=1))
853        self.assertIsInstance(c, dict)
854        self.assertIsInstance(c, Mapping)
855        self.assertTrue(issubclass(Counter, dict))
856        self.assertTrue(issubclass(Counter, Mapping))
857        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)
866        with test_support.check_py3k_warnings():
867            self.assertEqual(c.has_key('c'), True)
868            self.assertEqual(c.has_key('z'), False)
869        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))
874        self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
875        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
883        del c['c']          # make sure that del doesn't raise KeyError
884        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)
890        self.assertNotIn('f', c)
891        for i in range(3):
892            elem, cnt = c.popitem()
893            self.assertNotIn(elem, c)
894        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)
899        c.update(dict(a=5, b=3))
900        c.update(c=1)
901        c.update(Counter('a' * 50 + 'b' * 30))
902        c.update()          # test case with no args
903        c.__init__('a' * 500 + 'b' * 300)
904        c.__init__('cdc')
905        c.__init__()
906        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
912    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
934    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,
954                    Counter(words),
955                    ]):
956            msg = (i, dup, words)
957            self.assertTrue(dup is not words)
958            self.assertEqual(dup, words)
959            self.assertEqual(len(dup), len(words))
960            self.assertEqual(type(dup), type(words))
961
962    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
971    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
979    def test_invariant_for_the_in_operator(self):
980        c = Counter(a=10, b=-2, c=0)
981        for elem in c:
982            self.assertTrue(elem in c)
983            self.assertIn(elem, c)
984
985    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))
994            p.update(e=1, f=-1, g=0)
995            q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
996            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))),
1002            ]:
1003                result = counterop(p, q)
1004                for x in elements:
1005                    self.assertEqual(numberop(p[x], q[x]), result[x],
1006                                     (counterop, x, p, q))
1007                # verify that results exclude non-positive counts
1008                self.assertTrue(x>0 for x in result.values())
1009
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))
1023
1024    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
1035        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
1045
1046def test_main(verbose=None):
1047    NamedTupleDocs = doctest.DocTestSuite(module=collections)
1048    test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
1049                    TestCollectionABCs, TestCounter]
1050    test_support.run_unittest(*test_classes)
1051    test_support.run_doctest(collections, verbose)
1052
1053if __name__ == "__main__":
1054    test_main(verbose=True)
1055