aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_collections.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_collections.py')
-rw-r--r--Lib/test/test_collections.py347
1 files changed, 276 insertions, 71 deletions
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 313f81ff656..b2a5f052604 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -1,19 +1,121 @@
+"""Unit tests for collections.py."""
import unittest, doctest, operator
import inspect
-from test import test_support
-from collections import namedtuple, Counter, OrderedDict
+from test import support
+from collections import namedtuple, Counter, OrderedDict, _count_elements
from test import mapping_tests
-import pickle, cPickle, copy
+import pickle, copy
from random import randrange, shuffle
import keyword
import re
import sys
+from collections import _ChainMap
from collections import Hashable, Iterable, Iterator
from collections import Sized, Container, Callable
from collections import Set, MutableSet
-from collections import Mapping, MutableMapping
+from collections import Mapping, MutableMapping, KeysView, ItemsView, UserDict
from collections import Sequence, MutableSequence
+from collections import ByteString
+
+
+################################################################################
+### _ChainMap (helper class for configparser)
+################################################################################
+
+ChainMap = _ChainMap # rename to keep test code in sync with 3.3 version
+
+class TestChainMap(unittest.TestCase):
+
+ def test_basics(self):
+ c = ChainMap()
+ c['a'] = 1
+ c['b'] = 2
+ d = c.new_child()
+ d['b'] = 20
+ d['c'] = 30
+ self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state
+ self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem
+ self.assertEqual(len(d), 3) # check len
+ for key in 'abc': # check contains
+ self.assertIn(key, d)
+ for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get
+ self.assertEqual(d.get(k, 100), v)
+
+ del d['b'] # unmask a value
+ self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state
+ self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem
+ self.assertEqual(len(d), 3) # check len
+ for key in 'abc': # check contains
+ self.assertIn(key, d)
+ for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get
+ self.assertEqual(d.get(k, 100), v)
+ self.assertIn(repr(d), [ # check repr
+ type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})",
+ type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})"
+ ])
+
+ for e in d.copy(), copy.copy(d): # check shallow copies
+ self.assertEqual(d, e)
+ self.assertEqual(d.maps, e.maps)
+ self.assertIsNot(d, e)
+ self.assertIsNot(d.maps[0], e.maps[0])
+ for m1, m2 in zip(d.maps[1:], e.maps[1:]):
+ self.assertIs(m1, m2)
+
+ for e in [pickle.loads(pickle.dumps(d)),
+ copy.deepcopy(d),
+ eval(repr(d))
+ ]: # check deep copies
+ self.assertEqual(d, e)
+ self.assertEqual(d.maps, e.maps)
+ self.assertIsNot(d, e)
+ for m1, m2 in zip(d.maps, e.maps):
+ self.assertIsNot(m1, m2, e)
+
+ f = d.new_child()
+ f['b'] = 5
+ self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}])
+ self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents
+ self.assertEqual(f['b'], 5) # find first in chain
+ self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
+
+ def test_contructor(self):
+ self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict
+ self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list
+
+ def test_bool(self):
+ self.assertFalse(ChainMap())
+ self.assertFalse(ChainMap({}, {}))
+ self.assertTrue(ChainMap({1:2}, {}))
+ self.assertTrue(ChainMap({}, {1:2}))
+
+ def test_missing(self):
+ class DefaultChainMap(ChainMap):
+ def __missing__(self, key):
+ return 999
+ d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30))
+ for k, v in dict(a=1, b=2, c=30, d=999).items():
+ self.assertEqual(d[k], v) # check __getitem__ w/missing
+ for k, v in dict(a=1, b=2, c=30, d=77).items():
+ self.assertEqual(d.get(k, 77), v) # check get() w/ missing
+ for k, v in dict(a=True, b=True, c=True, d=False).items():
+ self.assertEqual(k in d, v) # check __contains__ w/missing
+ self.assertEqual(d.pop('a', 1001), 1, d)
+ self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing
+ self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing
+ with self.assertRaises(KeyError):
+ d.popitem()
+
+ def test_dict_coercion(self):
+ d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
+ self.assertEqual(dict(d), dict(a=1, b=2, c=30))
+ self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
+
+
+################################################################################
+### Named Tuples
+################################################################################
TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
@@ -40,9 +142,9 @@ class TestNamedTuple(unittest.TestCase):
namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
namedtuple('_', 'a b c') # Test leading underscores in a typename
- nt = namedtuple('nt', u'the quick brown fox') # check unicode input
+ nt = namedtuple('nt', 'the quick brown fox') # check unicode input
self.assertNotIn("u'", repr(nt._fields))
- nt = namedtuple('nt', (u'the', u'quick')) # check unicode input
+ nt = namedtuple('nt', ('the', 'quick')) # check unicode input
self.assertNotIn("u'", repr(nt._fields))
self.assertRaises(TypeError, Point._make, [11]) # catch too few args
@@ -138,7 +240,8 @@ class TestNamedTuple(unittest.TestCase):
self.assertEqual(Dot(1)._replace(d=999), (999,))
self.assertEqual(Dot(1)._fields, ('d',))
- n = 5000
+ # n = 5000
+ n = 254 # SyntaxError: more than 255 arguments:
import string, random
names = list(set(''.join([random.choice(string.ascii_letters)
for j in range(10)]) for i in range(n)))
@@ -154,7 +257,7 @@ class TestNamedTuple(unittest.TestCase):
d_expected = dict(zip(names, range(n)))
self.assertEqual(d, d_expected)
b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
- b2_expected = range(n)
+ b2_expected = list(range(n))
b2_expected[1] = 999
b2_expected[-5] = 42
self.assertEqual(b2, tuple(b2_expected))
@@ -162,7 +265,7 @@ class TestNamedTuple(unittest.TestCase):
def test_pickle(self):
p = TestNT(x=10, y=20, z=30)
- for module in pickle, cPickle:
+ for module in (pickle,):
loads = getattr(module, 'loads')
dumps = getattr(module, 'dumps')
for protocol in -1, 0, 1, 2:
@@ -187,7 +290,7 @@ class TestNamedTuple(unittest.TestCase):
self.assertEqual(newt, (10,20,30,40,50))
# Broader test of all interesting names in a template
- with test_support.captured_stdout() as template:
+ with support.captured_stdout() as template:
T = namedtuple('T', 'x', verbose=True)
words = set(re.findall('[A-Za-z]+', template.getvalue()))
words -= set(keyword.kwlist)
@@ -215,6 +318,20 @@ class TestNamedTuple(unittest.TestCase):
# test __getnewargs__
self.assertEqual(t.__getnewargs__(), values)
+ def test_repr(self):
+ with support.captured_stdout() as template:
+ A = namedtuple('A', 'x', verbose=True)
+ self.assertEqual(repr(A(1)), 'A(x=1)')
+ # repr should show the name of the subclass
+ class B(A):
+ pass
+ self.assertEqual(repr(B(1)), 'B(x=1)')
+
+
+################################################################################
+### Abstract Base Classes
+################################################################################
+
class ABCTestCase(unittest.TestCase):
def validate_abstract_methods(self, abc, *names):
@@ -234,24 +351,14 @@ class ABCTestCase(unittest.TestCase):
def validate_isinstance(self, abc, name):
stub = lambda s, *args: 0
- # new-style class
- C = type('C', (object,), {name: stub})
- self.assertIsInstance(C(), abc)
- self.assertTrue(issubclass(C, abc))
- # old-style class
- class C: pass
+ C = type('C', (object,), {'__hash__': None})
setattr(C, name, stub)
self.assertIsInstance(C(), abc)
self.assertTrue(issubclass(C, abc))
- # new-style class
C = type('C', (object,), {'__hash__': None})
self.assertNotIsInstance(C(), abc)
self.assertFalse(issubclass(C, abc))
- # old-style class
- class C: pass
- self.assertNotIsInstance(C(), abc)
- self.assertFalse(issubclass(C, abc))
def validate_comparison(self, instance):
ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
@@ -288,7 +395,7 @@ class TestOneTrickPonyABCs(ABCTestCase):
def test_Hashable(self):
# Check some non-hashables
- non_samples = [list(), set(), dict()]
+ non_samples = [bytearray(), list(), set(), dict()]
for x in non_samples:
self.assertNotIsInstance(x, Hashable)
self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
@@ -297,7 +404,7 @@ class TestOneTrickPonyABCs(ABCTestCase):
int(), float(), complex(),
str(),
tuple(), frozenset(),
- int, list, object, type,
+ int, list, object, type, bytes()
]
for x in samples:
self.assertIsInstance(x, Hashable)
@@ -306,8 +413,7 @@ class TestOneTrickPonyABCs(ABCTestCase):
# Check direct subclassing
class H(Hashable):
def __hash__(self):
- return super(H, self).__hash__()
- __eq__ = Hashable.__eq__ # Silence Py3k warning
+ return super().__hash__()
self.assertEqual(hash(H()), 0)
self.assertFalse(issubclass(int, H))
self.validate_abstract_methods(Hashable, '__hash__')
@@ -320,7 +426,7 @@ class TestOneTrickPonyABCs(ABCTestCase):
self.assertNotIsInstance(x, Iterable)
self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
# Check some iterables
- samples = [str(),
+ samples = [bytes(), str(),
tuple(), list(), set(), frozenset(), dict(),
dict().keys(), dict().items(), dict().values(),
(lambda: (yield))(),
@@ -332,19 +438,18 @@ class TestOneTrickPonyABCs(ABCTestCase):
# Check direct subclassing
class I(Iterable):
def __iter__(self):
- return super(I, self).__iter__()
+ return super().__iter__()
self.assertEqual(list(I()), [])
self.assertFalse(issubclass(str, I))
self.validate_abstract_methods(Iterable, '__iter__')
self.validate_isinstance(Iterable, '__iter__')
def test_Iterator(self):
- non_samples = [None, 42, 3.14, 1j, "".encode('ascii'), "", (), [],
- {}, set()]
+ non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
for x in non_samples:
self.assertNotIsInstance(x, Iterator)
self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
- samples = [iter(str()),
+ samples = [iter(bytes()), iter(str()),
iter(tuple()), iter(list()), iter(dict()),
iter(set()), iter(frozenset()),
iter(dict().keys()), iter(dict().items()),
@@ -355,7 +460,7 @@ class TestOneTrickPonyABCs(ABCTestCase):
for x in samples:
self.assertIsInstance(x, Iterator)
self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
- self.validate_abstract_methods(Iterator, 'next', '__iter__')
+ self.validate_abstract_methods(Iterator, '__next__', '__iter__')
# Issue 10565
class NextOnly:
@@ -363,11 +468,6 @@ class TestOneTrickPonyABCs(ABCTestCase):
yield 1
raise StopIteration
self.assertNotIsInstance(NextOnly(), Iterator)
- class NextOnlyNew(object):
- def __next__(self):
- yield 1
- raise StopIteration
- self.assertNotIsInstance(NextOnlyNew(), Iterator)
def test_Sized(self):
non_samples = [None, 42, 3.14, 1j,
@@ -377,7 +477,7 @@ class TestOneTrickPonyABCs(ABCTestCase):
for x in non_samples:
self.assertNotIsInstance(x, Sized)
self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
- samples = [str(),
+ samples = [bytes(), str(),
tuple(), list(), set(), frozenset(), dict(),
dict().keys(), dict().items(), dict().values(),
]
@@ -395,7 +495,7 @@ class TestOneTrickPonyABCs(ABCTestCase):
for x in non_samples:
self.assertNotIsInstance(x, Container)
self.assertFalse(issubclass(type(x), Container), repr(type(x)))
- samples = [str(),
+ samples = [bytes(), str(),
tuple(), list(), set(), frozenset(), dict(),
dict().keys(), dict().items(),
]
@@ -407,7 +507,7 @@ class TestOneTrickPonyABCs(ABCTestCase):
def test_Callable(self):
non_samples = [None, 42, 3.14, 1j,
- "", "".encode('ascii'), (), [], {}, set(),
+ "", b"", (), [], {}, set(),
(lambda: (yield))(),
(x for x in []),
]
@@ -435,7 +535,6 @@ class TestOneTrickPonyABCs(ABCTestCase):
def test_registration(self):
for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
class C:
- __metaclass__ = type
__hash__ = None # Make sure it isn't hashable by default
self.assertFalse(issubclass(C, B), B.__name__)
B.register(C)
@@ -512,7 +611,7 @@ class TestCollectionABCs(ABCTestCase):
def test_issue_4920(self):
# MutableSet.pop() method did not work
- class MySet(collections.MutableSet):
+ class MySet(MutableSet):
__slots__=['__s']
def __init__(self,items=None):
if items is None:
@@ -552,13 +651,46 @@ class TestCollectionABCs(ABCTestCase):
s |= s
self.assertEqual(s, full)
+ def test_issue16373(self):
+ # Recursion error comparing comparable and noncomparable
+ # Set instances
+ class MyComparableSet(Set):
+ def __contains__(self, x):
+ return False
+ def __len__(self):
+ return 0
+ def __iter__(self):
+ return iter([])
+ class MyNonComparableSet(Set):
+ def __contains__(self, x):
+ return False
+ def __len__(self):
+ return 0
+ def __iter__(self):
+ return iter([])
+ def __le__(self, x):
+ return NotImplemented
+ def __lt__(self, x):
+ return NotImplemented
+
+ cs = MyComparableSet()
+ ncs = MyNonComparableSet()
+ with self.assertRaises(TypeError):
+ ncs < cs
+ with self.assertRaises(TypeError):
+ ncs <= cs
+ with self.assertRaises(TypeError):
+ cs > ncs
+ with self.assertRaises(TypeError):
+ cs >= ncs
+
def test_Mapping(self):
for sample in [dict]:
self.assertIsInstance(sample(), Mapping)
self.assertTrue(issubclass(sample, Mapping))
self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
'__getitem__')
- class MyMapping(collections.Mapping):
+ class MyMapping(Mapping):
def __len__(self):
return 0
def __getitem__(self, i):
@@ -574,28 +706,67 @@ class TestCollectionABCs(ABCTestCase):
self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
'__getitem__', '__setitem__', '__delitem__')
+ def test_MutableMapping_subclass(self):
+ # Test issue 9214
+ mymap = UserDict()
+ mymap['red'] = 5
+ self.assertIsInstance(mymap.keys(), Set)
+ self.assertIsInstance(mymap.keys(), KeysView)
+ self.assertIsInstance(mymap.items(), Set)
+ self.assertIsInstance(mymap.items(), ItemsView)
+
+ mymap = UserDict()
+ mymap['red'] = 5
+ z = mymap.keys() | {'orange'}
+ self.assertIsInstance(z, set)
+ list(z)
+ mymap['blue'] = 7 # Shouldn't affect 'z'
+ self.assertEqual(sorted(z), ['orange', 'red'])
+
+ mymap = UserDict()
+ mymap['red'] = 5
+ z = mymap.items() | {('orange', 3)}
+ self.assertIsInstance(z, set)
+ list(z)
+ mymap['blue'] = 7 # Shouldn't affect 'z'
+ self.assertEqual(sorted(z), [('orange', 3), ('red', 5)])
+
def test_Sequence(self):
- for sample in [tuple, list, str]:
+ for sample in [tuple, list, bytes, str]:
self.assertIsInstance(sample(), Sequence)
self.assertTrue(issubclass(sample, Sequence))
- self.assertTrue(issubclass(basestring, Sequence))
self.assertIsInstance(range(10), Sequence)
- self.assertTrue(issubclass(xrange, Sequence))
+ self.assertTrue(issubclass(range, Sequence))
self.assertTrue(issubclass(str, Sequence))
self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
'__getitem__')
+ def test_ByteString(self):
+ for sample in [bytes, bytearray]:
+ self.assertIsInstance(sample(), ByteString)
+ self.assertTrue(issubclass(sample, ByteString))
+ for sample in [str, list, tuple]:
+ self.assertNotIsInstance(sample(), ByteString)
+ self.assertFalse(issubclass(sample, ByteString))
+ self.assertNotIsInstance(memoryview(b""), ByteString)
+ self.assertFalse(issubclass(memoryview, ByteString))
+
def test_MutableSequence(self):
- for sample in [tuple, str]:
+ for sample in [tuple, str, bytes]:
self.assertNotIsInstance(sample(), MutableSequence)
self.assertFalse(issubclass(sample, MutableSequence))
- for sample in [list]:
+ for sample in [list, bytearray]:
self.assertIsInstance(sample(), MutableSequence)
self.assertTrue(issubclass(sample, MutableSequence))
- self.assertFalse(issubclass(basestring, MutableSequence))
+ self.assertFalse(issubclass(str, MutableSequence))
self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
'__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
+
+################################################################################
+### Counter
+################################################################################
+
class TestCounter(unittest.TestCase):
def test_basics(self):
@@ -615,9 +786,6 @@ class TestCounter(unittest.TestCase):
[('a', 3), ('b', 2), ('c', 1)])
self.assertEqual(c['b'], 2)
self.assertEqual(c['z'], 0)
- with test_support.check_py3k_warnings():
- self.assertEqual(c.has_key('c'), True)
- self.assertEqual(c.has_key('z'), False)
self.assertEqual(c.__contains__('c'), True)
self.assertEqual(c.__contains__('z'), False)
self.assertEqual(c.get('b', 10), 2)
@@ -675,10 +843,6 @@ class TestCounter(unittest.TestCase):
pickle.loads(pickle.dumps(words, 1)),
pickle.loads(pickle.dumps(words, 2)),
pickle.loads(pickle.dumps(words, -1)),
- cPickle.loads(cPickle.dumps(words, 0)),
- cPickle.loads(cPickle.dumps(words, 1)),
- cPickle.loads(cPickle.dumps(words, 2)),
- cPickle.loads(cPickle.dumps(words, -1)),
eval(repr(words)),
update_test,
Counter(words),
@@ -762,6 +926,30 @@ class TestCounter(unittest.TestCase):
c.subtract('aaaabbcce')
self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
+ def test_repr_nonsortable(self):
+ c = Counter(a=2, b=None)
+ r = repr(c)
+ self.assertIn("'a': 2", r)
+ self.assertIn("'b': None", r)
+
+ def test_helper_function(self):
+ # two paths, one for real dicts and one for other mappings
+ elems = list('abracadabra')
+
+ d = dict()
+ _count_elements(d, elems)
+ self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
+
+ m = OrderedDict()
+ _count_elements(m, elems)
+ self.assertEqual(m,
+ OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]))
+
+
+################################################################################
+### OrderedDict
+################################################################################
+
class TestOrderedDict(unittest.TestCase):
def test_init(self):
@@ -854,12 +1042,9 @@ class TestOrderedDict(unittest.TestCase):
shuffle(pairs)
od = OrderedDict(pairs)
self.assertEqual(list(od), [t[0] for t in pairs])
- self.assertEqual(od.keys()[:], [t[0] for t in pairs])
- self.assertEqual(od.values()[:], [t[1] for t in pairs])
- self.assertEqual(od.items()[:], pairs)
- self.assertEqual(list(od.iterkeys()), [t[0] for t in pairs])
- self.assertEqual(list(od.itervalues()), [t[1] for t in pairs])
- self.assertEqual(list(od.iteritems()), pairs)
+ self.assertEqual(list(od.keys()), [t[0] for t in pairs])
+ self.assertEqual(list(od.values()), [t[1] for t in pairs])
+ self.assertEqual(list(od.items()), pairs)
self.assertEqual(list(reversed(od)),
[t[0] for t in reversed(pairs)])
@@ -926,6 +1111,7 @@ class TestOrderedDict(unittest.TestCase):
pickle.loads(pickle.dumps(od, 0)),
pickle.loads(pickle.dumps(od, 1)),
pickle.loads(pickle.dumps(od, 2)),
+ pickle.loads(pickle.dumps(od, 3)),
pickle.loads(pickle.dumps(od, -1)),
eval(repr(od)),
update_test,
@@ -996,12 +1182,25 @@ class TestOrderedDict(unittest.TestCase):
od['a'] = 1
self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
- def test_views(self):
- s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split()
- od = OrderedDict.fromkeys(s)
- self.assertEqual(list(od.viewkeys()), s)
- self.assertEqual(list(od.viewvalues()), [None for k in s])
- self.assertEqual(list(od.viewitems()), [(k, None) for k in s])
+ def test_move_to_end(self):
+ od = OrderedDict.fromkeys('abcde')
+ self.assertEqual(list(od), list('abcde'))
+ od.move_to_end('c')
+ self.assertEqual(list(od), list('abdec'))
+ od.move_to_end('c', 0)
+ self.assertEqual(list(od), list('cabde'))
+ od.move_to_end('c', 0)
+ self.assertEqual(list(od), list('cabde'))
+ od.move_to_end('e')
+ self.assertEqual(list(od), list('cabde'))
+ with self.assertRaises(KeyError):
+ od.move_to_end('x')
+
+ def test_sizeof(self):
+ # Wimpy test: Just verify the reported size is larger than a regular dict
+ d = dict(a=1)
+ od = OrderedDict(**d)
+ self.assertGreater(sys.getsizeof(od), sys.getsizeof(d))
def test_override_update(self):
# Verify that subclasses can override update() without breaking __init__()
@@ -1028,15 +1227,21 @@ class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
d = self._empty_mapping()
self.assertRaises(KeyError, d.popitem)
-import collections
+
+################################################################################
+### Run tests
+################################################################################
+
+import doctest, collections
def test_main(verbose=None):
NamedTupleDocs = doctest.DocTestSuite(module=collections)
test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
- TestCollectionABCs, TestCounter,
+ TestCollectionABCs, TestCounter, TestChainMap,
TestOrderedDict, GeneralMappingTests, SubclassMappingTests]
- test_support.run_unittest(*test_classes)
- test_support.run_doctest(collections, verbose)
+ support.run_unittest(*test_classes)
+ support.run_doctest(collections, verbose)
+
if __name__ == "__main__":
test_main(verbose=True)