• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Check every path through every method of UserDict
2
3from test import test_support, mapping_tests
4import UserDict
5import warnings
6
7d0 = {}
8d1 = {"one": 1}
9d2 = {"one": 1, "two": 2}
10d3 = {"one": 1, "two": 3, "three": 5}
11d4 = {"one": None, "two": None}
12d5 = {"one": 1, "two": 1}
13
14class UserDictTest(mapping_tests.TestHashMappingProtocol):
15    type2test = UserDict.IterableUserDict
16
17    def test_all(self):
18        # Test constructors
19        u = UserDict.UserDict()
20        u0 = UserDict.UserDict(d0)
21        u1 = UserDict.UserDict(d1)
22        u2 = UserDict.IterableUserDict(d2)
23
24        uu = UserDict.UserDict(u)
25        uu0 = UserDict.UserDict(u0)
26        uu1 = UserDict.UserDict(u1)
27        uu2 = UserDict.UserDict(u2)
28
29        # keyword arg constructor
30        self.assertEqual(UserDict.UserDict(one=1, two=2), d2)
31        # item sequence constructor
32        self.assertEqual(UserDict.UserDict([('one',1), ('two',2)]), d2)
33        with test_support.check_warnings((".*'dict'.*",
34                                          PendingDeprecationWarning)):
35            self.assertEqual(UserDict.UserDict(dict=[('one',1), ('two',2)]), d2)
36        # both together
37        self.assertEqual(UserDict.UserDict([('one',1), ('two',2)], two=3, three=5), d3)
38
39        # alternate constructor
40        self.assertEqual(UserDict.UserDict.fromkeys('one two'.split()), d4)
41        self.assertEqual(UserDict.UserDict().fromkeys('one two'.split()), d4)
42        self.assertEqual(UserDict.UserDict.fromkeys('one two'.split(), 1), d5)
43        self.assertEqual(UserDict.UserDict().fromkeys('one two'.split(), 1), d5)
44        self.assertTrue(u1.fromkeys('one two'.split()) is not u1)
45        self.assertIsInstance(u1.fromkeys('one two'.split()), UserDict.UserDict)
46        self.assertIsInstance(u2.fromkeys('one two'.split()), UserDict.IterableUserDict)
47
48        # Test __repr__
49        self.assertEqual(str(u0), str(d0))
50        self.assertEqual(repr(u1), repr(d1))
51        self.assertEqual(repr(u2), repr(d2))
52
53        # Test __cmp__ and __len__
54        all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2]
55        for a in all:
56            for b in all:
57                self.assertEqual(cmp(a, b), cmp(len(a), len(b)))
58
59        # Test __getitem__
60        self.assertEqual(u2["one"], 1)
61        self.assertRaises(KeyError, u1.__getitem__, "two")
62
63        # Test __setitem__
64        u3 = UserDict.UserDict(u2)
65        u3["two"] = 2
66        u3["three"] = 3
67
68        # Test __delitem__
69        del u3["three"]
70        self.assertRaises(KeyError, u3.__delitem__, "three")
71
72        # Test clear
73        u3.clear()
74        self.assertEqual(u3, {})
75
76        # Test copy()
77        u2a = u2.copy()
78        self.assertEqual(u2a, u2)
79        u2b = UserDict.UserDict(x=42, y=23)
80        u2c = u2b.copy() # making a copy of a UserDict is special cased
81        self.assertEqual(u2b, u2c)
82
83        class MyUserDict(UserDict.UserDict):
84            def display(self): print self
85
86        m2 = MyUserDict(u2)
87        m2a = m2.copy()
88        self.assertEqual(m2a, m2)
89
90        # SF bug #476616 -- copy() of UserDict subclass shared data
91        m2['foo'] = 'bar'
92        self.assertNotEqual(m2a, m2)
93
94        # Test keys, items, values
95        self.assertEqual(u2.keys(), d2.keys())
96        self.assertEqual(u2.items(), d2.items())
97        self.assertEqual(u2.values(), d2.values())
98
99        # Test has_key and "in".
100        for i in u2.keys():
101            self.assertIn(i, u2)
102            self.assertEqual(i in u1, i in d1)
103            self.assertEqual(i in u0, i in d0)
104            with test_support.check_py3k_warnings():
105                self.assertTrue(u2.has_key(i))
106                self.assertEqual(u1.has_key(i), d1.has_key(i))
107                self.assertEqual(u0.has_key(i), d0.has_key(i))
108
109        # Test update
110        t = UserDict.UserDict()
111        t.update(u2)
112        self.assertEqual(t, u2)
113        class Items:
114            def items(self):
115                return (("x", 42), ("y", 23))
116        t = UserDict.UserDict()
117        t.update(Items())
118        self.assertEqual(t, {"x": 42, "y": 23})
119
120        # Test get
121        for i in u2.keys():
122            self.assertEqual(u2.get(i), u2[i])
123            self.assertEqual(u1.get(i), d1.get(i))
124            self.assertEqual(u0.get(i), d0.get(i))
125
126        # Test "in" iteration.
127        for i in xrange(20):
128            u2[i] = str(i)
129        ikeys = []
130        for k in u2:
131            ikeys.append(k)
132        keys = u2.keys()
133        self.assertEqual(set(ikeys), set(keys))
134
135        # Test setdefault
136        t = UserDict.UserDict()
137        self.assertEqual(t.setdefault("x", 42), 42)
138        self.assertTrue(t.has_key("x"))
139        self.assertEqual(t.setdefault("x", 23), 42)
140
141        # Test pop
142        t = UserDict.UserDict(x=42)
143        self.assertEqual(t.pop("x"), 42)
144        self.assertRaises(KeyError, t.pop, "x")
145        self.assertEqual(t.pop("x", 1), 1)
146        t["x"] = 42
147        self.assertEqual(t.pop("x", 1), 42)
148
149        # Test popitem
150        t = UserDict.UserDict(x=42)
151        self.assertEqual(t.popitem(), ("x", 42))
152        self.assertRaises(KeyError, t.popitem)
153
154    def test_init(self):
155        for kw in 'self', 'other', 'iterable':
156            self.assertEqual(list(UserDict.UserDict(**{kw: 42}).items()),
157                             [(kw, 42)])
158        self.assertEqual(list(UserDict.UserDict({}, dict=42).items()),
159                         [('dict', 42)])
160        self.assertEqual(list(UserDict.UserDict({}, dict=None).items()),
161                         [('dict', None)])
162        with test_support.check_warnings((".*'dict'.*",
163                                          PendingDeprecationWarning)):
164            self.assertEqual(list(UserDict.UserDict(dict={'a': 42}).items()),
165                             [('a', 42)])
166        self.assertRaises(TypeError, UserDict.UserDict, 42)
167        self.assertRaises(TypeError, UserDict.UserDict, (), ())
168        self.assertRaises(TypeError, UserDict.UserDict.__init__)
169
170    def test_update(self):
171        for kw in 'self', 'other', 'iterable':
172            d = UserDict.UserDict()
173            d.update(**{kw: 42})
174            self.assertEqual(list(d.items()), [(kw, 42)])
175        d = UserDict.UserDict()
176        with test_support.check_warnings((".*'dict'.*",
177                                          PendingDeprecationWarning)):
178            d.update(dict={'a': 42})
179        self.assertEqual(list(d.items()), [('a', 42)])
180        self.assertRaises(TypeError, UserDict.UserDict().update, 42)
181        self.assertRaises(TypeError, UserDict.UserDict().update, {}, {})
182        self.assertRaises(TypeError, UserDict.UserDict.update)
183
184    def test_missing(self):
185        # Make sure UserDict doesn't have a __missing__ method
186        self.assertEqual(hasattr(UserDict, "__missing__"), False)
187        # Test several cases:
188        # (D) subclass defines __missing__ method returning a value
189        # (E) subclass defines __missing__ method raising RuntimeError
190        # (F) subclass sets __missing__ instance variable (no effect)
191        # (G) subclass doesn't define __missing__ at all
192        class D(UserDict.UserDict):
193            def __missing__(self, key):
194                return 42
195        d = D({1: 2, 3: 4})
196        self.assertEqual(d[1], 2)
197        self.assertEqual(d[3], 4)
198        self.assertNotIn(2, d)
199        self.assertNotIn(2, d.keys())
200        self.assertEqual(d[2], 42)
201        class E(UserDict.UserDict):
202            def __missing__(self, key):
203                raise RuntimeError(key)
204        e = E()
205        try:
206            e[42]
207        except RuntimeError, err:
208            self.assertEqual(err.args, (42,))
209        else:
210            self.fail("e[42] didn't raise RuntimeError")
211        class F(UserDict.UserDict):
212            def __init__(self):
213                # An instance variable __missing__ should have no effect
214                self.__missing__ = lambda key: None
215                UserDict.UserDict.__init__(self)
216        f = F()
217        try:
218            f[42]
219        except KeyError, err:
220            self.assertEqual(err.args, (42,))
221        else:
222            self.fail("f[42] didn't raise KeyError")
223        class G(UserDict.UserDict):
224            pass
225        g = G()
226        try:
227            g[42]
228        except KeyError, err:
229            self.assertEqual(err.args, (42,))
230        else:
231            self.fail("g[42] didn't raise KeyError")
232
233##########################
234# Test Dict Mixin
235
236class SeqDict(UserDict.DictMixin):
237    """Dictionary lookalike implemented with lists.
238
239    Used to test and demonstrate DictMixin
240    """
241    def __init__(self, other=None, **kwargs):
242        self.keylist = []
243        self.valuelist = []
244        if other is not None:
245            for (key, value) in other:
246                self[key] = value
247        for (key, value) in kwargs.iteritems():
248            self[key] = value
249    def __getitem__(self, key):
250        try:
251            i = self.keylist.index(key)
252        except ValueError:
253            raise KeyError
254        return self.valuelist[i]
255    def __setitem__(self, key, value):
256        try:
257            i = self.keylist.index(key)
258            self.valuelist[i] = value
259        except ValueError:
260            self.keylist.append(key)
261            self.valuelist.append(value)
262    def __delitem__(self, key):
263        try:
264            i = self.keylist.index(key)
265        except ValueError:
266            raise KeyError
267        self.keylist.pop(i)
268        self.valuelist.pop(i)
269    def keys(self):
270        return list(self.keylist)
271    def copy(self):
272        d = self.__class__()
273        for key, value in self.iteritems():
274            d[key] = value
275        return d
276    @classmethod
277    def fromkeys(cls, keys, value=None):
278        d = cls()
279        for key in keys:
280            d[key] = value
281        return d
282
283class UserDictMixinTest(mapping_tests.TestMappingProtocol):
284    type2test = SeqDict
285
286    def test_all(self):
287        ## Setup test and verify working of the test class
288
289        # check init
290        s = SeqDict()
291
292        # exercise setitem
293        s[10] = 'ten'
294        s[20] = 'twenty'
295        s[30] = 'thirty'
296
297        # exercise delitem
298        del s[20]
299        # check getitem and setitem
300        self.assertEqual(s[10], 'ten')
301        # check keys() and delitem
302        self.assertEqual(s.keys(), [10, 30])
303
304        ## Now, test the DictMixin methods one by one
305        # has_key
306        self.assertTrue(s.has_key(10))
307        self.assertTrue(not s.has_key(20))
308
309        # __contains__
310        self.assertIn(10, s)
311        self.assertNotIn(20, s)
312
313        # __iter__
314        self.assertEqual([k for k in s], [10, 30])
315
316        # __len__
317        self.assertEqual(len(s), 2)
318
319        # iteritems
320        self.assertEqual(list(s.iteritems()), [(10,'ten'), (30, 'thirty')])
321
322        # iterkeys
323        self.assertEqual(list(s.iterkeys()), [10, 30])
324
325        # itervalues
326        self.assertEqual(list(s.itervalues()), ['ten', 'thirty'])
327
328        # values
329        self.assertEqual(s.values(), ['ten', 'thirty'])
330
331        # items
332        self.assertEqual(s.items(), [(10,'ten'), (30, 'thirty')])
333
334        # get
335        self.assertEqual(s.get(10), 'ten')
336        self.assertEqual(s.get(15,'fifteen'), 'fifteen')
337        self.assertEqual(s.get(15), None)
338
339        # setdefault
340        self.assertEqual(s.setdefault(40, 'forty'), 'forty')
341        self.assertEqual(s.setdefault(10, 'null'), 'ten')
342        del s[40]
343
344        # pop
345        self.assertEqual(s.pop(10), 'ten')
346        self.assertNotIn(10, s)
347        s[10] = 'ten'
348        self.assertEqual(s.pop("x", 1), 1)
349        s["x"] = 42
350        self.assertEqual(s.pop("x", 1), 42)
351
352        # popitem
353        k, v = s.popitem()
354        self.assertNotIn(k, s)
355        s[k] = v
356
357        # clear
358        s.clear()
359        self.assertEqual(len(s), 0)
360
361        # empty popitem
362        self.assertRaises(KeyError, s.popitem)
363
364        # update
365        s.update({10: 'ten', 20:'twenty'})
366        self.assertEqual(s[10], 'ten')
367        self.assertEqual(s[20], 'twenty')
368
369        # cmp
370        self.assertEqual(s, {10: 'ten', 20:'twenty'})
371        t = SeqDict()
372        t[20] = 'twenty'
373        t[10] = 'ten'
374        self.assertEqual(s, t)
375
376def test_main():
377    test_support.run_unittest(
378        UserDictTest,
379        UserDictMixinTest
380    )
381
382if __name__ == "__main__":
383    test_main()
384