Home | History | Annotate | Download | only in test
      1 import collections
      2 import copy
      3 import doctest
      4 import keyword
      5 import operator
      6 import pickle
      7 import cPickle
      8 from random import choice, randrange
      9 import re
     10 import string
     11 import sys
     12 from test import test_support
     13 import unittest
     14 
     15 from collections import namedtuple, Counter, OrderedDict
     16 from collections import Hashable, Iterable, Iterator
     17 from collections import Sized, Container, Callable
     18 from collections import Set, MutableSet
     19 from collections import Mapping, MutableMapping
     20 from collections import Sequence, MutableSequence
     21 
     22 # Silence deprecation warning
     23 sets = test_support.import_module('sets', deprecated=True)
     24 
     25 TestNT = namedtuple('TestNT', 'x y z')    # type used for pickle tests
     26 
     27 py273_named_tuple_pickle = '''\
     28 ccopy_reg
     29 _reconstructor
     30 p0
     31 (ctest.test_collections
     32 TestNT
     33 p1
     34 c__builtin__
     35 tuple
     36 p2
     37 (I10
     38 I20
     39 I30
     40 tp3
     41 tp4
     42 Rp5
     43 ccollections
     44 OrderedDict
     45 p6
     46 ((lp7
     47 (lp8
     48 S'x'
     49 p9
     50 aI10
     51 aa(lp10
     52 S'y'
     53 p11
     54 aI20
     55 aa(lp12
     56 S'z'
     57 p13
     58 aI30
     59 aatp14
     60 Rp15
     61 b.
     62 '''
     63 
     64 class 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 
    266 class 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 
    335 class 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 
    492 class 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 
    512 class 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 
    847 class 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 
   1046 def 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 
   1053 if __name__ == "__main__":
   1054     test_main(verbose=True)
   1055