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