1"""Unit tests for collections.py."""
2
3import collections
4import copy
5import doctest
6import inspect
7import operator
8import pickle
9from random import choice, randrange
10from itertools import product, chain, combinations
11import string
12import sys
13from test import support
14import types
15import unittest
16
17from collections import namedtuple, Counter, OrderedDict, _count_elements
18from collections import UserDict, UserString, UserList
19from collections import ChainMap
20from collections import deque
21from collections.abc import Awaitable, Coroutine
22from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator
23from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
24from collections.abc import Sized, Container, Callable, Collection
25from collections.abc import Set, MutableSet
26from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
27from collections.abc import Sequence, MutableSequence
28from collections.abc import ByteString
29
30
31class TestUserObjects(unittest.TestCase):
32    def _superset_test(self, a, b):
33        self.assertGreaterEqual(
34            set(dir(a)),
35            set(dir(b)),
36            '{a} should have all the methods of {b}'.format(
37                a=a.__name__,
38                b=b.__name__,
39            ),
40        )
41
42    def _copy_test(self, obj):
43        # Test internal copy
44        obj_copy = obj.copy()
45        self.assertIsNot(obj.data, obj_copy.data)
46        self.assertEqual(obj.data, obj_copy.data)
47
48        # Test copy.copy
49        obj.test = [1234]  # Make sure instance vars are also copied.
50        obj_copy = copy.copy(obj)
51        self.assertIsNot(obj.data, obj_copy.data)
52        self.assertEqual(obj.data, obj_copy.data)
53        self.assertIs(obj.test, obj_copy.test)
54
55    def test_str_protocol(self):
56        self._superset_test(UserString, str)
57
58    def test_list_protocol(self):
59        self._superset_test(UserList, list)
60
61    def test_dict_protocol(self):
62        self._superset_test(UserDict, dict)
63
64    def test_list_copy(self):
65        obj = UserList()
66        obj.append(123)
67        self._copy_test(obj)
68
69    def test_dict_copy(self):
70        obj = UserDict()
71        obj[123] = "abc"
72        self._copy_test(obj)
73
74
75################################################################################
76### ChainMap (helper class for configparser and the string module)
77################################################################################
78
79class TestChainMap(unittest.TestCase):
80
81    def test_basics(self):
82        c = ChainMap()
83        c['a'] = 1
84        c['b'] = 2
85        d = c.new_child()
86        d['b'] = 20
87        d['c'] = 30
88        self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}])  # check internal state
89        self.assertEqual(d.items(), dict(a=1, b=20, c=30).items())    # check items/iter/getitem
90        self.assertEqual(len(d), 3)                                   # check len
91        for key in 'abc':                                             # check contains
92            self.assertIn(key, d)
93        for k, v in dict(a=1, b=20, c=30, z=100).items():             # check get
94            self.assertEqual(d.get(k, 100), v)
95
96        del d['b']                                                    # unmask a value
97        self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}])          # check internal state
98        self.assertEqual(d.items(), dict(a=1, b=2, c=30).items())     # check items/iter/getitem
99        self.assertEqual(len(d), 3)                                   # check len
100        for key in 'abc':                                             # check contains
101            self.assertIn(key, d)
102        for k, v in dict(a=1, b=2, c=30, z=100).items():              # check get
103            self.assertEqual(d.get(k, 100), v)
104        self.assertIn(repr(d), [                                      # check repr
105            type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
106            type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
107        ])
108
109        for e in d.copy(), copy.copy(d):                               # check shallow copies
110            self.assertEqual(d, e)
111            self.assertEqual(d.maps, e.maps)
112            self.assertIsNot(d, e)
113            self.assertIsNot(d.maps[0], e.maps[0])
114            for m1, m2 in zip(d.maps[1:], e.maps[1:]):
115                self.assertIs(m1, m2)
116
117        # check deep copies
118        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
119            e = pickle.loads(pickle.dumps(d, proto))
120            self.assertEqual(d, e)
121            self.assertEqual(d.maps, e.maps)
122            self.assertIsNot(d, e)
123            for m1, m2 in zip(d.maps, e.maps):
124                self.assertIsNot(m1, m2, e)
125        for e in [copy.deepcopy(d),
126                  eval(repr(d))
127                ]:
128            self.assertEqual(d, e)
129            self.assertEqual(d.maps, e.maps)
130            self.assertIsNot(d, e)
131            for m1, m2 in zip(d.maps, e.maps):
132                self.assertIsNot(m1, m2, e)
133
134        f = d.new_child()
135        f['b'] = 5
136        self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
137        self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}])   # check parents
138        self.assertEqual(f['b'], 5)                                    # find first in chain
139        self.assertEqual(f.parents['b'], 2)                            # look beyond maps[0]
140
141    def test_ordering(self):
142        # Combined order matches a series of dict updates from last to first.
143        # This test relies on the ordering of the underlying dicts.
144
145        baseline = {'music': 'bach', 'art': 'rembrandt'}
146        adjustments = {'art': 'van gogh', 'opera': 'carmen'}
147
148        cm = ChainMap(adjustments, baseline)
149
150        combined = baseline.copy()
151        combined.update(adjustments)
152
153        self.assertEqual(list(combined.items()), list(cm.items()))
154
155    def test_constructor(self):
156        self.assertEqual(ChainMap().maps, [{}])                        # no-args --> one new dict
157        self.assertEqual(ChainMap({1:2}).maps, [{1:2}])                # 1 arg --> list
158
159    def test_bool(self):
160        self.assertFalse(ChainMap())
161        self.assertFalse(ChainMap({}, {}))
162        self.assertTrue(ChainMap({1:2}, {}))
163        self.assertTrue(ChainMap({}, {1:2}))
164
165    def test_missing(self):
166        class DefaultChainMap(ChainMap):
167            def __missing__(self, key):
168                return 999
169        d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
170        for k, v in dict(a=1, b=2, c=30, d=999).items():
171            self.assertEqual(d[k], v)                                  # check __getitem__ w/missing
172        for k, v in dict(a=1, b=2, c=30, d=77).items():
173            self.assertEqual(d.get(k, 77), v)                          # check get() w/ missing
174        for k, v in dict(a=True, b=True, c=True, d=False).items():
175            self.assertEqual(k in d, v)                                # check __contains__ w/missing
176        self.assertEqual(d.pop('a', 1001), 1, d)
177        self.assertEqual(d.pop('a', 1002), 1002)                       # check pop() w/missing
178        self.assertEqual(d.popitem(), ('b', 2))                        # check popitem() w/missing
179        with self.assertRaises(KeyError):
180            d.popitem()
181
182    def test_order_preservation(self):
183        d = ChainMap(
184                OrderedDict(j=0, h=88888),
185                OrderedDict(),
186                OrderedDict(i=9999, d=4444, c=3333),
187                OrderedDict(f=666, b=222, g=777, c=333, h=888),
188                OrderedDict(),
189                OrderedDict(e=55, b=22),
190                OrderedDict(a=1, b=2, c=3, d=4, e=5),
191                OrderedDict(),
192            )
193        self.assertEqual(''.join(d), 'abcdefghij')
194        self.assertEqual(list(d.items()),
195            [('a', 1), ('b', 222), ('c', 3333), ('d', 4444),
196             ('e', 55), ('f', 666), ('g', 777), ('h', 88888),
197             ('i', 9999), ('j', 0)])
198
199    def test_iter_not_calling_getitem_on_maps(self):
200        class DictWithGetItem(UserDict):
201            def __init__(self, *args, **kwds):
202                self.called = False
203                UserDict.__init__(self, *args, **kwds)
204            def __getitem__(self, item):
205                self.called = True
206                UserDict.__getitem__(self, item)
207
208        d = DictWithGetItem(a=1)
209        c = ChainMap(d)
210        d.called = False
211
212        set(c)  # iterate over chain map
213        self.assertFalse(d.called, '__getitem__ was called')
214
215    def test_dict_coercion(self):
216        d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
217        self.assertEqual(dict(d), dict(a=1, b=2, c=30))
218        self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
219
220    def test_new_child(self):
221        'Tests for changes for issue #16613.'
222        c = ChainMap()
223        c['a'] = 1
224        c['b'] = 2
225        m = {'b':20, 'c': 30}
226        d = c.new_child(m)
227        self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}])  # check internal state
228        self.assertIs(m, d.maps[0])
229
230        # Use a different map than a dict
231        class lowerdict(dict):
232            def __getitem__(self, key):
233                if isinstance(key, str):
234                    key = key.lower()
235                return dict.__getitem__(self, key)
236            def __contains__(self, key):
237                if isinstance(key, str):
238                    key = key.lower()
239                return dict.__contains__(self, key)
240
241        c = ChainMap()
242        c['a'] = 1
243        c['b'] = 2
244        m = lowerdict(b=20, c=30)
245        d = c.new_child(m)
246        self.assertIs(m, d.maps[0])
247        for key in 'abc':                                             # check contains
248            self.assertIn(key, d)
249        for k, v in dict(a=1, B=20, C=30, z=100).items():             # check get
250            self.assertEqual(d.get(k, 100), v)
251
252        c = ChainMap({'a': 1, 'b': 2})
253        d = c.new_child(b=20, c=30)
254        self.assertEqual(d.maps, [{'b': 20, 'c': 30}, {'a': 1, 'b': 2}])
255
256    def test_union_operators(self):
257        cm1 = ChainMap(dict(a=1, b=2), dict(c=3, d=4))
258        cm2 = ChainMap(dict(a=10, e=5), dict(b=20, d=4))
259        cm3 = cm1.copy()
260        d = dict(a=10, c=30)
261        pairs = [('c', 3), ('p',0)]
262
263        tmp = cm1 | cm2 # testing between chainmaps
264        self.assertEqual(tmp.maps, [cm1.maps[0] | dict(cm2), *cm1.maps[1:]])
265        cm1 |= cm2
266        self.assertEqual(tmp, cm1)
267
268        tmp = cm2 | d # testing between chainmap and mapping
269        self.assertEqual(tmp.maps, [cm2.maps[0] | d, *cm2.maps[1:]])
270        self.assertEqual((d | cm2).maps, [d | dict(cm2)])
271        cm2 |= d
272        self.assertEqual(tmp, cm2)
273
274        # testing behavior between chainmap and iterable key-value pairs
275        with self.assertRaises(TypeError):
276            cm3 | pairs
277        tmp = cm3.copy()
278        cm3 |= pairs
279        self.assertEqual(cm3.maps, [tmp.maps[0] | dict(pairs), *tmp.maps[1:]])
280
281        # testing proper return types for ChainMap and it's subclasses
282        class Subclass(ChainMap):
283            pass
284
285        class SubclassRor(ChainMap):
286            def __ror__(self, other):
287                return super().__ror__(other)
288
289        tmp = ChainMap() | ChainMap()
290        self.assertIs(type(tmp), ChainMap)
291        self.assertIs(type(tmp.maps[0]), dict)
292        tmp = ChainMap() | Subclass()
293        self.assertIs(type(tmp), ChainMap)
294        self.assertIs(type(tmp.maps[0]), dict)
295        tmp = Subclass() | ChainMap()
296        self.assertIs(type(tmp), Subclass)
297        self.assertIs(type(tmp.maps[0]), dict)
298        tmp = ChainMap() | SubclassRor()
299        self.assertIs(type(tmp), SubclassRor)
300        self.assertIs(type(tmp.maps[0]), dict)
301
302
303################################################################################
304### Named Tuples
305################################################################################
306
307TestNT = namedtuple('TestNT', 'x y z')    # type used for pickle tests
308
309class TestNamedTuple(unittest.TestCase):
310
311    def test_factory(self):
312        Point = namedtuple('Point', 'x y')
313        self.assertEqual(Point.__name__, 'Point')
314        self.assertEqual(Point.__slots__, ())
315        self.assertEqual(Point.__module__, __name__)
316        self.assertEqual(Point.__getitem__, tuple.__getitem__)
317        self.assertEqual(Point._fields, ('x', 'y'))
318
319        self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi')       # type has non-alpha char
320        self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi')      # type has keyword
321        self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi')       # type starts with digit
322
323        self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi')       # field with non-alpha char
324        self.assertRaises(ValueError, namedtuple, 'abc', 'abc class')      # field has keyword
325        self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi')      # field starts with digit
326        self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi')       # field with leading underscore
327        self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi')    # duplicate field
328
329        namedtuple('Point0', 'x1 y2')   # Verify that numbers are allowed in names
330        namedtuple('_', 'a b c')        # Test leading underscores in a typename
331
332        nt = namedtuple('nt', 'the quick brown fox')                       # check unicode input
333        self.assertNotIn("u'", repr(nt._fields))
334        nt = namedtuple('nt', ('the', 'quick'))                           # check unicode input
335        self.assertNotIn("u'", repr(nt._fields))
336
337        self.assertRaises(TypeError, Point._make, [11])                     # catch too few args
338        self.assertRaises(TypeError, Point._make, [11, 22, 33])             # catch too many args
339
340    def test_defaults(self):
341        Point = namedtuple('Point', 'x y', defaults=(10, 20))              # 2 defaults
342        self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
343        self.assertEqual(Point(1, 2), (1, 2))
344        self.assertEqual(Point(1), (1, 20))
345        self.assertEqual(Point(), (10, 20))
346
347        Point = namedtuple('Point', 'x y', defaults=(20,))                 # 1 default
348        self.assertEqual(Point._field_defaults, {'y': 20})
349        self.assertEqual(Point(1, 2), (1, 2))
350        self.assertEqual(Point(1), (1, 20))
351
352        Point = namedtuple('Point', 'x y', defaults=())                     # 0 defaults
353        self.assertEqual(Point._field_defaults, {})
354        self.assertEqual(Point(1, 2), (1, 2))
355        with self.assertRaises(TypeError):
356            Point(1)
357
358        with self.assertRaises(TypeError):                                  # catch too few args
359            Point()
360        with self.assertRaises(TypeError):                                  # catch too many args
361            Point(1, 2, 3)
362        with self.assertRaises(TypeError):                                  # too many defaults
363            Point = namedtuple('Point', 'x y', defaults=(10, 20, 30))
364        with self.assertRaises(TypeError):                                  # non-iterable defaults
365            Point = namedtuple('Point', 'x y', defaults=10)
366        with self.assertRaises(TypeError):                                  # another non-iterable default
367            Point = namedtuple('Point', 'x y', defaults=False)
368
369        Point = namedtuple('Point', 'x y', defaults=None)                   # default is None
370        self.assertEqual(Point._field_defaults, {})
371        self.assertIsNone(Point.__new__.__defaults__, None)
372        self.assertEqual(Point(10, 20), (10, 20))
373        with self.assertRaises(TypeError):                                  # catch too few args
374            Point(10)
375
376        Point = namedtuple('Point', 'x y', defaults=[10, 20])               # allow non-tuple iterable
377        self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
378        self.assertEqual(Point.__new__.__defaults__, (10, 20))
379        self.assertEqual(Point(1, 2), (1, 2))
380        self.assertEqual(Point(1), (1, 20))
381        self.assertEqual(Point(), (10, 20))
382
383        Point = namedtuple('Point', 'x y', defaults=iter([10, 20]))         # allow plain iterator
384        self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20})
385        self.assertEqual(Point.__new__.__defaults__, (10, 20))
386        self.assertEqual(Point(1, 2), (1, 2))
387        self.assertEqual(Point(1), (1, 20))
388        self.assertEqual(Point(), (10, 20))
389
390    def test_readonly(self):
391        Point = namedtuple('Point', 'x y')
392        p = Point(11, 22)
393        with self.assertRaises(AttributeError):
394            p.x = 33
395        with self.assertRaises(AttributeError):
396            del p.x
397        with self.assertRaises(TypeError):
398            p[0] = 33
399        with self.assertRaises(TypeError):
400            del p[0]
401        self.assertEqual(p.x, 11)
402        self.assertEqual(p[0], 11)
403
404    @unittest.skipIf(sys.flags.optimize >= 2,
405                     "Docstrings are omitted with -O2 and above")
406    def test_factory_doc_attr(self):
407        Point = namedtuple('Point', 'x y')
408        self.assertEqual(Point.__doc__, 'Point(x, y)')
409        Point.__doc__ = '2D point'
410        self.assertEqual(Point.__doc__, '2D point')
411
412    @unittest.skipIf(sys.flags.optimize >= 2,
413                     "Docstrings are omitted with -O2 and above")
414    def test_field_doc(self):
415        Point = namedtuple('Point', 'x y')
416        self.assertEqual(Point.x.__doc__, 'Alias for field number 0')
417        self.assertEqual(Point.y.__doc__, 'Alias for field number 1')
418        Point.x.__doc__ = 'docstring for Point.x'
419        self.assertEqual(Point.x.__doc__, 'docstring for Point.x')
420        # namedtuple can mutate doc of descriptors independently
421        Vector = namedtuple('Vector', 'x y')
422        self.assertEqual(Vector.x.__doc__, 'Alias for field number 0')
423        Vector.x.__doc__ = 'docstring for Vector.x'
424        self.assertEqual(Vector.x.__doc__, 'docstring for Vector.x')
425
426    @support.cpython_only
427    @unittest.skipIf(sys.flags.optimize >= 2,
428                     "Docstrings are omitted with -O2 and above")
429    def test_field_doc_reuse(self):
430        P = namedtuple('P', ['m', 'n'])
431        Q = namedtuple('Q', ['o', 'p'])
432        self.assertIs(P.m.__doc__, Q.o.__doc__)
433        self.assertIs(P.n.__doc__, Q.p.__doc__)
434
435    @support.cpython_only
436    def test_field_repr(self):
437        Point = namedtuple('Point', 'x y')
438        self.assertEqual(repr(Point.x), "_tuplegetter(0, 'Alias for field number 0')")
439        self.assertEqual(repr(Point.y), "_tuplegetter(1, 'Alias for field number 1')")
440
441        Point.x.__doc__ = 'The x-coordinate'
442        Point.y.__doc__ = 'The y-coordinate'
443
444        self.assertEqual(repr(Point.x), "_tuplegetter(0, 'The x-coordinate')")
445        self.assertEqual(repr(Point.y), "_tuplegetter(1, 'The y-coordinate')")
446
447    def test_name_fixer(self):
448        for spec, renamed in [
449            [('efg', 'g%hi'),  ('efg', '_1')],                              # field with non-alpha char
450            [('abc', 'class'), ('abc', '_1')],                              # field has keyword
451            [('8efg', '9ghi'), ('_0', '_1')],                               # field starts with digit
452            [('abc', '_efg'), ('abc', '_1')],                               # field with leading underscore
453            [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')],    # duplicate field
454            [('abc', '', 'x'), ('abc', '_1', 'x')],                         # fieldname is a space
455        ]:
456            self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
457
458    def test_module_parameter(self):
459        NT = namedtuple('NT', ['x', 'y'], module=collections)
460        self.assertEqual(NT.__module__, collections)
461
462    def test_instance(self):
463        Point = namedtuple('Point', 'x y')
464        p = Point(11, 22)
465        self.assertEqual(p, Point(x=11, y=22))
466        self.assertEqual(p, Point(11, y=22))
467        self.assertEqual(p, Point(y=22, x=11))
468        self.assertEqual(p, Point(*(11, 22)))
469        self.assertEqual(p, Point(**dict(x=11, y=22)))
470        self.assertRaises(TypeError, Point, 1)          # too few args
471        self.assertRaises(TypeError, Point, 1, 2, 3)    # too many args
472        with self.assertRaises(TypeError):              # wrong keyword argument
473            Point(XXX=1, y=2)
474        with self.assertRaises(TypeError):              # missing keyword argument
475            Point(x=1)
476        self.assertEqual(repr(p), 'Point(x=11, y=22)')
477        self.assertNotIn('__weakref__', dir(p))
478        self.assertEqual(p, Point._make([11, 22]))      # test _make classmethod
479        self.assertEqual(p._fields, ('x', 'y'))         # test _fields attribute
480        self.assertEqual(p._replace(x=1), (1, 22))      # test _replace method
481        self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
482
483        try:
484            p._replace(x=1, error=2)
485        except ValueError:
486            pass
487        else:
488            self._fail('Did not detect an incorrect fieldname')
489
490        # verify that field string can have commas
491        Point = namedtuple('Point', 'x, y')
492        p = Point(x=11, y=22)
493        self.assertEqual(repr(p), 'Point(x=11, y=22)')
494
495        # verify that fieldspec can be a non-string sequence
496        Point = namedtuple('Point', ('x', 'y'))
497        p = Point(x=11, y=22)
498        self.assertEqual(repr(p), 'Point(x=11, y=22)')
499
500    def test_tupleness(self):
501        Point = namedtuple('Point', 'x y')
502        p = Point(11, 22)
503
504        self.assertIsInstance(p, tuple)
505        self.assertEqual(p, (11, 22))                                       # matches a real tuple
506        self.assertEqual(tuple(p), (11, 22))                                # coercible to a real tuple
507        self.assertEqual(list(p), [11, 22])                                 # coercible to a list
508        self.assertEqual(max(p), 22)                                        # iterable
509        self.assertEqual(max(*p), 22)                                       # star-able
510        x, y = p
511        self.assertEqual(p, (x, y))                                         # unpacks like a tuple
512        self.assertEqual((p[0], p[1]), (11, 22))                            # indexable like a tuple
513        with self.assertRaises(IndexError):
514            p[3]
515        self.assertEqual(p[-1], 22)
516        self.assertEqual(hash(p), hash((11, 22)))
517
518        self.assertEqual(p.x, x)
519        self.assertEqual(p.y, y)
520        with self.assertRaises(AttributeError):
521            p.z
522
523    def test_odd_sizes(self):
524        Zero = namedtuple('Zero', '')
525        self.assertEqual(Zero(), ())
526        self.assertEqual(Zero._make([]), ())
527        self.assertEqual(repr(Zero()), 'Zero()')
528        self.assertEqual(Zero()._asdict(), {})
529        self.assertEqual(Zero()._fields, ())
530
531        Dot = namedtuple('Dot', 'd')
532        self.assertEqual(Dot(1), (1,))
533        self.assertEqual(Dot._make([1]), (1,))
534        self.assertEqual(Dot(1).d, 1)
535        self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
536        self.assertEqual(Dot(1)._asdict(), {'d':1})
537        self.assertEqual(Dot(1)._replace(d=999), (999,))
538        self.assertEqual(Dot(1)._fields, ('d',))
539
540        n = 5000
541        names = list(set(''.join([choice(string.ascii_letters)
542                                  for j in range(10)]) for i in range(n)))
543        n = len(names)
544        Big = namedtuple('Big', names)
545        b = Big(*range(n))
546        self.assertEqual(b, tuple(range(n)))
547        self.assertEqual(Big._make(range(n)), tuple(range(n)))
548        for pos, name in enumerate(names):
549            self.assertEqual(getattr(b, name), pos)
550        repr(b)                                 # make sure repr() doesn't blow-up
551        d = b._asdict()
552        d_expected = dict(zip(names, range(n)))
553        self.assertEqual(d, d_expected)
554        b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
555        b2_expected = list(range(n))
556        b2_expected[1] = 999
557        b2_expected[-5] = 42
558        self.assertEqual(b2, tuple(b2_expected))
559        self.assertEqual(b._fields, tuple(names))
560
561    def test_pickle(self):
562        p = TestNT(x=10, y=20, z=30)
563        for module in (pickle,):
564            loads = getattr(module, 'loads')
565            dumps = getattr(module, 'dumps')
566            for protocol in range(-1, module.HIGHEST_PROTOCOL + 1):
567                q = loads(dumps(p, protocol))
568                self.assertEqual(p, q)
569                self.assertEqual(p._fields, q._fields)
570                self.assertNotIn(b'OrderedDict', dumps(p, protocol))
571
572    def test_copy(self):
573        p = TestNT(x=10, y=20, z=30)
574        for copier in copy.copy, copy.deepcopy:
575            q = copier(p)
576            self.assertEqual(p, q)
577            self.assertEqual(p._fields, q._fields)
578
579    def test_name_conflicts(self):
580        # Some names like "self", "cls", "tuple", "itemgetter", and "property"
581        # failed when used as field names.  Test to make sure these now work.
582        T = namedtuple('T', 'itemgetter property self cls tuple')
583        t = T(1, 2, 3, 4, 5)
584        self.assertEqual(t, (1,2,3,4,5))
585        newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
586        self.assertEqual(newt, (10,20,30,40,50))
587
588       # Broader test of all interesting names taken from the code, old
589       # template, and an example
590        words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create',
591        'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper',
592        'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note',
593        'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError',
594        'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add',
595        'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments',
596        'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot',
597        'class_namespace', 'classmethod', 'cls', 'collections', 'convert',
598        'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict',
599        'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect',
600        'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f',
601        'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame',
602        'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater',
603        'has', 'help', 'identifiers', 'index', 'indexable', 'instance',
604        'instantiate', 'interning', 'introspection', 'isidentifier',
605        'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords',
606        'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata',
607        'method', 'methods', 'module', 'module_name', 'must', 'name', 'named',
608        'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new',
609        'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option',
610        'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional',
611        'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr',
612        'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen',
613        'self', 'sequence', 'set', 'side', 'specified', 'split', 'start',
614        'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys',
615        'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new',
616        'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use',
617        'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where',
618        'which', 'work', 'x', 'y', 'z', 'zip'}
619        T = namedtuple('T', words)
620        # test __new__
621        values = tuple(range(len(words)))
622        t = T(*values)
623        self.assertEqual(t, values)
624        t = T(**dict(zip(T._fields, values)))
625        self.assertEqual(t, values)
626        # test _make
627        t = T._make(values)
628        self.assertEqual(t, values)
629        # exercise __repr__
630        repr(t)
631        # test _asdict
632        self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
633        # test _replace
634        t = T._make(values)
635        newvalues = tuple(v*10 for v in values)
636        newt = t._replace(**dict(zip(T._fields, newvalues)))
637        self.assertEqual(newt, newvalues)
638        # test _fields
639        self.assertEqual(T._fields, tuple(words))
640        # test __getnewargs__
641        self.assertEqual(t.__getnewargs__(), values)
642
643    def test_repr(self):
644        A = namedtuple('A', 'x')
645        self.assertEqual(repr(A(1)), 'A(x=1)')
646        # repr should show the name of the subclass
647        class B(A):
648            pass
649        self.assertEqual(repr(B(1)), 'B(x=1)')
650
651    def test_keyword_only_arguments(self):
652        # See issue 25628
653        with self.assertRaises(TypeError):
654            NT = namedtuple('NT', ['x', 'y'], True)
655
656        NT = namedtuple('NT', ['abc', 'def'], rename=True)
657        self.assertEqual(NT._fields, ('abc', '_1'))
658        with self.assertRaises(TypeError):
659            NT = namedtuple('NT', ['abc', 'def'], False, True)
660
661    def test_namedtuple_subclass_issue_24931(self):
662        class Point(namedtuple('_Point', ['x', 'y'])):
663            pass
664
665        a = Point(3, 4)
666        self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)]))
667
668        a.w = 5
669        self.assertEqual(a.__dict__, {'w': 5})
670
671    @support.cpython_only
672    def test_field_descriptor(self):
673        Point = namedtuple('Point', 'x y')
674        p = Point(11, 22)
675        self.assertTrue(inspect.isdatadescriptor(Point.x))
676        self.assertEqual(Point.x.__get__(p), 11)
677        self.assertRaises(AttributeError, Point.x.__set__, p, 33)
678        self.assertRaises(AttributeError, Point.x.__delete__, p)
679
680        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
681            with self.subTest(proto=proto):
682                class NewPoint(tuple):
683                    x = pickle.loads(pickle.dumps(Point.x, proto))
684                    y = pickle.loads(pickle.dumps(Point.y, proto))
685
686                np = NewPoint([1, 2])
687
688                self.assertEqual(np.x, 1)
689                self.assertEqual(np.y, 2)
690
691    def test_new_builtins_issue_43102(self):
692        obj = namedtuple('C', ())
693        new_func = obj.__new__
694        self.assertEqual(new_func.__globals__['__builtins__'], {})
695        self.assertEqual(new_func.__builtins__, {})
696
697    def test_match_args(self):
698        Point = namedtuple('Point', 'x y')
699        self.assertEqual(Point.__match_args__, ('x', 'y'))
700
701    def test_non_generic_subscript(self):
702        # For backward compatibility, subscription works
703        # on arbitrary named tuple types.
704        Group = collections.namedtuple('Group', 'key group')
705        A = Group[int, list[int]]
706        self.assertEqual(A.__origin__, Group)
707        self.assertEqual(A.__parameters__, ())
708        self.assertEqual(A.__args__, (int, list[int]))
709        a = A(1, [2])
710        self.assertIs(type(a), Group)
711        self.assertEqual(a, (1, [2]))
712
713
714################################################################################
715### Abstract Base Classes
716################################################################################
717
718class ABCTestCase(unittest.TestCase):
719
720    def validate_abstract_methods(self, abc, *names):
721        methodstubs = dict.fromkeys(names, lambda s, *args: 0)
722
723        # everything should work will all required methods are present
724        C = type('C', (abc,), methodstubs)
725        C()
726
727        # instantiation should fail if a required method is missing
728        for name in names:
729            stubs = methodstubs.copy()
730            del stubs[name]
731            C = type('C', (abc,), stubs)
732            self.assertRaises(TypeError, C, name)
733
734    def validate_isinstance(self, abc, name):
735        stub = lambda s, *args: 0
736
737        C = type('C', (object,), {'__hash__': None})
738        setattr(C, name, stub)
739        self.assertIsInstance(C(), abc)
740        self.assertTrue(issubclass(C, abc))
741
742        C = type('C', (object,), {'__hash__': None})
743        self.assertNotIsInstance(C(), abc)
744        self.assertFalse(issubclass(C, abc))
745
746    def validate_comparison(self, instance):
747        ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
748        operators = {}
749        for op in ops:
750            name = '__' + op + '__'
751            operators[name] = getattr(operator, name)
752
753        class Other:
754            def __init__(self):
755                self.right_side = False
756            def __eq__(self, other):
757                self.right_side = True
758                return True
759            __lt__ = __eq__
760            __gt__ = __eq__
761            __le__ = __eq__
762            __ge__ = __eq__
763            __ne__ = __eq__
764            __ror__ = __eq__
765            __rand__ = __eq__
766            __rxor__ = __eq__
767            __rsub__ = __eq__
768
769        for name, op in operators.items():
770            if not hasattr(instance, name):
771                continue
772            other = Other()
773            op(instance, other)
774            self.assertTrue(other.right_side,'Right side not called for %s.%s'
775                            % (type(instance), name))
776
777def _test_gen():
778    yield
779
780class TestOneTrickPonyABCs(ABCTestCase):
781
782    def test_Awaitable(self):
783        def gen():
784            yield
785
786        @types.coroutine
787        def coro():
788            yield
789
790        async def new_coro():
791            pass
792
793        class Bar:
794            def __await__(self):
795                yield
796
797        class MinimalCoro(Coroutine):
798            def send(self, value):
799                return value
800            def throw(self, typ, val=None, tb=None):
801                super().throw(typ, val, tb)
802            def __await__(self):
803                yield
804
805        self.validate_abstract_methods(Awaitable, '__await__')
806
807        non_samples = [None, int(), gen(), object()]
808        for x in non_samples:
809            self.assertNotIsInstance(x, Awaitable)
810            self.assertFalse(issubclass(type(x), Awaitable), repr(type(x)))
811
812        samples = [Bar(), MinimalCoro()]
813        for x in samples:
814            self.assertIsInstance(x, Awaitable)
815            self.assertTrue(issubclass(type(x), Awaitable))
816
817        c = coro()
818        # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
819        # flag don't have '__await__' method, hence can't be instances
820        # of Awaitable. Use inspect.isawaitable to detect them.
821        self.assertNotIsInstance(c, Awaitable)
822
823        c = new_coro()
824        self.assertIsInstance(c, Awaitable)
825        c.close() # avoid RuntimeWarning that coro() was not awaited
826
827        class CoroLike: pass
828        Coroutine.register(CoroLike)
829        self.assertTrue(isinstance(CoroLike(), Awaitable))
830        self.assertTrue(issubclass(CoroLike, Awaitable))
831        CoroLike = None
832        support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache
833
834    def test_Coroutine(self):
835        def gen():
836            yield
837
838        @types.coroutine
839        def coro():
840            yield
841
842        async def new_coro():
843            pass
844
845        class Bar:
846            def __await__(self):
847                yield
848
849        class MinimalCoro(Coroutine):
850            def send(self, value):
851                return value
852            def throw(self, typ, val=None, tb=None):
853                super().throw(typ, val, tb)
854            def __await__(self):
855                yield
856
857        self.validate_abstract_methods(Coroutine, '__await__', 'send', 'throw')
858
859        non_samples = [None, int(), gen(), object(), Bar()]
860        for x in non_samples:
861            self.assertNotIsInstance(x, Coroutine)
862            self.assertFalse(issubclass(type(x), Coroutine), repr(type(x)))
863
864        samples = [MinimalCoro()]
865        for x in samples:
866            self.assertIsInstance(x, Awaitable)
867            self.assertTrue(issubclass(type(x), Awaitable))
868
869        c = coro()
870        # Iterable coroutines (generators with CO_ITERABLE_COROUTINE
871        # flag don't have '__await__' method, hence can't be instances
872        # of Coroutine. Use inspect.isawaitable to detect them.
873        self.assertNotIsInstance(c, Coroutine)
874
875        c = new_coro()
876        self.assertIsInstance(c, Coroutine)
877        c.close() # avoid RuntimeWarning that coro() was not awaited
878
879        class CoroLike:
880            def send(self, value):
881                pass
882            def throw(self, typ, val=None, tb=None):
883                pass
884            def close(self):
885                pass
886            def __await__(self):
887                pass
888        self.assertTrue(isinstance(CoroLike(), Coroutine))
889        self.assertTrue(issubclass(CoroLike, Coroutine))
890
891        class CoroLike:
892            def send(self, value):
893                pass
894            def close(self):
895                pass
896            def __await__(self):
897                pass
898        self.assertFalse(isinstance(CoroLike(), Coroutine))
899        self.assertFalse(issubclass(CoroLike, Coroutine))
900
901    def test_Hashable(self):
902        # Check some non-hashables
903        non_samples = [bytearray(), list(), set(), dict()]
904        for x in non_samples:
905            self.assertNotIsInstance(x, Hashable)
906            self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
907        # Check some hashables
908        samples = [None,
909                   int(), float(), complex(),
910                   str(),
911                   tuple(), frozenset(),
912                   int, list, object, type, bytes()
913                   ]
914        for x in samples:
915            self.assertIsInstance(x, Hashable)
916            self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
917        self.assertRaises(TypeError, Hashable)
918        # Check direct subclassing
919        class H(Hashable):
920            def __hash__(self):
921                return super().__hash__()
922        self.assertEqual(hash(H()), 0)
923        self.assertFalse(issubclass(int, H))
924        self.validate_abstract_methods(Hashable, '__hash__')
925        self.validate_isinstance(Hashable, '__hash__')
926
927    def test_AsyncIterable(self):
928        class AI:
929            def __aiter__(self):
930                return self
931        self.assertTrue(isinstance(AI(), AsyncIterable))
932        self.assertTrue(issubclass(AI, AsyncIterable))
933        # Check some non-iterables
934        non_samples = [None, object, []]
935        for x in non_samples:
936            self.assertNotIsInstance(x, AsyncIterable)
937            self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x)))
938        self.validate_abstract_methods(AsyncIterable, '__aiter__')
939        self.validate_isinstance(AsyncIterable, '__aiter__')
940
941    def test_AsyncIterator(self):
942        class AI:
943            def __aiter__(self):
944                return self
945            async def __anext__(self):
946                raise StopAsyncIteration
947        self.assertTrue(isinstance(AI(), AsyncIterator))
948        self.assertTrue(issubclass(AI, AsyncIterator))
949        non_samples = [None, object, []]
950        # Check some non-iterables
951        for x in non_samples:
952            self.assertNotIsInstance(x, AsyncIterator)
953            self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x)))
954        # Similarly to regular iterators (see issue 10565)
955        class AnextOnly:
956            async def __anext__(self):
957                raise StopAsyncIteration
958        self.assertNotIsInstance(AnextOnly(), AsyncIterator)
959        self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__')
960
961    def test_Iterable(self):
962        # Check some non-iterables
963        non_samples = [None, 42, 3.14, 1j]
964        for x in non_samples:
965            self.assertNotIsInstance(x, Iterable)
966            self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
967        # Check some iterables
968        samples = [bytes(), str(),
969                   tuple(), list(), set(), frozenset(), dict(),
970                   dict().keys(), dict().items(), dict().values(),
971                   _test_gen(),
972                   (x for x in []),
973                   ]
974        for x in samples:
975            self.assertIsInstance(x, Iterable)
976            self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
977        # Check direct subclassing
978        class I(Iterable):
979            def __iter__(self):
980                return super().__iter__()
981        self.assertEqual(list(I()), [])
982        self.assertFalse(issubclass(str, I))
983        self.validate_abstract_methods(Iterable, '__iter__')
984        self.validate_isinstance(Iterable, '__iter__')
985        # Check None blocking
986        class It:
987            def __iter__(self): return iter([])
988        class ItBlocked(It):
989            __iter__ = None
990        self.assertTrue(issubclass(It, Iterable))
991        self.assertTrue(isinstance(It(), Iterable))
992        self.assertFalse(issubclass(ItBlocked, Iterable))
993        self.assertFalse(isinstance(ItBlocked(), Iterable))
994
995    def test_Reversible(self):
996        # Check some non-reversibles
997        non_samples = [None, 42, 3.14, 1j, set(), frozenset()]
998        for x in non_samples:
999            self.assertNotIsInstance(x, Reversible)
1000            self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
1001        # Check some non-reversible iterables
1002        non_reversibles = [_test_gen(), (x for x in []), iter([]), reversed([])]
1003        for x in non_reversibles:
1004            self.assertNotIsInstance(x, Reversible)
1005            self.assertFalse(issubclass(type(x), Reversible), repr(type(x)))
1006        # Check some reversible iterables
1007        samples = [bytes(), str(), tuple(), list(), OrderedDict(),
1008                   OrderedDict().keys(), OrderedDict().items(),
1009                   OrderedDict().values(), Counter(), Counter().keys(),
1010                   Counter().items(), Counter().values(), dict(),
1011                   dict().keys(), dict().items(), dict().values()]
1012        for x in samples:
1013            self.assertIsInstance(x, Reversible)
1014            self.assertTrue(issubclass(type(x), Reversible), repr(type(x)))
1015        # Check also Mapping, MutableMapping, and Sequence
1016        self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence))
1017        self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping))
1018        self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping))
1019        # Check direct subclassing
1020        class R(Reversible):
1021            def __iter__(self):
1022                return iter(list())
1023            def __reversed__(self):
1024                return iter(list())
1025        self.assertEqual(list(reversed(R())), [])
1026        self.assertFalse(issubclass(float, R))
1027        self.validate_abstract_methods(Reversible, '__reversed__', '__iter__')
1028        # Check reversible non-iterable (which is not Reversible)
1029        class RevNoIter:
1030            def __reversed__(self): return reversed([])
1031        class RevPlusIter(RevNoIter):
1032            def __iter__(self): return iter([])
1033        self.assertFalse(issubclass(RevNoIter, Reversible))
1034        self.assertFalse(isinstance(RevNoIter(), Reversible))
1035        self.assertTrue(issubclass(RevPlusIter, Reversible))
1036        self.assertTrue(isinstance(RevPlusIter(), Reversible))
1037        # Check None blocking
1038        class Rev:
1039            def __iter__(self): return iter([])
1040            def __reversed__(self): return reversed([])
1041        class RevItBlocked(Rev):
1042            __iter__ = None
1043        class RevRevBlocked(Rev):
1044            __reversed__ = None
1045        self.assertTrue(issubclass(Rev, Reversible))
1046        self.assertTrue(isinstance(Rev(), Reversible))
1047        self.assertFalse(issubclass(RevItBlocked, Reversible))
1048        self.assertFalse(isinstance(RevItBlocked(), Reversible))
1049        self.assertFalse(issubclass(RevRevBlocked, Reversible))
1050        self.assertFalse(isinstance(RevRevBlocked(), Reversible))
1051
1052    def test_Collection(self):
1053        # Check some non-collections
1054        non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
1055        for x in non_collections:
1056            self.assertNotIsInstance(x, Collection)
1057            self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
1058        # Check some non-collection iterables
1059        non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
1060                             (x for x in [])]
1061        for x in non_col_iterables:
1062            self.assertNotIsInstance(x, Collection)
1063            self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
1064        # Check some collections
1065        samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
1066                   list(), dict().keys(), dict().items(), dict().values()]
1067        for x in samples:
1068            self.assertIsInstance(x, Collection)
1069            self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
1070        # Check also Mapping, MutableMapping, etc.
1071        self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
1072        self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
1073        self.assertTrue(issubclass(MutableMapping, Collection),
1074                                    repr(MutableMapping))
1075        self.assertTrue(issubclass(Set, Collection), repr(Set))
1076        self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
1077        self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
1078        # Check direct subclassing
1079        class Col(Collection):
1080            def __iter__(self):
1081                return iter(list())
1082            def __len__(self):
1083                return 0
1084            def __contains__(self, item):
1085                return False
1086        class DerCol(Col): pass
1087        self.assertEqual(list(iter(Col())), [])
1088        self.assertFalse(issubclass(list, Col))
1089        self.assertFalse(issubclass(set, Col))
1090        self.assertFalse(issubclass(float, Col))
1091        self.assertEqual(list(iter(DerCol())), [])
1092        self.assertFalse(issubclass(list, DerCol))
1093        self.assertFalse(issubclass(set, DerCol))
1094        self.assertFalse(issubclass(float, DerCol))
1095        self.validate_abstract_methods(Collection, '__len__', '__iter__',
1096                                                   '__contains__')
1097        # Check sized container non-iterable (which is not Collection) etc.
1098        class ColNoIter:
1099            def __len__(self): return 0
1100            def __contains__(self, item): return False
1101        class ColNoSize:
1102            def __iter__(self): return iter([])
1103            def __contains__(self, item): return False
1104        class ColNoCont:
1105            def __iter__(self): return iter([])
1106            def __len__(self): return 0
1107        self.assertFalse(issubclass(ColNoIter, Collection))
1108        self.assertFalse(isinstance(ColNoIter(), Collection))
1109        self.assertFalse(issubclass(ColNoSize, Collection))
1110        self.assertFalse(isinstance(ColNoSize(), Collection))
1111        self.assertFalse(issubclass(ColNoCont, Collection))
1112        self.assertFalse(isinstance(ColNoCont(), Collection))
1113        # Check None blocking
1114        class SizeBlock:
1115            def __iter__(self): return iter([])
1116            def __contains__(self): return False
1117            __len__ = None
1118        class IterBlock:
1119            def __len__(self): return 0
1120            def __contains__(self): return True
1121            __iter__ = None
1122        self.assertFalse(issubclass(SizeBlock, Collection))
1123        self.assertFalse(isinstance(SizeBlock(), Collection))
1124        self.assertFalse(issubclass(IterBlock, Collection))
1125        self.assertFalse(isinstance(IterBlock(), Collection))
1126        # Check None blocking in subclass
1127        class ColImpl:
1128            def __iter__(self):
1129                return iter(list())
1130            def __len__(self):
1131                return 0
1132            def __contains__(self, item):
1133                return False
1134        class NonCol(ColImpl):
1135            __contains__ = None
1136        self.assertFalse(issubclass(NonCol, Collection))
1137        self.assertFalse(isinstance(NonCol(), Collection))
1138
1139
1140    def test_Iterator(self):
1141        non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
1142        for x in non_samples:
1143            self.assertNotIsInstance(x, Iterator)
1144            self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
1145        samples = [iter(bytes()), iter(str()),
1146                   iter(tuple()), iter(list()), iter(dict()),
1147                   iter(set()), iter(frozenset()),
1148                   iter(dict().keys()), iter(dict().items()),
1149                   iter(dict().values()),
1150                   _test_gen(),
1151                   (x for x in []),
1152                   ]
1153        for x in samples:
1154            self.assertIsInstance(x, Iterator)
1155            self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
1156        self.validate_abstract_methods(Iterator, '__next__', '__iter__')
1157
1158        # Issue 10565
1159        class NextOnly:
1160            def __next__(self):
1161                yield 1
1162                return
1163        self.assertNotIsInstance(NextOnly(), Iterator)
1164
1165    def test_Generator(self):
1166        class NonGen1:
1167            def __iter__(self): return self
1168            def __next__(self): return None
1169            def close(self): pass
1170            def throw(self, typ, val=None, tb=None): pass
1171
1172        class NonGen2:
1173            def __iter__(self): return self
1174            def __next__(self): return None
1175            def close(self): pass
1176            def send(self, value): return value
1177
1178        class NonGen3:
1179            def close(self): pass
1180            def send(self, value): return value
1181            def throw(self, typ, val=None, tb=None): pass
1182
1183        non_samples = [
1184            None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1185            iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()]
1186        for x in non_samples:
1187            self.assertNotIsInstance(x, Generator)
1188            self.assertFalse(issubclass(type(x), Generator), repr(type(x)))
1189
1190        class Gen:
1191            def __iter__(self): return self
1192            def __next__(self): return None
1193            def close(self): pass
1194            def send(self, value): return value
1195            def throw(self, typ, val=None, tb=None): pass
1196
1197        class MinimalGen(Generator):
1198            def send(self, value):
1199                return value
1200            def throw(self, typ, val=None, tb=None):
1201                super().throw(typ, val, tb)
1202
1203        def gen():
1204            yield 1
1205
1206        samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()]
1207        for x in samples:
1208            self.assertIsInstance(x, Iterator)
1209            self.assertIsInstance(x, Generator)
1210            self.assertTrue(issubclass(type(x), Generator), repr(type(x)))
1211        self.validate_abstract_methods(Generator, 'send', 'throw')
1212
1213        # mixin tests
1214        mgen = MinimalGen()
1215        self.assertIs(mgen, iter(mgen))
1216        self.assertIs(mgen.send(None), next(mgen))
1217        self.assertEqual(2, mgen.send(2))
1218        self.assertIsNone(mgen.close())
1219        self.assertRaises(ValueError, mgen.throw, ValueError)
1220        self.assertRaisesRegex(ValueError, "^huhu$",
1221                               mgen.throw, ValueError, ValueError("huhu"))
1222        self.assertRaises(StopIteration, mgen.throw, StopIteration())
1223
1224        class FailOnClose(Generator):
1225            def send(self, value): return value
1226            def throw(self, *args): raise ValueError
1227
1228        self.assertRaises(ValueError, FailOnClose().close)
1229
1230        class IgnoreGeneratorExit(Generator):
1231            def send(self, value): return value
1232            def throw(self, *args): pass
1233
1234        self.assertRaises(RuntimeError, IgnoreGeneratorExit().close)
1235
1236    def test_AsyncGenerator(self):
1237        class NonAGen1:
1238            def __aiter__(self): return self
1239            def __anext__(self): return None
1240            def aclose(self): pass
1241            def athrow(self, typ, val=None, tb=None): pass
1242
1243        class NonAGen2:
1244            def __aiter__(self): return self
1245            def __anext__(self): return None
1246            def aclose(self): pass
1247            def asend(self, value): return value
1248
1249        class NonAGen3:
1250            def aclose(self): pass
1251            def asend(self, value): return value
1252            def athrow(self, typ, val=None, tb=None): pass
1253
1254        non_samples = [
1255            None, 42, 3.14, 1j, b"", "", (), [], {}, set(),
1256            iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()]
1257        for x in non_samples:
1258            self.assertNotIsInstance(x, AsyncGenerator)
1259            self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x)))
1260
1261        class Gen:
1262            def __aiter__(self): return self
1263            async def __anext__(self): return None
1264            async def aclose(self): pass
1265            async def asend(self, value): return value
1266            async def athrow(self, typ, val=None, tb=None): pass
1267
1268        class MinimalAGen(AsyncGenerator):
1269            async def asend(self, value):
1270                return value
1271            async def athrow(self, typ, val=None, tb=None):
1272                await super().athrow(typ, val, tb)
1273
1274        async def gen():
1275            yield 1
1276
1277        samples = [gen(), Gen(), MinimalAGen()]
1278        for x in samples:
1279            self.assertIsInstance(x, AsyncIterator)
1280            self.assertIsInstance(x, AsyncGenerator)
1281            self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x)))
1282        self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow')
1283
1284        def run_async(coro):
1285            result = None
1286            while True:
1287                try:
1288                    coro.send(None)
1289                except StopIteration as ex:
1290                    result = ex.args[0] if ex.args else None
1291                    break
1292            return result
1293
1294        # mixin tests
1295        mgen = MinimalAGen()
1296        self.assertIs(mgen, mgen.__aiter__())
1297        self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__()))
1298        self.assertEqual(2, run_async(mgen.asend(2)))
1299        self.assertIsNone(run_async(mgen.aclose()))
1300        with self.assertRaises(ValueError):
1301            run_async(mgen.athrow(ValueError))
1302
1303        class FailOnClose(AsyncGenerator):
1304            async def asend(self, value): return value
1305            async def athrow(self, *args): raise ValueError
1306
1307        with self.assertRaises(ValueError):
1308            run_async(FailOnClose().aclose())
1309
1310        class IgnoreGeneratorExit(AsyncGenerator):
1311            async def asend(self, value): return value
1312            async def athrow(self, *args): pass
1313
1314        with self.assertRaises(RuntimeError):
1315            run_async(IgnoreGeneratorExit().aclose())
1316
1317    def test_Sized(self):
1318        non_samples = [None, 42, 3.14, 1j,
1319                       _test_gen(),
1320                       (x for x in []),
1321                       ]
1322        for x in non_samples:
1323            self.assertNotIsInstance(x, Sized)
1324            self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
1325        samples = [bytes(), str(),
1326                   tuple(), list(), set(), frozenset(), dict(),
1327                   dict().keys(), dict().items(), dict().values(),
1328                   ]
1329        for x in samples:
1330            self.assertIsInstance(x, Sized)
1331            self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
1332        self.validate_abstract_methods(Sized, '__len__')
1333        self.validate_isinstance(Sized, '__len__')
1334
1335    def test_Container(self):
1336        non_samples = [None, 42, 3.14, 1j,
1337                       _test_gen(),
1338                       (x for x in []),
1339                       ]
1340        for x in non_samples:
1341            self.assertNotIsInstance(x, Container)
1342            self.assertFalse(issubclass(type(x), Container), repr(type(x)))
1343        samples = [bytes(), str(),
1344                   tuple(), list(), set(), frozenset(), dict(),
1345                   dict().keys(), dict().items(),
1346                   ]
1347        for x in samples:
1348            self.assertIsInstance(x, Container)
1349            self.assertTrue(issubclass(type(x), Container), repr(type(x)))
1350        self.validate_abstract_methods(Container, '__contains__')
1351        self.validate_isinstance(Container, '__contains__')
1352
1353    def test_Callable(self):
1354        non_samples = [None, 42, 3.14, 1j,
1355                       "", b"", (), [], {}, set(),
1356                       _test_gen(),
1357                       (x for x in []),
1358                       ]
1359        for x in non_samples:
1360            self.assertNotIsInstance(x, Callable)
1361            self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
1362        samples = [lambda: None,
1363                   type, int, object,
1364                   len,
1365                   list.append, [].append,
1366                   ]
1367        for x in samples:
1368            self.assertIsInstance(x, Callable)
1369            self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
1370        self.validate_abstract_methods(Callable, '__call__')
1371        self.validate_isinstance(Callable, '__call__')
1372
1373    def test_direct_subclassing(self):
1374        for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
1375            class C(B):
1376                pass
1377            self.assertTrue(issubclass(C, B))
1378            self.assertFalse(issubclass(int, C))
1379
1380    def test_registration(self):
1381        for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable:
1382            class C:
1383                __hash__ = None  # Make sure it isn't hashable by default
1384            self.assertFalse(issubclass(C, B), B.__name__)
1385            B.register(C)
1386            self.assertTrue(issubclass(C, B))
1387
1388class WithSet(MutableSet):
1389
1390    def __init__(self, it=()):
1391        self.data = set(it)
1392
1393    def __len__(self):
1394        return len(self.data)
1395
1396    def __iter__(self):
1397        return iter(self.data)
1398
1399    def __contains__(self, item):
1400        return item in self.data
1401
1402    def add(self, item):
1403        self.data.add(item)
1404
1405    def discard(self, item):
1406        self.data.discard(item)
1407
1408class TestCollectionABCs(ABCTestCase):
1409
1410    # XXX For now, we only test some virtual inheritance properties.
1411    # We should also test the proper behavior of the collection ABCs
1412    # as real base classes or mix-in classes.
1413
1414    def test_Set(self):
1415        for sample in [set, frozenset]:
1416            self.assertIsInstance(sample(), Set)
1417            self.assertTrue(issubclass(sample, Set))
1418        self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
1419        class MySet(Set):
1420            def __contains__(self, x):
1421                return False
1422            def __len__(self):
1423                return 0
1424            def __iter__(self):
1425                return iter([])
1426        self.validate_comparison(MySet())
1427
1428    def test_hash_Set(self):
1429        class OneTwoThreeSet(Set):
1430            def __init__(self):
1431                self.contents = [1, 2, 3]
1432            def __contains__(self, x):
1433                return x in self.contents
1434            def __len__(self):
1435                return len(self.contents)
1436            def __iter__(self):
1437                return iter(self.contents)
1438            def __hash__(self):
1439                return self._hash()
1440        a, b = OneTwoThreeSet(), OneTwoThreeSet()
1441        self.assertTrue(hash(a) == hash(b))
1442
1443    def test_isdisjoint_Set(self):
1444        class MySet(Set):
1445            def __init__(self, itr):
1446                self.contents = itr
1447            def __contains__(self, x):
1448                return x in self.contents
1449            def __iter__(self):
1450                return iter(self.contents)
1451            def __len__(self):
1452                return len([x for x in self.contents])
1453        s1 = MySet((1, 2, 3))
1454        s2 = MySet((4, 5, 6))
1455        s3 = MySet((1, 5, 6))
1456        self.assertTrue(s1.isdisjoint(s2))
1457        self.assertFalse(s1.isdisjoint(s3))
1458
1459    def test_equality_Set(self):
1460        class MySet(Set):
1461            def __init__(self, itr):
1462                self.contents = itr
1463            def __contains__(self, x):
1464                return x in self.contents
1465            def __iter__(self):
1466                return iter(self.contents)
1467            def __len__(self):
1468                return len([x for x in self.contents])
1469        s1 = MySet((1,))
1470        s2 = MySet((1, 2))
1471        s3 = MySet((3, 4))
1472        s4 = MySet((3, 4))
1473        self.assertTrue(s2 > s1)
1474        self.assertTrue(s1 < s2)
1475        self.assertFalse(s2 <= s1)
1476        self.assertFalse(s2 <= s3)
1477        self.assertFalse(s1 >= s2)
1478        self.assertEqual(s3, s4)
1479        self.assertNotEqual(s2, s3)
1480
1481    def test_arithmetic_Set(self):
1482        class MySet(Set):
1483            def __init__(self, itr):
1484                self.contents = itr
1485            def __contains__(self, x):
1486                return x in self.contents
1487            def __iter__(self):
1488                return iter(self.contents)
1489            def __len__(self):
1490                return len([x for x in self.contents])
1491        s1 = MySet((1, 2, 3))
1492        s2 = MySet((3, 4, 5))
1493        s3 = s1 & s2
1494        self.assertEqual(s3, MySet((3,)))
1495
1496    def test_MutableSet(self):
1497        self.assertIsInstance(set(), MutableSet)
1498        self.assertTrue(issubclass(set, MutableSet))
1499        self.assertNotIsInstance(frozenset(), MutableSet)
1500        self.assertFalse(issubclass(frozenset, MutableSet))
1501        self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
1502            'add', 'discard')
1503
1504    def test_issue_5647(self):
1505        # MutableSet.__iand__ mutated the set during iteration
1506        s = WithSet('abcd')
1507        s &= WithSet('cdef')            # This used to fail
1508        self.assertEqual(set(s), set('cd'))
1509
1510    def test_issue_4920(self):
1511        # MutableSet.pop() method did not work
1512        class MySet(MutableSet):
1513            __slots__=['__s']
1514            def __init__(self,items=None):
1515                if items is None:
1516                    items=[]
1517                self.__s=set(items)
1518            def __contains__(self,v):
1519                return v in self.__s
1520            def __iter__(self):
1521                return iter(self.__s)
1522            def __len__(self):
1523                return len(self.__s)
1524            def add(self,v):
1525                result=v not in self.__s
1526                self.__s.add(v)
1527                return result
1528            def discard(self,v):
1529                result=v in self.__s
1530                self.__s.discard(v)
1531                return result
1532            def __repr__(self):
1533                return "MySet(%s)" % repr(list(self))
1534        items = [5,43,2,1]
1535        s = MySet(items)
1536        r = s.pop()
1537        self.assertEqual(len(s), len(items) - 1)
1538        self.assertNotIn(r, s)
1539        self.assertIn(r, items)
1540
1541    def test_issue8750(self):
1542        empty = WithSet()
1543        full = WithSet(range(10))
1544        s = WithSet(full)
1545        s -= s
1546        self.assertEqual(s, empty)
1547        s = WithSet(full)
1548        s ^= s
1549        self.assertEqual(s, empty)
1550        s = WithSet(full)
1551        s &= s
1552        self.assertEqual(s, full)
1553        s |= s
1554        self.assertEqual(s, full)
1555
1556    def test_issue16373(self):
1557        # Recursion error comparing comparable and noncomparable
1558        # Set instances
1559        class MyComparableSet(Set):
1560            def __contains__(self, x):
1561                return False
1562            def __len__(self):
1563                return 0
1564            def __iter__(self):
1565                return iter([])
1566        class MyNonComparableSet(Set):
1567            def __contains__(self, x):
1568                return False
1569            def __len__(self):
1570                return 0
1571            def __iter__(self):
1572                return iter([])
1573            def __le__(self, x):
1574                return NotImplemented
1575            def __lt__(self, x):
1576                return NotImplemented
1577
1578        cs = MyComparableSet()
1579        ncs = MyNonComparableSet()
1580        self.assertFalse(ncs < cs)
1581        self.assertTrue(ncs <= cs)
1582        self.assertFalse(ncs > cs)
1583        self.assertTrue(ncs >= cs)
1584
1585    def test_issue26915(self):
1586        # Container membership test should check identity first
1587        class CustomSequence(Sequence):
1588            def __init__(self, seq):
1589                self._seq = seq
1590            def __getitem__(self, index):
1591                return self._seq[index]
1592            def __len__(self):
1593                return len(self._seq)
1594
1595        nan = float('nan')
1596        obj = support.NEVER_EQ
1597        seq = CustomSequence([nan, obj, nan])
1598        containers = [
1599            seq,
1600            ItemsView({1: nan, 2: obj}),
1601            KeysView({1: nan, 2: obj}),
1602            ValuesView({1: nan, 2: obj})
1603        ]
1604        for container in containers:
1605            for elem in container:
1606                self.assertIn(elem, container)
1607        self.assertEqual(seq.index(nan), 0)
1608        self.assertEqual(seq.index(obj), 1)
1609        self.assertEqual(seq.count(nan), 2)
1610        self.assertEqual(seq.count(obj), 1)
1611
1612    def assertSameSet(self, s1, s2):
1613        # coerce both to a real set then check equality
1614        self.assertSetEqual(set(s1), set(s2))
1615
1616    def test_Set_from_iterable(self):
1617        """Verify _from_iterable overridden to an instance method works."""
1618        class SetUsingInstanceFromIterable(MutableSet):
1619            def __init__(self, values, created_by):
1620                if not created_by:
1621                    raise ValueError(f'created_by must be specified')
1622                self.created_by = created_by
1623                self._values = set(values)
1624
1625            def _from_iterable(self, values):
1626                return type(self)(values, 'from_iterable')
1627
1628            def __contains__(self, value):
1629                return value in self._values
1630
1631            def __iter__(self):
1632                yield from self._values
1633
1634            def __len__(self):
1635                return len(self._values)
1636
1637            def add(self, value):
1638                self._values.add(value)
1639
1640            def discard(self, value):
1641                self._values.discard(value)
1642
1643        impl = SetUsingInstanceFromIterable([1, 2, 3], 'test')
1644
1645        actual = impl - {1}
1646        self.assertIsInstance(actual, SetUsingInstanceFromIterable)
1647        self.assertEqual('from_iterable', actual.created_by)
1648        self.assertEqual({2, 3}, actual)
1649
1650        actual = impl | {4}
1651        self.assertIsInstance(actual, SetUsingInstanceFromIterable)
1652        self.assertEqual('from_iterable', actual.created_by)
1653        self.assertEqual({1, 2, 3, 4}, actual)
1654
1655        actual = impl & {2}
1656        self.assertIsInstance(actual, SetUsingInstanceFromIterable)
1657        self.assertEqual('from_iterable', actual.created_by)
1658        self.assertEqual({2}, actual)
1659
1660        actual = impl ^ {3, 4}
1661        self.assertIsInstance(actual, SetUsingInstanceFromIterable)
1662        self.assertEqual('from_iterable', actual.created_by)
1663        self.assertEqual({1, 2, 4}, actual)
1664
1665        # NOTE: ixor'ing with a list is important here: internally, __ixor__
1666        # only calls _from_iterable if the other value isn't already a Set.
1667        impl ^= [3, 4]
1668        self.assertIsInstance(impl, SetUsingInstanceFromIterable)
1669        self.assertEqual('test', impl.created_by)
1670        self.assertEqual({1, 2, 4}, impl)
1671
1672    def test_Set_interoperability_with_real_sets(self):
1673        # Issue: 8743
1674        class ListSet(Set):
1675            def __init__(self, elements=()):
1676                self.data = []
1677                for elem in elements:
1678                    if elem not in self.data:
1679                        self.data.append(elem)
1680            def __contains__(self, elem):
1681                return elem in self.data
1682            def __iter__(self):
1683                return iter(self.data)
1684            def __len__(self):
1685                return len(self.data)
1686            def __repr__(self):
1687                return 'Set({!r})'.format(self.data)
1688
1689        r1 = set('abc')
1690        r2 = set('bcd')
1691        r3 = set('abcde')
1692        f1 = ListSet('abc')
1693        f2 = ListSet('bcd')
1694        f3 = ListSet('abcde')
1695        l1 = list('abccba')
1696        l2 = list('bcddcb')
1697        l3 = list('abcdeedcba')
1698
1699        target = r1 & r2
1700        self.assertSameSet(f1 & f2, target)
1701        self.assertSameSet(f1 & r2, target)
1702        self.assertSameSet(r2 & f1, target)
1703        self.assertSameSet(f1 & l2, target)
1704
1705        target = r1 | r2
1706        self.assertSameSet(f1 | f2, target)
1707        self.assertSameSet(f1 | r2, target)
1708        self.assertSameSet(r2 | f1, target)
1709        self.assertSameSet(f1 | l2, target)
1710
1711        fwd_target = r1 - r2
1712        rev_target = r2 - r1
1713        self.assertSameSet(f1 - f2, fwd_target)
1714        self.assertSameSet(f2 - f1, rev_target)
1715        self.assertSameSet(f1 - r2, fwd_target)
1716        self.assertSameSet(f2 - r1, rev_target)
1717        self.assertSameSet(r1 - f2, fwd_target)
1718        self.assertSameSet(r2 - f1, rev_target)
1719        self.assertSameSet(f1 - l2, fwd_target)
1720        self.assertSameSet(f2 - l1, rev_target)
1721
1722        target = r1 ^ r2
1723        self.assertSameSet(f1 ^ f2, target)
1724        self.assertSameSet(f1 ^ r2, target)
1725        self.assertSameSet(r2 ^ f1, target)
1726        self.assertSameSet(f1 ^ l2, target)
1727
1728        # Don't change the following to use assertLess or other
1729        # "more specific" unittest assertions.  The current
1730        # assertTrue/assertFalse style makes the pattern of test
1731        # case combinations clear and allows us to know for sure
1732        # the exact operator being invoked.
1733
1734        # proper subset
1735        self.assertTrue(f1 < f3)
1736        self.assertFalse(f1 < f1)
1737        self.assertFalse(f1 < f2)
1738        self.assertTrue(r1 < f3)
1739        self.assertFalse(r1 < f1)
1740        self.assertFalse(r1 < f2)
1741        self.assertTrue(r1 < r3)
1742        self.assertFalse(r1 < r1)
1743        self.assertFalse(r1 < r2)
1744        with self.assertRaises(TypeError):
1745            f1 < l3
1746        with self.assertRaises(TypeError):
1747            f1 < l1
1748        with self.assertRaises(TypeError):
1749            f1 < l2
1750
1751        # any subset
1752        self.assertTrue(f1 <= f3)
1753        self.assertTrue(f1 <= f1)
1754        self.assertFalse(f1 <= f2)
1755        self.assertTrue(r1 <= f3)
1756        self.assertTrue(r1 <= f1)
1757        self.assertFalse(r1 <= f2)
1758        self.assertTrue(r1 <= r3)
1759        self.assertTrue(r1 <= r1)
1760        self.assertFalse(r1 <= r2)
1761        with self.assertRaises(TypeError):
1762            f1 <= l3
1763        with self.assertRaises(TypeError):
1764            f1 <= l1
1765        with self.assertRaises(TypeError):
1766            f1 <= l2
1767
1768        # proper superset
1769        self.assertTrue(f3 > f1)
1770        self.assertFalse(f1 > f1)
1771        self.assertFalse(f2 > f1)
1772        self.assertTrue(r3 > r1)
1773        self.assertFalse(f1 > r1)
1774        self.assertFalse(f2 > r1)
1775        self.assertTrue(r3 > r1)
1776        self.assertFalse(r1 > r1)
1777        self.assertFalse(r2 > r1)
1778        with self.assertRaises(TypeError):
1779            f1 > l3
1780        with self.assertRaises(TypeError):
1781            f1 > l1
1782        with self.assertRaises(TypeError):
1783            f1 > l2
1784
1785        # any superset
1786        self.assertTrue(f3 >= f1)
1787        self.assertTrue(f1 >= f1)
1788        self.assertFalse(f2 >= f1)
1789        self.assertTrue(r3 >= r1)
1790        self.assertTrue(f1 >= r1)
1791        self.assertFalse(f2 >= r1)
1792        self.assertTrue(r3 >= r1)
1793        self.assertTrue(r1 >= r1)
1794        self.assertFalse(r2 >= r1)
1795        with self.assertRaises(TypeError):
1796            f1 >= l3
1797        with self.assertRaises(TypeError):
1798            f1 >=l1
1799        with self.assertRaises(TypeError):
1800            f1 >= l2
1801
1802        # equality
1803        self.assertTrue(f1 == f1)
1804        self.assertTrue(r1 == f1)
1805        self.assertTrue(f1 == r1)
1806        self.assertFalse(f1 == f3)
1807        self.assertFalse(r1 == f3)
1808        self.assertFalse(f1 == r3)
1809        self.assertFalse(f1 == l3)
1810        self.assertFalse(f1 == l1)
1811        self.assertFalse(f1 == l2)
1812
1813        # inequality
1814        self.assertFalse(f1 != f1)
1815        self.assertFalse(r1 != f1)
1816        self.assertFalse(f1 != r1)
1817        self.assertTrue(f1 != f3)
1818        self.assertTrue(r1 != f3)
1819        self.assertTrue(f1 != r3)
1820        self.assertTrue(f1 != l3)
1821        self.assertTrue(f1 != l1)
1822        self.assertTrue(f1 != l2)
1823
1824    def test_Set_hash_matches_frozenset(self):
1825        sets = [
1826            {}, {1}, {None}, {-1}, {0.0}, {"abc"}, {1, 2, 3},
1827            {10**100, 10**101}, {"a", "b", "ab", ""}, {False, True},
1828            {object(), object(), object()}, {float("nan")},  {frozenset()},
1829            {*range(1000)}, {*range(1000)} - {100, 200, 300},
1830            {*range(sys.maxsize - 10, sys.maxsize + 10)},
1831        ]
1832        for s in sets:
1833            fs = frozenset(s)
1834            self.assertEqual(hash(fs), Set._hash(fs), msg=s)
1835
1836    def test_Mapping(self):
1837        for sample in [dict]:
1838            self.assertIsInstance(sample(), Mapping)
1839            self.assertTrue(issubclass(sample, Mapping))
1840        self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
1841            '__getitem__')
1842        class MyMapping(Mapping):
1843            def __len__(self):
1844                return 0
1845            def __getitem__(self, i):
1846                raise IndexError
1847            def __iter__(self):
1848                return iter(())
1849        self.validate_comparison(MyMapping())
1850        self.assertRaises(TypeError, reversed, MyMapping())
1851
1852    def test_MutableMapping(self):
1853        for sample in [dict]:
1854            self.assertIsInstance(sample(), MutableMapping)
1855            self.assertTrue(issubclass(sample, MutableMapping))
1856        self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
1857            '__getitem__', '__setitem__', '__delitem__')
1858
1859    def test_MutableMapping_subclass(self):
1860        # Test issue 9214
1861        mymap = UserDict()
1862        mymap['red'] = 5
1863        self.assertIsInstance(mymap.keys(), Set)
1864        self.assertIsInstance(mymap.keys(), KeysView)
1865        self.assertIsInstance(mymap.values(), Collection)
1866        self.assertIsInstance(mymap.values(), ValuesView)
1867        self.assertIsInstance(mymap.items(), Set)
1868        self.assertIsInstance(mymap.items(), ItemsView)
1869
1870        mymap = UserDict()
1871        mymap['red'] = 5
1872        z = mymap.keys() | {'orange'}
1873        self.assertIsInstance(z, set)
1874        list(z)
1875        mymap['blue'] = 7               # Shouldn't affect 'z'
1876        self.assertEqual(sorted(z), ['orange', 'red'])
1877
1878        mymap = UserDict()
1879        mymap['red'] = 5
1880        z = mymap.items() | {('orange', 3)}
1881        self.assertIsInstance(z, set)
1882        list(z)
1883        mymap['blue'] = 7               # Shouldn't affect 'z'
1884        self.assertEqual(z, {('orange', 3), ('red', 5)})
1885
1886    def test_Sequence(self):
1887        for sample in [tuple, list, bytes, str]:
1888            self.assertIsInstance(sample(), Sequence)
1889            self.assertTrue(issubclass(sample, Sequence))
1890        self.assertIsInstance(range(10), Sequence)
1891        self.assertTrue(issubclass(range, Sequence))
1892        self.assertIsInstance(memoryview(b""), Sequence)
1893        self.assertTrue(issubclass(memoryview, Sequence))
1894        self.assertTrue(issubclass(str, Sequence))
1895        self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
1896            '__getitem__')
1897
1898    def test_Sequence_mixins(self):
1899        class SequenceSubclass(Sequence):
1900            def __init__(self, seq=()):
1901                self.seq = seq
1902
1903            def __getitem__(self, index):
1904                return self.seq[index]
1905
1906            def __len__(self):
1907                return len(self.seq)
1908
1909        # Compare Sequence.index() behavior to (list|str).index() behavior
1910        def assert_index_same(seq1, seq2, index_args):
1911            try:
1912                expected = seq1.index(*index_args)
1913            except ValueError:
1914                with self.assertRaises(ValueError):
1915                    seq2.index(*index_args)
1916            else:
1917                actual = seq2.index(*index_args)
1918                self.assertEqual(
1919                    actual, expected, '%r.index%s' % (seq1, index_args))
1920
1921        for ty in list, str:
1922            nativeseq = ty('abracadabra')
1923            indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1924            seqseq = SequenceSubclass(nativeseq)
1925            for letter in set(nativeseq) | {'z'}:
1926                assert_index_same(nativeseq, seqseq, (letter,))
1927                for start in range(-3, len(nativeseq) + 3):
1928                    assert_index_same(nativeseq, seqseq, (letter, start))
1929                    for stop in range(-3, len(nativeseq) + 3):
1930                        assert_index_same(
1931                            nativeseq, seqseq, (letter, start, stop))
1932
1933    def test_ByteString(self):
1934        for sample in [bytes, bytearray]:
1935            self.assertIsInstance(sample(), ByteString)
1936            self.assertTrue(issubclass(sample, ByteString))
1937        for sample in [str, list, tuple]:
1938            self.assertNotIsInstance(sample(), ByteString)
1939            self.assertFalse(issubclass(sample, ByteString))
1940        self.assertNotIsInstance(memoryview(b""), ByteString)
1941        self.assertFalse(issubclass(memoryview, ByteString))
1942        self.validate_abstract_methods(ByteString, '__getitem__', '__len__')
1943
1944    def test_MutableSequence(self):
1945        for sample in [tuple, str, bytes]:
1946            self.assertNotIsInstance(sample(), MutableSequence)
1947            self.assertFalse(issubclass(sample, MutableSequence))
1948        for sample in [list, bytearray, deque]:
1949            self.assertIsInstance(sample(), MutableSequence)
1950            self.assertTrue(issubclass(sample, MutableSequence))
1951        self.assertFalse(issubclass(str, MutableSequence))
1952        self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
1953            '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
1954
1955    def test_MutableSequence_mixins(self):
1956        # Test the mixins of MutableSequence by creating a minimal concrete
1957        # class inherited from it.
1958        class MutableSequenceSubclass(MutableSequence):
1959            def __init__(self):
1960                self.lst = []
1961
1962            def __setitem__(self, index, value):
1963                self.lst[index] = value
1964
1965            def __getitem__(self, index):
1966                return self.lst[index]
1967
1968            def __len__(self):
1969                return len(self.lst)
1970
1971            def __delitem__(self, index):
1972                del self.lst[index]
1973
1974            def insert(self, index, value):
1975                self.lst.insert(index, value)
1976
1977        mss = MutableSequenceSubclass()
1978        mss.append(0)
1979        mss.extend((1, 2, 3, 4))
1980        self.assertEqual(len(mss), 5)
1981        self.assertEqual(mss[3], 3)
1982        mss.reverse()
1983        self.assertEqual(mss[3], 1)
1984        mss.pop()
1985        self.assertEqual(len(mss), 4)
1986        mss.remove(3)
1987        self.assertEqual(len(mss), 3)
1988        mss += (10, 20, 30)
1989        self.assertEqual(len(mss), 6)
1990        self.assertEqual(mss[-1], 30)
1991        mss.clear()
1992        self.assertEqual(len(mss), 0)
1993
1994        # issue 34427
1995        # extending self should not cause infinite loop
1996        items = 'ABCD'
1997        mss2 = MutableSequenceSubclass()
1998        mss2.extend(items + items)
1999        mss.clear()
2000        mss.extend(items)
2001        mss.extend(mss)
2002        self.assertEqual(len(mss), len(mss2))
2003        self.assertEqual(list(mss), list(mss2))
2004
2005    def test_illegal_patma_flags(self):
2006        with self.assertRaises(TypeError):
2007            class Both(Collection):
2008                __abc_tpflags__ = (Sequence.__flags__ | Mapping.__flags__)
2009
2010
2011
2012################################################################################
2013### Counter
2014################################################################################
2015
2016class CounterSubclassWithSetItem(Counter):
2017    # Test a counter subclass that overrides __setitem__
2018    def __init__(self, *args, **kwds):
2019        self.called = False
2020        Counter.__init__(self, *args, **kwds)
2021    def __setitem__(self, key, value):
2022        self.called = True
2023        Counter.__setitem__(self, key, value)
2024
2025class CounterSubclassWithGet(Counter):
2026    # Test a counter subclass that overrides get()
2027    def __init__(self, *args, **kwds):
2028        self.called = False
2029        Counter.__init__(self, *args, **kwds)
2030    def get(self, key, default):
2031        self.called = True
2032        return Counter.get(self, key, default)
2033
2034class TestCounter(unittest.TestCase):
2035
2036    def test_basics(self):
2037        c = Counter('abcaba')
2038        self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
2039        self.assertEqual(c, Counter(a=3, b=2, c=1))
2040        self.assertIsInstance(c, dict)
2041        self.assertIsInstance(c, Mapping)
2042        self.assertTrue(issubclass(Counter, dict))
2043        self.assertTrue(issubclass(Counter, Mapping))
2044        self.assertEqual(len(c), 3)
2045        self.assertEqual(sum(c.values()), 6)
2046        self.assertEqual(list(c.values()), [3, 2, 1])
2047        self.assertEqual(list(c.keys()), ['a', 'b', 'c'])
2048        self.assertEqual(list(c), ['a', 'b', 'c'])
2049        self.assertEqual(list(c.items()),
2050                         [('a', 3), ('b', 2), ('c', 1)])
2051        self.assertEqual(c['b'], 2)
2052        self.assertEqual(c['z'], 0)
2053        self.assertEqual(c.__contains__('c'), True)
2054        self.assertEqual(c.__contains__('z'), False)
2055        self.assertEqual(c.get('b', 10), 2)
2056        self.assertEqual(c.get('z', 10), 10)
2057        self.assertEqual(c, dict(a=3, b=2, c=1))
2058        self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
2059        self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
2060        for i in range(5):
2061            self.assertEqual(c.most_common(i),
2062                             [('a', 3), ('b', 2), ('c', 1)][:i])
2063        self.assertEqual(''.join(c.elements()), 'aaabbc')
2064        c['a'] += 1         # increment an existing value
2065        c['b'] -= 2         # sub existing value to zero
2066        del c['c']          # remove an entry
2067        del c['c']          # make sure that del doesn't raise KeyError
2068        c['d'] -= 2         # sub from a missing value
2069        c['e'] = -5         # directly assign a missing value
2070        c['f'] += 4         # add to a missing value
2071        self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
2072        self.assertEqual(''.join(c.elements()), 'aaaaffff')
2073        self.assertEqual(c.pop('f'), 4)
2074        self.assertNotIn('f', c)
2075        for i in range(3):
2076            elem, cnt = c.popitem()
2077            self.assertNotIn(elem, c)
2078        c.clear()
2079        self.assertEqual(c, {})
2080        self.assertEqual(repr(c), 'Counter()')
2081        self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
2082        self.assertRaises(TypeError, hash, c)
2083        c.update(dict(a=5, b=3))
2084        c.update(c=1)
2085        c.update(Counter('a' * 50 + 'b' * 30))
2086        c.update()          # test case with no args
2087        c.__init__('a' * 500 + 'b' * 300)
2088        c.__init__('cdc')
2089        c.__init__()
2090        self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
2091        self.assertEqual(c.setdefault('d', 5), 1)
2092        self.assertEqual(c['d'], 1)
2093        self.assertEqual(c.setdefault('e', 5), 5)
2094        self.assertEqual(c['e'], 5)
2095
2096    def test_init(self):
2097        self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
2098        self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
2099        self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
2100        self.assertRaises(TypeError, Counter, 42)
2101        self.assertRaises(TypeError, Counter, (), ())
2102        self.assertRaises(TypeError, Counter.__init__)
2103
2104    def test_total(self):
2105        c = Counter(a=10, b=5, c=0)
2106        self.assertEqual(c.total(), 15)
2107
2108    def test_order_preservation(self):
2109        # Input order dictates items() order
2110        self.assertEqual(list(Counter('abracadabra').items()),
2111               [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])
2112        # letters with same count:   ^----------^         ^---------^
2113
2114        # Verify retention of order even when all counts are equal
2115        self.assertEqual(list(Counter('xyzpdqqdpzyx').items()),
2116               [('x', 2), ('y', 2), ('z', 2), ('p', 2), ('d', 2), ('q', 2)])
2117
2118        # Input order dictates elements() order
2119        self.assertEqual(list(Counter('abracadabra simsalabim').elements()),
2120                ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b','r',
2121                 'r', 'c', 'd', ' ', 's', 's', 'i', 'i', 'm', 'm', 'l'])
2122
2123        # Math operations order first by the order encountered in the left
2124        # operand and then by the order encountered in the right operand.
2125        ps = 'aaabbcdddeefggghhijjjkkl'
2126        qs = 'abbcccdeefffhkkllllmmnno'
2127        order = {letter: i for i, letter in enumerate(dict.fromkeys(ps + qs))}
2128        def correctly_ordered(seq):
2129            'Return true if the letters occur in the expected order'
2130            positions = [order[letter] for letter in seq]
2131            return positions == sorted(positions)
2132
2133        p, q = Counter(ps), Counter(qs)
2134        self.assertTrue(correctly_ordered(+p))
2135        self.assertTrue(correctly_ordered(-p))
2136        self.assertTrue(correctly_ordered(p + q))
2137        self.assertTrue(correctly_ordered(p - q))
2138        self.assertTrue(correctly_ordered(p | q))
2139        self.assertTrue(correctly_ordered(p & q))
2140
2141        p, q = Counter(ps), Counter(qs)
2142        p += q
2143        self.assertTrue(correctly_ordered(p))
2144
2145        p, q = Counter(ps), Counter(qs)
2146        p -= q
2147        self.assertTrue(correctly_ordered(p))
2148
2149        p, q = Counter(ps), Counter(qs)
2150        p |= q
2151        self.assertTrue(correctly_ordered(p))
2152
2153        p, q = Counter(ps), Counter(qs)
2154        p &= q
2155        self.assertTrue(correctly_ordered(p))
2156
2157        p, q = Counter(ps), Counter(qs)
2158        p.update(q)
2159        self.assertTrue(correctly_ordered(p))
2160
2161        p, q = Counter(ps), Counter(qs)
2162        p.subtract(q)
2163        self.assertTrue(correctly_ordered(p))
2164
2165    def test_update(self):
2166        c = Counter()
2167        c.update(self=42)
2168        self.assertEqual(list(c.items()), [('self', 42)])
2169        c = Counter()
2170        c.update(iterable=42)
2171        self.assertEqual(list(c.items()), [('iterable', 42)])
2172        c = Counter()
2173        c.update(iterable=None)
2174        self.assertEqual(list(c.items()), [('iterable', None)])
2175        self.assertRaises(TypeError, Counter().update, 42)
2176        self.assertRaises(TypeError, Counter().update, {}, {})
2177        self.assertRaises(TypeError, Counter.update)
2178
2179    def test_copying(self):
2180        # Check that counters are copyable, deepcopyable, picklable, and
2181        #have a repr/eval round-trip
2182        words = Counter('which witch had which witches wrist watch'.split())
2183        def check(dup):
2184            msg = "\ncopy: %s\nwords: %s" % (dup, words)
2185            self.assertIsNot(dup, words, msg)
2186            self.assertEqual(dup, words)
2187        check(words.copy())
2188        check(copy.copy(words))
2189        check(copy.deepcopy(words))
2190        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2191            with self.subTest(proto=proto):
2192                check(pickle.loads(pickle.dumps(words, proto)))
2193        check(eval(repr(words)))
2194        update_test = Counter()
2195        update_test.update(words)
2196        check(update_test)
2197        check(Counter(words))
2198
2199    def test_copy_subclass(self):
2200        class MyCounter(Counter):
2201            pass
2202        c = MyCounter('slartibartfast')
2203        d = c.copy()
2204        self.assertEqual(d, c)
2205        self.assertEqual(len(d), len(c))
2206        self.assertEqual(type(d), type(c))
2207
2208    def test_conversions(self):
2209        # Convert to: set, list, dict
2210        s = 'she sells sea shells by the sea shore'
2211        self.assertEqual(sorted(Counter(s).elements()), sorted(s))
2212        self.assertEqual(sorted(Counter(s)), sorted(set(s)))
2213        self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
2214        self.assertEqual(set(Counter(s)), set(s))
2215
2216    def test_invariant_for_the_in_operator(self):
2217        c = Counter(a=10, b=-2, c=0)
2218        for elem in c:
2219            self.assertTrue(elem in c)
2220            self.assertIn(elem, c)
2221
2222    def test_multiset_operations(self):
2223        # Verify that adding a zero counter will strip zeros and negatives
2224        c = Counter(a=10, b=-2, c=0) + Counter()
2225        self.assertEqual(dict(c), dict(a=10))
2226
2227        elements = 'abcd'
2228        for i in range(1000):
2229            # test random pairs of multisets
2230            p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2231            p.update(e=1, f=-1, g=0)
2232            q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2233            q.update(h=1, i=-1, j=0)
2234            for counterop, numberop in [
2235                (Counter.__add__, lambda x, y: max(0, x+y)),
2236                (Counter.__sub__, lambda x, y: max(0, x-y)),
2237                (Counter.__or__, lambda x, y: max(0,x,y)),
2238                (Counter.__and__, lambda x, y: max(0, min(x,y))),
2239            ]:
2240                result = counterop(p, q)
2241                for x in elements:
2242                    self.assertEqual(numberop(p[x], q[x]), result[x],
2243                                     (counterop, x, p, q))
2244                # verify that results exclude non-positive counts
2245                self.assertTrue(x>0 for x in result.values())
2246
2247        elements = 'abcdef'
2248        for i in range(100):
2249            # verify that random multisets with no repeats are exactly like sets
2250            p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
2251            q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
2252            for counterop, setop in [
2253                (Counter.__sub__, set.__sub__),
2254                (Counter.__or__, set.__or__),
2255                (Counter.__and__, set.__and__),
2256            ]:
2257                counter_result = counterop(p, q)
2258                set_result = setop(set(p.elements()), set(q.elements()))
2259                self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
2260
2261    def test_inplace_operations(self):
2262        elements = 'abcd'
2263        for i in range(1000):
2264            # test random pairs of multisets
2265            p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2266            p.update(e=1, f=-1, g=0)
2267            q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
2268            q.update(h=1, i=-1, j=0)
2269            for inplace_op, regular_op in [
2270                (Counter.__iadd__, Counter.__add__),
2271                (Counter.__isub__, Counter.__sub__),
2272                (Counter.__ior__, Counter.__or__),
2273                (Counter.__iand__, Counter.__and__),
2274            ]:
2275                c = p.copy()
2276                c_id = id(c)
2277                regular_result = regular_op(c, q)
2278                inplace_result = inplace_op(c, q)
2279                self.assertEqual(inplace_result, regular_result)
2280                self.assertEqual(id(inplace_result), c_id)
2281
2282    def test_subtract(self):
2283        c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2284        c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
2285        self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
2286        c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2287        c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
2288        self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
2289        c = Counter('aaabbcd')
2290        c.subtract('aaaabbcce')
2291        self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
2292
2293        c = Counter()
2294        c.subtract(self=42)
2295        self.assertEqual(list(c.items()), [('self', -42)])
2296        c = Counter()
2297        c.subtract(iterable=42)
2298        self.assertEqual(list(c.items()), [('iterable', -42)])
2299        self.assertRaises(TypeError, Counter().subtract, 42)
2300        self.assertRaises(TypeError, Counter().subtract, {}, {})
2301        self.assertRaises(TypeError, Counter.subtract)
2302
2303    def test_unary(self):
2304        c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
2305        self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
2306        self.assertEqual(dict(-c), dict(a=5))
2307
2308    def test_repr_nonsortable(self):
2309        c = Counter(a=2, b=None)
2310        r = repr(c)
2311        self.assertIn("'a': 2", r)
2312        self.assertIn("'b': None", r)
2313
2314    def test_helper_function(self):
2315        # two paths, one for real dicts and one for other mappings
2316        elems = list('abracadabra')
2317
2318        d = dict()
2319        _count_elements(d, elems)
2320        self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
2321
2322        m = OrderedDict()
2323        _count_elements(m, elems)
2324        self.assertEqual(m,
2325             OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
2326
2327        # test fidelity to the pure python version
2328        c = CounterSubclassWithSetItem('abracadabra')
2329        self.assertTrue(c.called)
2330        self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
2331        c = CounterSubclassWithGet('abracadabra')
2332        self.assertTrue(c.called)
2333        self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
2334
2335    def test_multiset_operations_equivalent_to_set_operations(self):
2336        # When the multiplicities are all zero or one, multiset operations
2337        # are guaranteed to be equivalent to the corresponding operations
2338        # for regular sets.
2339        s = list(product(('a', 'b', 'c'), range(2)))
2340        powerset = chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
2341        counters = [Counter(dict(groups)) for groups in powerset]
2342        for cp, cq in product(counters, repeat=2):
2343            sp = set(cp.elements())
2344            sq = set(cq.elements())
2345            self.assertEqual(set(cp + cq), sp | sq)
2346            self.assertEqual(set(cp - cq), sp - sq)
2347            self.assertEqual(set(cp | cq), sp | sq)
2348            self.assertEqual(set(cp & cq), sp & sq)
2349            self.assertEqual(cp == cq, sp == sq)
2350            self.assertEqual(cp != cq, sp != sq)
2351            self.assertEqual(cp <= cq, sp <= sq)
2352            self.assertEqual(cp >= cq, sp >= sq)
2353            self.assertEqual(cp < cq, sp < sq)
2354            self.assertEqual(cp > cq, sp > sq)
2355
2356    def test_eq(self):
2357        self.assertEqual(Counter(a=3, b=2, c=0), Counter('ababa'))
2358        self.assertNotEqual(Counter(a=3, b=2), Counter('babab'))
2359
2360    def test_le(self):
2361        self.assertTrue(Counter(a=3, b=2, c=0) <= Counter('ababa'))
2362        self.assertFalse(Counter(a=3, b=2) <= Counter('babab'))
2363
2364    def test_lt(self):
2365        self.assertTrue(Counter(a=3, b=1, c=0) < Counter('ababa'))
2366        self.assertFalse(Counter(a=3, b=2, c=0) < Counter('ababa'))
2367
2368    def test_ge(self):
2369        self.assertTrue(Counter(a=2, b=1, c=0) >= Counter('aab'))
2370        self.assertFalse(Counter(a=3, b=2, c=0) >= Counter('aabd'))
2371
2372    def test_gt(self):
2373        self.assertTrue(Counter(a=3, b=2, c=0) > Counter('aab'))
2374        self.assertFalse(Counter(a=2, b=1, c=0) > Counter('aab'))
2375
2376
2377def load_tests(loader, tests, pattern):
2378    tests.addTest(doctest.DocTestSuite(collections))
2379    return tests
2380
2381
2382if __name__ == "__main__":
2383    unittest.main()
2384