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