test_userdict.py 7.66 KB
Newer Older
1 2
# Check every path through every method of UserDict

3
from test import support, mapping_tests
4
import unittest
5
import collections
6 7 8 9

d0 = {}
d1 = {"one": 1}
d2 = {"one": 1, "two": 2}
10 11 12
d3 = {"one": 1, "two": 3, "three": 5}
d4 = {"one": None, "two": None}
d5 = {"one": 1, "two": 1}
13

14
class UserDictTest(mapping_tests.TestHashMappingProtocol):
15
    type2test = collections.UserDict
16

17 18
    def test_all(self):
        # Test constructors
19 20 21 22
        u = collections.UserDict()
        u0 = collections.UserDict(d0)
        u1 = collections.UserDict(d1)
        u2 = collections.UserDict(d2)
23

24 25 26 27
        uu = collections.UserDict(u)
        uu0 = collections.UserDict(u0)
        uu1 = collections.UserDict(u1)
        uu2 = collections.UserDict(u2)
28 29

        # keyword arg constructor
30
        self.assertEqual(collections.UserDict(one=1, two=2), d2)
31
        # item sequence constructor
32
        self.assertEqual(collections.UserDict([('one',1), ('two',2)]), d2)
33 34
        with self.assertWarnsRegex(PendingDeprecationWarning, "'dict'"):
            self.assertEqual(collections.UserDict(dict=[('one',1), ('two',2)]), d2)
35
        # both together
36
        self.assertEqual(collections.UserDict([('one',1), ('two',2)], two=3, three=5), d3)
37 38

        # alternate constructor
39 40 41 42
        self.assertEqual(collections.UserDict.fromkeys('one two'.split()), d4)
        self.assertEqual(collections.UserDict().fromkeys('one two'.split()), d4)
        self.assertEqual(collections.UserDict.fromkeys('one two'.split(), 1), d5)
        self.assertEqual(collections.UserDict().fromkeys('one two'.split(), 1), d5)
43
        self.assertTrue(u1.fromkeys('one two'.split()) is not u1)
44 45
        self.assertIsInstance(u1.fromkeys('one two'.split()), collections.UserDict)
        self.assertIsInstance(u2.fromkeys('one two'.split()), collections.UserDict)
46 47 48 49

        # Test __repr__
        self.assertEqual(str(u0), str(d0))
        self.assertEqual(repr(u1), repr(d1))
50 51
        self.assertIn(repr(u2), ("{'one': 1, 'two': 2}",
                                 "{'two': 2, 'one': 1}"))
52

53
        # Test rich comparison and __len__
54 55 56
        all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2]
        for a in all:
            for b in all:
57
                self.assertEqual(a == b, len(a) == len(b))
58 59 60 61 62 63

        # Test __getitem__
        self.assertEqual(u2["one"], 1)
        self.assertRaises(KeyError, u1.__getitem__, "two")

        # Test __setitem__
64
        u3 = collections.UserDict(u2)
65 66 67 68 69 70 71 72 73 74 75 76 77 78
        u3["two"] = 2
        u3["three"] = 3

        # Test __delitem__
        del u3["three"]
        self.assertRaises(KeyError, u3.__delitem__, "three")

        # Test clear
        u3.clear()
        self.assertEqual(u3, {})

        # Test copy()
        u2a = u2.copy()
        self.assertEqual(u2a, u2)
79
        u2b = collections.UserDict(x=42, y=23)
80 81 82
        u2c = u2b.copy() # making a copy of a UserDict is special cased
        self.assertEqual(u2b, u2c)

83
        class MyUserDict(collections.UserDict):
84
            def display(self): print(self)
85 86 87 88 89 90 91 92 93 94

        m2 = MyUserDict(u2)
        m2a = m2.copy()
        self.assertEqual(m2a, m2)

        # SF bug #476616 -- copy() of UserDict subclass shared data
        m2['foo'] = 'bar'
        self.assertNotEqual(m2a, m2)

        # Test keys, items, values
95 96 97
        self.assertEqual(sorted(u2.keys()), sorted(d2.keys()))
        self.assertEqual(sorted(u2.items()), sorted(d2.items()))
        self.assertEqual(sorted(u2.values()), sorted(d2.values()))
98

99
        # Test "in".
100
        for i in u2.keys():
101
            self.assertIn(i, u2)
102 103 104 105
            self.assertEqual(i in u1, i in d1)
            self.assertEqual(i in u0, i in d0)

        # Test update
106
        t = collections.UserDict()
107 108 109 110 111 112 113 114 115 116
        t.update(u2)
        self.assertEqual(t, u2)

        # Test get
        for i in u2.keys():
            self.assertEqual(u2.get(i), u2[i])
            self.assertEqual(u1.get(i), d1.get(i))
            self.assertEqual(u0.get(i), d0.get(i))

        # Test "in" iteration.
117
        for i in range(20):
