changeset: 99355:afaad8dc8edf branch: 2.7 parent: 99351:eb9d2e5bc8dc user: Serhiy Storchaka date: Wed Nov 25 17:19:27 2015 +0200 files: Lib/test/test_collections.py Lib/test/test_ordered_dict.py Misc/NEWS description: Issue #25616: Tests for OrderedDict are extracted from test_collections into separate file test_ordered_dict. diff -r eb9d2e5bc8dc -r afaad8dc8edf Lib/test/test_collections.py --- a/Lib/test/test_collections.py Wed Nov 25 16:20:04 2015 +0200 +++ b/Lib/test/test_collections.py Wed Nov 25 17:19:27 2015 +0200 @@ -1,19 +1,24 @@ +import collections +import copy +import doctest +import keyword +import operator +import pickle +import cPickle +from random import choice, randrange +import re +import string +import sys +from test import test_support +import unittest -import unittest, doctest, operator -import inspect -from test import test_support from collections import namedtuple, Counter, OrderedDict -from test import mapping_tests -import pickle, cPickle, copy -from random import randrange, shuffle -import keyword -import re -import sys 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 Sequence, MutableSequence + # Silence deprecation warning sets = test_support.import_module('sets', deprecated=True) @@ -178,8 +183,7 @@ self.assertEqual(Dot(1)._fields, ('d',)) n = 5000 - import string, random - names = list(set(''.join([random.choice(string.ascii_letters) + names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) Big = namedtuple('Big', names) @@ -556,7 +560,7 @@ 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: @@ -802,7 +806,7 @@ 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): @@ -1038,290 +1042,11 @@ self.assertRaises(TypeError, Counter().subtract, {}, {}) self.assertRaises(TypeError, Counter.subtract) -class TestOrderedDict(unittest.TestCase): - - def test_init(self): - with self.assertRaises(TypeError): - OrderedDict([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input - self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input - self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input - self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)], - c=3, e=5).items()), pairs) # mixed input - - # make sure no positional args conflict with possible kwdargs - self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)]) - self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)]) - self.assertRaises(TypeError, OrderedDict, 42) - self.assertRaises(TypeError, OrderedDict, (), ()) - self.assertRaises(TypeError, OrderedDict.__init__) - - # Make sure that direct calls to __init__ do not clear previous contents - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.__init__([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - def test_update(self): - with self.assertRaises(TypeError): - OrderedDict().update([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - od = OrderedDict() - od.update(dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # dict input - od = OrderedDict() - od.update(**dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # kwds input - od = OrderedDict() - od.update(pairs) - self.assertEqual(list(od.items()), pairs) # pairs input - od = OrderedDict() - od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5) - self.assertEqual(list(od.items()), pairs) # mixed input - - # Issue 9137: Named argument called 'other' or 'self' - # shouldn't be treated specially. - od = OrderedDict() - od.update(self=23) - self.assertEqual(list(od.items()), [('self', 23)]) - od = OrderedDict() - od.update(other={}) - self.assertEqual(list(od.items()), [('other', {})]) - od = OrderedDict() - od.update(red=5, blue=6, other=7, self=8) - self.assertEqual(sorted(list(od.items())), - [('blue', 6), ('other', 7), ('red', 5), ('self', 8)]) - - # Make sure that direct calls to update do not clear previous contents - # add that updates items are not moved to the end - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.update([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - self.assertRaises(TypeError, OrderedDict().update, 42) - self.assertRaises(TypeError, OrderedDict().update, (), ()) - self.assertRaises(TypeError, OrderedDict.update) - - def test_abc(self): - self.assertIsInstance(OrderedDict(), MutableMapping) - self.assertTrue(issubclass(OrderedDict, MutableMapping)) - - def test_clear(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - self.assertEqual(len(od), len(pairs)) - od.clear() - self.assertEqual(len(od), 0) - - def test_delitem(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - del od['a'] - self.assertNotIn('a', od) - with self.assertRaises(KeyError): - del od['a'] - self.assertEqual(list(od.items()), pairs[:2] + pairs[3:]) - - def test_setitem(self): - od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)]) - od['c'] = 10 # existing element - od['f'] = 20 # new element - self.assertEqual(list(od.items()), - [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)]) - - def test_iterators(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - 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(reversed(od)), - [t[0] for t in reversed(pairs)]) - - def test_popitem(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - while pairs: - self.assertEqual(od.popitem(), pairs.pop()) - with self.assertRaises(KeyError): - od.popitem() - self.assertEqual(len(od), 0) - - def test_pop(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - shuffle(pairs) - while pairs: - k, v = pairs.pop() - self.assertEqual(od.pop(k), v) - with self.assertRaises(KeyError): - od.pop('xyz') - self.assertEqual(len(od), 0) - self.assertEqual(od.pop(k, 12345), 12345) - - # make sure pop still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - m = Missing(a=1) - self.assertEqual(m.pop('b', 5), 5) - self.assertEqual(m.pop('a', 6), 1) - self.assertEqual(m.pop('a', 6), 6) - with self.assertRaises(KeyError): - m.pop('a') - - def test_equality(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od1 = OrderedDict(pairs) - od2 = OrderedDict(pairs) - self.assertEqual(od1, od2) # same order implies equality - pairs = pairs[2:] + pairs[:2] - od2 = OrderedDict(pairs) - self.assertNotEqual(od1, od2) # different order implies inequality - # comparison to regular dict is not order sensitive - self.assertEqual(od1, dict(od2)) - self.assertEqual(dict(od2), od1) - # different length implied inequality - self.assertNotEqual(od1, OrderedDict(pairs[:-1])) - - def test_copying(self): - # Check that ordered dicts are copyable, deepcopyable, picklable, - # and have a repr/eval round-trip - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - update_test = OrderedDict() - update_test.update(od) - for i, dup in enumerate([ - od.copy(), - copy.copy(od), - copy.deepcopy(od), - pickle.loads(pickle.dumps(od, 0)), - pickle.loads(pickle.dumps(od, 1)), - pickle.loads(pickle.dumps(od, 2)), - pickle.loads(pickle.dumps(od, -1)), - eval(repr(od)), - update_test, - OrderedDict(od), - ]): - self.assertTrue(dup is not od) - self.assertEqual(dup, od) - self.assertEqual(list(dup.items()), list(od.items())) - self.assertEqual(len(dup), len(od)) - self.assertEqual(type(dup), type(od)) - - def test_yaml_linkage(self): - # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. - # In yaml, lists are native but tuples are not. - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - # yaml.dump(od) --> - # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n' - self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) - - def test_reduce_not_too_fat(self): - # do not save instance dictionary if not needed - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - self.assertEqual(len(od.__reduce__()), 2) - od.x = 10 - self.assertEqual(len(od.__reduce__()), 3) - - def test_repr(self): - od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) - self.assertEqual(repr(od), - "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") - self.assertEqual(eval(repr(od)), od) - self.assertEqual(repr(OrderedDict()), "OrderedDict()") - - def test_repr_recursive(self): - # See issue #9826 - od = OrderedDict.fromkeys('abc') - od['x'] = od - self.assertEqual(repr(od), - "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") - - def test_setdefault(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - pair_order = list(od.items()) - self.assertEqual(od.setdefault('a', 10), 3) - # make sure order didn't change - self.assertEqual(list(od.items()), pair_order) - self.assertEqual(od.setdefault('x', 10), 10) - # make sure 'x' is added to the end - self.assertEqual(list(od.items())[-1], ('x', 10)) - - # make sure setdefault still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - self.assertEqual(Missing().setdefault(5, 9), 9) - - def test_reinsert(self): - # Given insert a, insert b, delete a, re-insert a, - # verify that a is now later than b. - od = OrderedDict() - od['a'] = 1 - od['b'] = 2 - del od['a'] - 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]) - - # See http://bugs.python.org/issue24286 - self.assertEqual(od.viewkeys(), dict(od).viewkeys()) - self.assertEqual(od.viewitems(), dict(od).viewitems()) - - def test_override_update(self): - # Verify that subclasses can override update() without breaking __init__() - class MyOD(OrderedDict): - def update(self, *args, **kwds): - raise Exception() - items = [('a', 1), ('c', 3), ('b', 2)] - self.assertEqual(list(MyOD(items).items()), items) - -class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): - type2test = OrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - -class MyOrderedDict(OrderedDict): - pass - -class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol): - type2test = MyOrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - -import collections def test_main(verbose=None): NamedTupleDocs = doctest.DocTestSuite(module=collections) test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, - TestCollectionABCs, TestCounter, - TestOrderedDict, GeneralMappingTests, SubclassMappingTests] + TestCollectionABCs, TestCounter] test_support.run_unittest(*test_classes) test_support.run_doctest(collections, verbose) diff -r eb9d2e5bc8dc -r afaad8dc8edf Lib/test/test_ordered_dict.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/test/test_ordered_dict.py Wed Nov 25 17:19:27 2015 +0200 @@ -0,0 +1,293 @@ +import copy +import pickle +from random import shuffle +import unittest +from collections import OrderedDict +from collections import MutableMapping +from test import mapping_tests, test_support + + +class TestOrderedDict(unittest.TestCase): + + def test_init(self): + with self.assertRaises(TypeError): + OrderedDict([('a', 1), ('b', 2)], None) # too many args + pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] + self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input + self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input + self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input + self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)], + c=3, e=5).items()), pairs) # mixed input + + # make sure no positional args conflict with possible kwdargs + self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)]) + self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)]) + self.assertRaises(TypeError, OrderedDict, 42) + self.assertRaises(TypeError, OrderedDict, (), ()) + self.assertRaises(TypeError, OrderedDict.__init__) + + # Make sure that direct calls to __init__ do not clear previous contents + d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) + d.__init__([('e', 5), ('f', 6)], g=7, d=4) + self.assertEqual(list(d.items()), + [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) + + def test_update(self): + with self.assertRaises(TypeError): + OrderedDict().update([('a', 1), ('b', 2)], None) # too many args + pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] + od = OrderedDict() + od.update(dict(pairs)) + self.assertEqual(sorted(od.items()), pairs) # dict input + od = OrderedDict() + od.update(**dict(pairs)) + self.assertEqual(sorted(od.items()), pairs) # kwds input + od = OrderedDict() + od.update(pairs) + self.assertEqual(list(od.items()), pairs) # pairs input + od = OrderedDict() + od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5) + self.assertEqual(list(od.items()), pairs) # mixed input + + # Issue 9137: Named argument called 'other' or 'self' + # shouldn't be treated specially. + od = OrderedDict() + od.update(self=23) + self.assertEqual(list(od.items()), [('self', 23)]) + od = OrderedDict() + od.update(other={}) + self.assertEqual(list(od.items()), [('other', {})]) + od = OrderedDict() + od.update(red=5, blue=6, other=7, self=8) + self.assertEqual(sorted(list(od.items())), + [('blue', 6), ('other', 7), ('red', 5), ('self', 8)]) + + # Make sure that direct calls to update do not clear previous contents + # add that updates items are not moved to the end + d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) + d.update([('e', 5), ('f', 6)], g=7, d=4) + self.assertEqual(list(d.items()), + [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) + + self.assertRaises(TypeError, OrderedDict().update, 42) + self.assertRaises(TypeError, OrderedDict().update, (), ()) + self.assertRaises(TypeError, OrderedDict.update) + + def test_abc(self): + self.assertIsInstance(OrderedDict(), MutableMapping) + self.assertTrue(issubclass(OrderedDict, MutableMapping)) + + def test_clear(self): + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + shuffle(pairs) + od = OrderedDict(pairs) + self.assertEqual(len(od), len(pairs)) + od.clear() + self.assertEqual(len(od), 0) + + def test_delitem(self): + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + od = OrderedDict(pairs) + del od['a'] + self.assertNotIn('a', od) + with self.assertRaises(KeyError): + del od['a'] + self.assertEqual(list(od.items()), pairs[:2] + pairs[3:]) + + def test_setitem(self): + od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)]) + od['c'] = 10 # existing element + od['f'] = 20 # new element + self.assertEqual(list(od.items()), + [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)]) + + def test_iterators(self): + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + 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(reversed(od)), + [t[0] for t in reversed(pairs)]) + + def test_popitem(self): + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + shuffle(pairs) + od = OrderedDict(pairs) + while pairs: + self.assertEqual(od.popitem(), pairs.pop()) + with self.assertRaises(KeyError): + od.popitem() + self.assertEqual(len(od), 0) + + def test_pop(self): + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + shuffle(pairs) + od = OrderedDict(pairs) + shuffle(pairs) + while pairs: + k, v = pairs.pop() + self.assertEqual(od.pop(k), v) + with self.assertRaises(KeyError): + od.pop('xyz') + self.assertEqual(len(od), 0) + self.assertEqual(od.pop(k, 12345), 12345) + + # make sure pop still works when __missing__ is defined + class Missing(OrderedDict): + def __missing__(self, key): + return 0 + m = Missing(a=1) + self.assertEqual(m.pop('b', 5), 5) + self.assertEqual(m.pop('a', 6), 1) + self.assertEqual(m.pop('a', 6), 6) + with self.assertRaises(KeyError): + m.pop('a') + + def test_equality(self): + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + shuffle(pairs) + od1 = OrderedDict(pairs) + od2 = OrderedDict(pairs) + self.assertEqual(od1, od2) # same order implies equality + pairs = pairs[2:] + pairs[:2] + od2 = OrderedDict(pairs) + self.assertNotEqual(od1, od2) # different order implies inequality + # comparison to regular dict is not order sensitive + self.assertEqual(od1, dict(od2)) + self.assertEqual(dict(od2), od1) + # different length implied inequality + self.assertNotEqual(od1, OrderedDict(pairs[:-1])) + + def test_copying(self): + # Check that ordered dicts are copyable, deepcopyable, picklable, + # and have a repr/eval round-trip + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + od = OrderedDict(pairs) + update_test = OrderedDict() + update_test.update(od) + for i, dup in enumerate([ + od.copy(), + copy.copy(od), + copy.deepcopy(od), + pickle.loads(pickle.dumps(od, 0)), + pickle.loads(pickle.dumps(od, 1)), + pickle.loads(pickle.dumps(od, 2)), + pickle.loads(pickle.dumps(od, -1)), + eval(repr(od)), + update_test, + OrderedDict(od), + ]): + self.assertTrue(dup is not od) + self.assertEqual(dup, od) + self.assertEqual(list(dup.items()), list(od.items())) + self.assertEqual(len(dup), len(od)) + self.assertEqual(type(dup), type(od)) + + def test_yaml_linkage(self): + # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. + # In yaml, lists are native but tuples are not. + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + od = OrderedDict(pairs) + # yaml.dump(od) --> + # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n' + self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) + + def test_reduce_not_too_fat(self): + # do not save instance dictionary if not needed + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + od = OrderedDict(pairs) + self.assertEqual(len(od.__reduce__()), 2) + od.x = 10 + self.assertEqual(len(od.__reduce__()), 3) + + def test_repr(self): + od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) + self.assertEqual(repr(od), + "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") + self.assertEqual(eval(repr(od)), od) + self.assertEqual(repr(OrderedDict()), "OrderedDict()") + + def test_repr_recursive(self): + # See issue #9826 + od = OrderedDict.fromkeys('abc') + od['x'] = od + self.assertEqual(repr(od), + "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") + + def test_setdefault(self): + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + shuffle(pairs) + od = OrderedDict(pairs) + pair_order = list(od.items()) + self.assertEqual(od.setdefault('a', 10), 3) + # make sure order didn't change + self.assertEqual(list(od.items()), pair_order) + self.assertEqual(od.setdefault('x', 10), 10) + # make sure 'x' is added to the end + self.assertEqual(list(od.items())[-1], ('x', 10)) + + # make sure setdefault still works when __missing__ is defined + class Missing(OrderedDict): + def __missing__(self, key): + return 0 + self.assertEqual(Missing().setdefault(5, 9), 9) + + def test_reinsert(self): + # Given insert a, insert b, delete a, re-insert a, + # verify that a is now later than b. + od = OrderedDict() + od['a'] = 1 + od['b'] = 2 + del od['a'] + 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]) + + # See http://bugs.python.org/issue24286 + self.assertEqual(od.viewkeys(), dict(od).viewkeys()) + self.assertEqual(od.viewitems(), dict(od).viewitems()) + + def test_override_update(self): + # Verify that subclasses can override update() without breaking __init__() + class MyOD(OrderedDict): + def update(self, *args, **kwds): + raise Exception() + items = [('a', 1), ('c', 3), ('b', 2)] + self.assertEqual(list(MyOD(items).items()), items) + +class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): + type2test = OrderedDict + + def test_popitem(self): + d = self._empty_mapping() + self.assertRaises(KeyError, d.popitem) + +class MyOrderedDict(OrderedDict): + pass + +class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol): + type2test = MyOrderedDict + + def test_popitem(self): + d = self._empty_mapping() + self.assertRaises(KeyError, d.popitem) + + +def test_main(verbose=None): + test_classes = [TestOrderedDict, GeneralMappingTests, SubclassMappingTests] + test_support.run_unittest(*test_classes) + +if __name__ == "__main__": + test_main(verbose=True) diff -r eb9d2e5bc8dc -r afaad8dc8edf Misc/NEWS --- a/Misc/NEWS Wed Nov 25 16:20:04 2015 +0200 +++ b/Misc/NEWS Wed Nov 25 17:19:27 2015 +0200 @@ -27,6 +27,12 @@ - Issue #23914: Fixed SystemError raised by CPickle unpickler on broken data. +Tests +----- + +- Issue #25616: Tests for OrderedDict are extracted from test_collections + into separate file test_ordered_dict. + What's New in Python 2.7.11? ============================