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