118 119 120 121 122
            u2[i] = str(i)
        ikeys = []
        for k in u2:
            ikeys.append(k)
        keys = u2.keys()
123
        self.assertEqual(set(ikeys), set(keys))
124 125

        # Test setdefault
126
        t = collections.UserDict()
127
        self.assertEqual(t.setdefault("x", 42), 42)
128
        self.assertIn("x", t)
129 130 131
        self.assertEqual(t.setdefault("x", 23), 42)

        # Test pop
132
        t = collections.UserDict(x=42)
133 134
        self.assertEqual(t.pop("x"), 42)
        self.assertRaises(KeyError, t.pop, "x")
135 136 137
        self.assertEqual(t.pop("x", 1), 1)
        t["x"] = 42
        self.assertEqual(t.pop("x", 1), 42)
138 139

        # Test popitem
140
        t = collections.UserDict(x=42)
141 142
        self.assertEqual(t.popitem(), ("x", 42))
        self.assertRaises(KeyError, t.popitem)
143

144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
    def test_init(self):
        for kw in 'self', 'other', 'iterable':
            self.assertEqual(list(collections.UserDict(**{kw: 42}).items()),
                             [(kw, 42)])
        self.assertEqual(list(collections.UserDict({}, dict=42).items()),
                         [('dict', 42)])
        self.assertEqual(list(collections.UserDict({}, dict=None).items()),
                         [('dict', None)])
        with self.assertWarnsRegex(PendingDeprecationWarning, "'dict'"):
            self.assertEqual(list(collections.UserDict(dict={'a': 42}).items()),
                             [('a', 42)])
        self.assertRaises(TypeError, collections.UserDict, 42)
        self.assertRaises(TypeError, collections.UserDict, (), ())
        self.assertRaises(TypeError, collections.UserDict.__init__)

    def test_update(self):
        for kw in 'self', 'dict', 'other', 'iterable':
            d = collections.UserDict()
            d.update(**{kw: 42})
            self.assertEqual(list(d.items()), [(kw, 42)])
        self.assertRaises(TypeError, collections.UserDict().update, 42)
        self.assertRaises(TypeError, collections.UserDict().update, {}, {})
        self.assertRaises(TypeError, collections.UserDict.update)

Guido van Rossum's avatar
Guido van Rossum committed
168 169
    def test_missing(self):
        # Make sure UserDict doesn't have a __missing__ method
170
        self.assertEqual(hasattr(collections.UserDict, "__missing__"), False)
Guido van Rossum's avatar
Guido van Rossum committed
171 172 173 174
        # Test several cases:
        # (D) subclass defines __missing__ method returning a value
        # (E) subclass defines __missing__ method raising RuntimeError
        # (F) subclass sets __missing__ instance variable (no effect)
175
        # (G) subclass doesn't define __missing__ at all
176
        class D(collections.UserDict):
Guido van Rossum's avatar
Guido van Rossum committed
177 178 179 180 181
            def __missing__(self, key):
                return 42
        d = D({1: 2, 3: 4})
        self.assertEqual(d[1], 2)
        self.assertEqual(d[3], 4)
182 183
        self.assertNotIn(2, d)
        self.assertNotIn(2, d.keys())
Guido van Rossum's avatar
Guido van Rossum committed
184
        self.assertEqual(d[2], 42)
185
        class E(collections.UserDict):
Guido van Rossum's avatar
Guido van Rossum committed
186 187 188 189 190
            def __missing__(self, key):
                raise RuntimeError(key)
        e = E()
        try:
            e[42]
191
        except RuntimeError as err:
Guido van Rossum's avatar
Guido van Rossum committed
192 193
            self.assertEqual(err.args, (42,))
        else:
194
            self.fail("e[42] didn't raise RuntimeError")
195
        class F(collections.UserDict):
Guido van Rossum's avatar
Guido van Rossum committed
196 197 198
            def __init__(self):
                # An instance variable __missing__ should have no effect
                self.__missing__ = lambda key: None
199
                collections.UserDict.__init__(self)
Guido van Rossum's avatar
Guido van Rossum committed
200 201 202
        f = F()
        try:
            f[42]
203
        except KeyError as err:
Guido van Rossum's avatar
Guido van Rossum committed
204 205
            self.assertEqual(err.args, (42,))
        else:
206
            self.fail("f[42] didn't raise KeyError")
207
        class G(collections.UserDict):
Guido van Rossum's avatar
Guido van Rossum committed
208 209 210 211
            pass
        g = G()
        try:
            g[42]
212
        except KeyError as err:
Guido van Rossum's avatar
Guido van Rossum committed
213 214
            self.assertEqual(err.args, (42,))
        else:
215
            self.fail("g[42] didn't raise KeyError")
Guido van Rossum's avatar
Guido van Rossum committed
216

217

218 219

if __name__ == "__main__":
220
    unittest.main()