ยปCore Development>Code coverage>Lib/test/test_collections.py

Python code coverage for Lib/test/test_collections.py

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