]>
Commit | Line | Data |
---|---|---|
4710c53d | 1 | # tests common to dict and UserDict\r |
2 | import unittest\r | |
3 | import UserDict\r | |
4 | import test_support\r | |
5 | \r | |
6 | \r | |
7 | class BasicTestMappingProtocol(unittest.TestCase):\r | |
8 | # This base class can be used to check that an object conforms to the\r | |
9 | # mapping protocol\r | |
10 | \r | |
11 | # Functions that can be useful to override to adapt to dictionary\r | |
12 | # semantics\r | |
13 | type2test = None # which class is being tested (overwrite in subclasses)\r | |
14 | \r | |
15 | def _reference(self):\r | |
16 | """Return a dictionary of values which are invariant by storage\r | |
17 | in the object under test."""\r | |
18 | return {1:2, "key1":"value1", "key2":(1,2,3)}\r | |
19 | def _empty_mapping(self):\r | |
20 | """Return an empty mapping object"""\r | |
21 | return self.type2test()\r | |
22 | def _full_mapping(self, data):\r | |
23 | """Return a mapping object with the value contained in data\r | |
24 | dictionary"""\r | |
25 | x = self._empty_mapping()\r | |
26 | for key, value in data.items():\r | |
27 | x[key] = value\r | |
28 | return x\r | |
29 | \r | |
30 | def __init__(self, *args, **kw):\r | |
31 | unittest.TestCase.__init__(self, *args, **kw)\r | |
32 | self.reference = self._reference().copy()\r | |
33 | \r | |
34 | # A (key, value) pair not in the mapping\r | |
35 | key, value = self.reference.popitem()\r | |
36 | self.other = {key:value}\r | |
37 | \r | |
38 | # A (key, value) pair in the mapping\r | |
39 | key, value = self.reference.popitem()\r | |
40 | self.inmapping = {key:value}\r | |
41 | self.reference[key] = value\r | |
42 | \r | |
43 | def test_read(self):\r | |
44 | # Test for read only operations on mapping\r | |
45 | p = self._empty_mapping()\r | |
46 | p1 = dict(p) #workaround for singleton objects\r | |
47 | d = self._full_mapping(self.reference)\r | |
48 | if d is p:\r | |
49 | p = p1\r | |
50 | #Indexing\r | |
51 | for key, value in self.reference.items():\r | |
52 | self.assertEqual(d[key], value)\r | |
53 | knownkey = self.other.keys()[0]\r | |
54 | self.assertRaises(KeyError, lambda:d[knownkey])\r | |
55 | #len\r | |
56 | self.assertEqual(len(p), 0)\r | |
57 | self.assertEqual(len(d), len(self.reference))\r | |
58 | #in\r | |
59 | for k in self.reference:\r | |
60 | self.assertIn(k, d)\r | |
61 | for k in self.other:\r | |
62 | self.assertNotIn(k, d)\r | |
63 | #has_key\r | |
64 | with test_support.check_py3k_warnings(quiet=True):\r | |
65 | for k in self.reference:\r | |
66 | self.assertTrue(d.has_key(k))\r | |
67 | for k in self.other:\r | |
68 | self.assertFalse(d.has_key(k))\r | |
69 | #cmp\r | |
70 | self.assertEqual(cmp(p,p), 0)\r | |
71 | self.assertEqual(cmp(d,d), 0)\r | |
72 | self.assertEqual(cmp(p,d), -1)\r | |
73 | self.assertEqual(cmp(d,p), 1)\r | |
74 | #__non__zero__\r | |
75 | if p: self.fail("Empty mapping must compare to False")\r | |
76 | if not d: self.fail("Full mapping must compare to True")\r | |
77 | # keys(), items(), iterkeys() ...\r | |
78 | def check_iterandlist(iter, lst, ref):\r | |
79 | self.assertTrue(hasattr(iter, 'next'))\r | |
80 | self.assertTrue(hasattr(iter, '__iter__'))\r | |
81 | x = list(iter)\r | |
82 | self.assertTrue(set(x)==set(lst)==set(ref))\r | |
83 | check_iterandlist(d.iterkeys(), d.keys(), self.reference.keys())\r | |
84 | check_iterandlist(iter(d), d.keys(), self.reference.keys())\r | |
85 | check_iterandlist(d.itervalues(), d.values(), self.reference.values())\r | |
86 | check_iterandlist(d.iteritems(), d.items(), self.reference.items())\r | |
87 | #get\r | |
88 | key, value = d.iteritems().next()\r | |
89 | knownkey, knownvalue = self.other.iteritems().next()\r | |
90 | self.assertEqual(d.get(key, knownvalue), value)\r | |
91 | self.assertEqual(d.get(knownkey, knownvalue), knownvalue)\r | |
92 | self.assertNotIn(knownkey, d)\r | |
93 | \r | |
94 | def test_write(self):\r | |
95 | # Test for write operations on mapping\r | |
96 | p = self._empty_mapping()\r | |
97 | #Indexing\r | |
98 | for key, value in self.reference.items():\r | |
99 | p[key] = value\r | |
100 | self.assertEqual(p[key], value)\r | |
101 | for key in self.reference.keys():\r | |
102 | del p[key]\r | |
103 | self.assertRaises(KeyError, lambda:p[key])\r | |
104 | p = self._empty_mapping()\r | |
105 | #update\r | |
106 | p.update(self.reference)\r | |
107 | self.assertEqual(dict(p), self.reference)\r | |
108 | items = p.items()\r | |
109 | p = self._empty_mapping()\r | |
110 | p.update(items)\r | |
111 | self.assertEqual(dict(p), self.reference)\r | |
112 | d = self._full_mapping(self.reference)\r | |
113 | #setdefault\r | |
114 | key, value = d.iteritems().next()\r | |
115 | knownkey, knownvalue = self.other.iteritems().next()\r | |
116 | self.assertEqual(d.setdefault(key, knownvalue), value)\r | |
117 | self.assertEqual(d[key], value)\r | |
118 | self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue)\r | |
119 | self.assertEqual(d[knownkey], knownvalue)\r | |
120 | #pop\r | |
121 | self.assertEqual(d.pop(knownkey), knownvalue)\r | |
122 | self.assertNotIn(knownkey, d)\r | |
123 | self.assertRaises(KeyError, d.pop, knownkey)\r | |
124 | default = 909\r | |
125 | d[knownkey] = knownvalue\r | |
126 | self.assertEqual(d.pop(knownkey, default), knownvalue)\r | |
127 | self.assertNotIn(knownkey, d)\r | |
128 | self.assertEqual(d.pop(knownkey, default), default)\r | |
129 | #popitem\r | |
130 | key, value = d.popitem()\r | |
131 | self.assertNotIn(key, d)\r | |
132 | self.assertEqual(value, self.reference[key])\r | |
133 | p=self._empty_mapping()\r | |
134 | self.assertRaises(KeyError, p.popitem)\r | |
135 | \r | |
136 | def test_constructor(self):\r | |
137 | self.assertEqual(self._empty_mapping(), self._empty_mapping())\r | |
138 | \r | |
139 | def test_bool(self):\r | |
140 | self.assertTrue(not self._empty_mapping())\r | |
141 | self.assertTrue(self.reference)\r | |
142 | self.assertTrue(bool(self._empty_mapping()) is False)\r | |
143 | self.assertTrue(bool(self.reference) is True)\r | |
144 | \r | |
145 | def test_keys(self):\r | |
146 | d = self._empty_mapping()\r | |
147 | self.assertEqual(d.keys(), [])\r | |
148 | d = self.reference\r | |
149 | self.assertIn(self.inmapping.keys()[0], d.keys())\r | |
150 | self.assertNotIn(self.other.keys()[0], d.keys())\r | |
151 | self.assertRaises(TypeError, d.keys, None)\r | |
152 | \r | |
153 | def test_values(self):\r | |
154 | d = self._empty_mapping()\r | |
155 | self.assertEqual(d.values(), [])\r | |
156 | \r | |
157 | self.assertRaises(TypeError, d.values, None)\r | |
158 | \r | |
159 | def test_items(self):\r | |
160 | d = self._empty_mapping()\r | |
161 | self.assertEqual(d.items(), [])\r | |
162 | \r | |
163 | self.assertRaises(TypeError, d.items, None)\r | |
164 | \r | |
165 | def test_len(self):\r | |
166 | d = self._empty_mapping()\r | |
167 | self.assertEqual(len(d), 0)\r | |
168 | \r | |
169 | def test_getitem(self):\r | |
170 | d = self.reference\r | |
171 | self.assertEqual(d[self.inmapping.keys()[0]], self.inmapping.values()[0])\r | |
172 | \r | |
173 | self.assertRaises(TypeError, d.__getitem__)\r | |
174 | \r | |
175 | def test_update(self):\r | |
176 | # mapping argument\r | |
177 | d = self._empty_mapping()\r | |
178 | d.update(self.other)\r | |
179 | self.assertEqual(d.items(), self.other.items())\r | |
180 | \r | |
181 | # No argument\r | |
182 | d = self._empty_mapping()\r | |
183 | d.update()\r | |
184 | self.assertEqual(d, self._empty_mapping())\r | |
185 | \r | |
186 | # item sequence\r | |
187 | d = self._empty_mapping()\r | |
188 | d.update(self.other.items())\r | |
189 | self.assertEqual(d.items(), self.other.items())\r | |
190 | \r | |
191 | # Iterator\r | |
192 | d = self._empty_mapping()\r | |
193 | d.update(self.other.iteritems())\r | |
194 | self.assertEqual(d.items(), self.other.items())\r | |
195 | \r | |
196 | # FIXME: Doesn't work with UserDict\r | |
197 | # self.assertRaises((TypeError, AttributeError), d.update, None)\r | |
198 | self.assertRaises((TypeError, AttributeError), d.update, 42)\r | |
199 | \r | |
200 | outerself = self\r | |
201 | class SimpleUserDict:\r | |
202 | def __init__(self):\r | |
203 | self.d = outerself.reference\r | |
204 | def keys(self):\r | |
205 | return self.d.keys()\r | |
206 | def __getitem__(self, i):\r | |
207 | return self.d[i]\r | |
208 | d.clear()\r | |
209 | d.update(SimpleUserDict())\r | |
210 | i1 = d.items()\r | |
211 | i2 = self.reference.items()\r | |
212 | i1.sort()\r | |
213 | i2.sort()\r | |
214 | self.assertEqual(i1, i2)\r | |
215 | \r | |
216 | class Exc(Exception): pass\r | |
217 | \r | |
218 | d = self._empty_mapping()\r | |
219 | class FailingUserDict:\r | |
220 | def keys(self):\r | |
221 | raise Exc\r | |
222 | self.assertRaises(Exc, d.update, FailingUserDict())\r | |
223 | \r | |
224 | d.clear()\r | |
225 | \r | |
226 | class FailingUserDict:\r | |
227 | def keys(self):\r | |
228 | class BogonIter:\r | |
229 | def __init__(self):\r | |
230 | self.i = 1\r | |
231 | def __iter__(self):\r | |
232 | return self\r | |
233 | def next(self):\r | |
234 | if self.i:\r | |
235 | self.i = 0\r | |
236 | return 'a'\r | |
237 | raise Exc\r | |
238 | return BogonIter()\r | |
239 | def __getitem__(self, key):\r | |
240 | return key\r | |
241 | self.assertRaises(Exc, d.update, FailingUserDict())\r | |
242 | \r | |
243 | class FailingUserDict:\r | |
244 | def keys(self):\r | |
245 | class BogonIter:\r | |
246 | def __init__(self):\r | |
247 | self.i = ord('a')\r | |
248 | def __iter__(self):\r | |
249 | return self\r | |
250 | def next(self):\r | |
251 | if self.i <= ord('z'):\r | |
252 | rtn = chr(self.i)\r | |
253 | self.i += 1\r | |
254 | return rtn\r | |
255 | raise StopIteration\r | |
256 | return BogonIter()\r | |
257 | def __getitem__(self, key):\r | |
258 | raise Exc\r | |
259 | self.assertRaises(Exc, d.update, FailingUserDict())\r | |
260 | \r | |
261 | d = self._empty_mapping()\r | |
262 | class badseq(object):\r | |
263 | def __iter__(self):\r | |
264 | return self\r | |
265 | def next(self):\r | |
266 | raise Exc()\r | |
267 | \r | |
268 | self.assertRaises(Exc, d.update, badseq())\r | |
269 | \r | |
270 | self.assertRaises(ValueError, d.update, [(1, 2, 3)])\r | |
271 | \r | |
272 | # no test_fromkeys or test_copy as both os.environ and selves don't support it\r | |
273 | \r | |
274 | def test_get(self):\r | |
275 | d = self._empty_mapping()\r | |
276 | self.assertTrue(d.get(self.other.keys()[0]) is None)\r | |
277 | self.assertEqual(d.get(self.other.keys()[0], 3), 3)\r | |
278 | d = self.reference\r | |
279 | self.assertTrue(d.get(self.other.keys()[0]) is None)\r | |
280 | self.assertEqual(d.get(self.other.keys()[0], 3), 3)\r | |
281 | self.assertEqual(d.get(self.inmapping.keys()[0]), self.inmapping.values()[0])\r | |
282 | self.assertEqual(d.get(self.inmapping.keys()[0], 3), self.inmapping.values()[0])\r | |
283 | self.assertRaises(TypeError, d.get)\r | |
284 | self.assertRaises(TypeError, d.get, None, None, None)\r | |
285 | \r | |
286 | def test_setdefault(self):\r | |
287 | d = self._empty_mapping()\r | |
288 | self.assertRaises(TypeError, d.setdefault)\r | |
289 | \r | |
290 | def test_popitem(self):\r | |
291 | d = self._empty_mapping()\r | |
292 | self.assertRaises(KeyError, d.popitem)\r | |
293 | self.assertRaises(TypeError, d.popitem, 42)\r | |
294 | \r | |
295 | def test_pop(self):\r | |
296 | d = self._empty_mapping()\r | |
297 | k, v = self.inmapping.items()[0]\r | |
298 | d[k] = v\r | |
299 | self.assertRaises(KeyError, d.pop, self.other.keys()[0])\r | |
300 | \r | |
301 | self.assertEqual(d.pop(k), v)\r | |
302 | self.assertEqual(len(d), 0)\r | |
303 | \r | |
304 | self.assertRaises(KeyError, d.pop, k)\r | |
305 | \r | |
306 | \r | |
307 | class TestMappingProtocol(BasicTestMappingProtocol):\r | |
308 | def test_constructor(self):\r | |
309 | BasicTestMappingProtocol.test_constructor(self)\r | |
310 | self.assertTrue(self._empty_mapping() is not self._empty_mapping())\r | |
311 | self.assertEqual(self.type2test(x=1, y=2), {"x": 1, "y": 2})\r | |
312 | \r | |
313 | def test_bool(self):\r | |
314 | BasicTestMappingProtocol.test_bool(self)\r | |
315 | self.assertTrue(not self._empty_mapping())\r | |
316 | self.assertTrue(self._full_mapping({"x": "y"}))\r | |
317 | self.assertTrue(bool(self._empty_mapping()) is False)\r | |
318 | self.assertTrue(bool(self._full_mapping({"x": "y"})) is True)\r | |
319 | \r | |
320 | def test_keys(self):\r | |
321 | BasicTestMappingProtocol.test_keys(self)\r | |
322 | d = self._empty_mapping()\r | |
323 | self.assertEqual(d.keys(), [])\r | |
324 | d = self._full_mapping({'a': 1, 'b': 2})\r | |
325 | k = d.keys()\r | |
326 | self.assertIn('a', k)\r | |
327 | self.assertIn('b', k)\r | |
328 | self.assertNotIn('c', k)\r | |
329 | \r | |
330 | def test_values(self):\r | |
331 | BasicTestMappingProtocol.test_values(self)\r | |
332 | d = self._full_mapping({1:2})\r | |
333 | self.assertEqual(d.values(), [2])\r | |
334 | \r | |
335 | def test_items(self):\r | |
336 | BasicTestMappingProtocol.test_items(self)\r | |
337 | \r | |
338 | d = self._full_mapping({1:2})\r | |
339 | self.assertEqual(d.items(), [(1, 2)])\r | |
340 | \r | |
341 | def test_has_key(self):\r | |
342 | d = self._empty_mapping()\r | |
343 | self.assertTrue(not d.has_key('a'))\r | |
344 | d = self._full_mapping({'a': 1, 'b': 2})\r | |
345 | k = d.keys()\r | |
346 | k.sort()\r | |
347 | self.assertEqual(k, ['a', 'b'])\r | |
348 | \r | |
349 | self.assertRaises(TypeError, d.has_key)\r | |
350 | \r | |
351 | def test_contains(self):\r | |
352 | d = self._empty_mapping()\r | |
353 | self.assertNotIn('a', d)\r | |
354 | self.assertTrue(not ('a' in d))\r | |
355 | self.assertTrue('a' not in d)\r | |
356 | d = self._full_mapping({'a': 1, 'b': 2})\r | |
357 | self.assertIn('a', d)\r | |
358 | self.assertIn('b', d)\r | |
359 | self.assertNotIn('c', d)\r | |
360 | \r | |
361 | self.assertRaises(TypeError, d.__contains__)\r | |
362 | \r | |
363 | def test_len(self):\r | |
364 | BasicTestMappingProtocol.test_len(self)\r | |
365 | d = self._full_mapping({'a': 1, 'b': 2})\r | |
366 | self.assertEqual(len(d), 2)\r | |
367 | \r | |
368 | def test_getitem(self):\r | |
369 | BasicTestMappingProtocol.test_getitem(self)\r | |
370 | d = self._full_mapping({'a': 1, 'b': 2})\r | |
371 | self.assertEqual(d['a'], 1)\r | |
372 | self.assertEqual(d['b'], 2)\r | |
373 | d['c'] = 3\r | |
374 | d['a'] = 4\r | |
375 | self.assertEqual(d['c'], 3)\r | |
376 | self.assertEqual(d['a'], 4)\r | |
377 | del d['b']\r | |
378 | self.assertEqual(d, {'a': 4, 'c': 3})\r | |
379 | \r | |
380 | self.assertRaises(TypeError, d.__getitem__)\r | |
381 | \r | |
382 | def test_clear(self):\r | |
383 | d = self._full_mapping({1:1, 2:2, 3:3})\r | |
384 | d.clear()\r | |
385 | self.assertEqual(d, {})\r | |
386 | \r | |
387 | self.assertRaises(TypeError, d.clear, None)\r | |
388 | \r | |
389 | def test_update(self):\r | |
390 | BasicTestMappingProtocol.test_update(self)\r | |
391 | # mapping argument\r | |
392 | d = self._empty_mapping()\r | |
393 | d.update({1:100})\r | |
394 | d.update({2:20})\r | |
395 | d.update({1:1, 2:2, 3:3})\r | |
396 | self.assertEqual(d, {1:1, 2:2, 3:3})\r | |
397 | \r | |
398 | # no argument\r | |
399 | d.update()\r | |
400 | self.assertEqual(d, {1:1, 2:2, 3:3})\r | |
401 | \r | |
402 | # keyword arguments\r | |
403 | d = self._empty_mapping()\r | |
404 | d.update(x=100)\r | |
405 | d.update(y=20)\r | |
406 | d.update(x=1, y=2, z=3)\r | |
407 | self.assertEqual(d, {"x":1, "y":2, "z":3})\r | |
408 | \r | |
409 | # item sequence\r | |
410 | d = self._empty_mapping()\r | |
411 | d.update([("x", 100), ("y", 20)])\r | |
412 | self.assertEqual(d, {"x":100, "y":20})\r | |
413 | \r | |
414 | # Both item sequence and keyword arguments\r | |
415 | d = self._empty_mapping()\r | |
416 | d.update([("x", 100), ("y", 20)], x=1, y=2)\r | |
417 | self.assertEqual(d, {"x":1, "y":2})\r | |
418 | \r | |
419 | # iterator\r | |
420 | d = self._full_mapping({1:3, 2:4})\r | |
421 | d.update(self._full_mapping({1:2, 3:4, 5:6}).iteritems())\r | |
422 | self.assertEqual(d, {1:2, 2:4, 3:4, 5:6})\r | |
423 | \r | |
424 | class SimpleUserDict:\r | |
425 | def __init__(self):\r | |
426 | self.d = {1:1, 2:2, 3:3}\r | |
427 | def keys(self):\r | |
428 | return self.d.keys()\r | |
429 | def __getitem__(self, i):\r | |
430 | return self.d[i]\r | |
431 | d.clear()\r | |
432 | d.update(SimpleUserDict())\r | |
433 | self.assertEqual(d, {1:1, 2:2, 3:3})\r | |
434 | \r | |
435 | def test_fromkeys(self):\r | |
436 | self.assertEqual(self.type2test.fromkeys('abc'), {'a':None, 'b':None, 'c':None})\r | |
437 | d = self._empty_mapping()\r | |
438 | self.assertTrue(not(d.fromkeys('abc') is d))\r | |
439 | self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None})\r | |
440 | self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0})\r | |
441 | self.assertEqual(d.fromkeys([]), {})\r | |
442 | def g():\r | |
443 | yield 1\r | |
444 | self.assertEqual(d.fromkeys(g()), {1:None})\r | |
445 | self.assertRaises(TypeError, {}.fromkeys, 3)\r | |
446 | class dictlike(self.type2test): pass\r | |
447 | self.assertEqual(dictlike.fromkeys('a'), {'a':None})\r | |
448 | self.assertEqual(dictlike().fromkeys('a'), {'a':None})\r | |
449 | self.assertTrue(dictlike.fromkeys('a').__class__ is dictlike)\r | |
450 | self.assertTrue(dictlike().fromkeys('a').__class__ is dictlike)\r | |
451 | # FIXME: the following won't work with UserDict, because it's an old style class\r | |
452 | # self.assertTrue(type(dictlike.fromkeys('a')) is dictlike)\r | |
453 | class mydict(self.type2test):\r | |
454 | def __new__(cls):\r | |
455 | return UserDict.UserDict()\r | |
456 | ud = mydict.fromkeys('ab')\r | |
457 | self.assertEqual(ud, {'a':None, 'b':None})\r | |
458 | # FIXME: the following won't work with UserDict, because it's an old style class\r | |
459 | # self.assertIsInstance(ud, UserDict.UserDict)\r | |
460 | self.assertRaises(TypeError, dict.fromkeys)\r | |
461 | \r | |
462 | class Exc(Exception): pass\r | |
463 | \r | |
464 | class baddict1(self.type2test):\r | |
465 | def __init__(self):\r | |
466 | raise Exc()\r | |
467 | \r | |
468 | self.assertRaises(Exc, baddict1.fromkeys, [1])\r | |
469 | \r | |
470 | class BadSeq(object):\r | |
471 | def __iter__(self):\r | |
472 | return self\r | |
473 | def next(self):\r | |
474 | raise Exc()\r | |
475 | \r | |
476 | self.assertRaises(Exc, self.type2test.fromkeys, BadSeq())\r | |
477 | \r | |
478 | class baddict2(self.type2test):\r | |
479 | def __setitem__(self, key, value):\r | |
480 | raise Exc()\r | |
481 | \r | |
482 | self.assertRaises(Exc, baddict2.fromkeys, [1])\r | |
483 | \r | |
484 | def test_copy(self):\r | |
485 | d = self._full_mapping({1:1, 2:2, 3:3})\r | |
486 | self.assertEqual(d.copy(), {1:1, 2:2, 3:3})\r | |
487 | d = self._empty_mapping()\r | |
488 | self.assertEqual(d.copy(), d)\r | |
489 | self.assertIsInstance(d.copy(), d.__class__)\r | |
490 | self.assertRaises(TypeError, d.copy, None)\r | |
491 | \r | |
492 | def test_get(self):\r | |
493 | BasicTestMappingProtocol.test_get(self)\r | |
494 | d = self._empty_mapping()\r | |
495 | self.assertTrue(d.get('c') is None)\r | |
496 | self.assertEqual(d.get('c', 3), 3)\r | |
497 | d = self._full_mapping({'a' : 1, 'b' : 2})\r | |
498 | self.assertTrue(d.get('c') is None)\r | |
499 | self.assertEqual(d.get('c', 3), 3)\r | |
500 | self.assertEqual(d.get('a'), 1)\r | |
501 | self.assertEqual(d.get('a', 3), 1)\r | |
502 | \r | |
503 | def test_setdefault(self):\r | |
504 | BasicTestMappingProtocol.test_setdefault(self)\r | |
505 | d = self._empty_mapping()\r | |
506 | self.assertTrue(d.setdefault('key0') is None)\r | |
507 | d.setdefault('key0', [])\r | |
508 | self.assertTrue(d.setdefault('key0') is None)\r | |
509 | d.setdefault('key', []).append(3)\r | |
510 | self.assertEqual(d['key'][0], 3)\r | |
511 | d.setdefault('key', []).append(4)\r | |
512 | self.assertEqual(len(d['key']), 2)\r | |
513 | \r | |
514 | def test_popitem(self):\r | |
515 | BasicTestMappingProtocol.test_popitem(self)\r | |
516 | for copymode in -1, +1:\r | |
517 | # -1: b has same structure as a\r | |
518 | # +1: b is a.copy()\r | |
519 | for log2size in range(12):\r | |
520 | size = 2**log2size\r | |
521 | a = self._empty_mapping()\r | |
522 | b = self._empty_mapping()\r | |
523 | for i in range(size):\r | |
524 | a[repr(i)] = i\r | |
525 | if copymode < 0:\r | |
526 | b[repr(i)] = i\r | |
527 | if copymode > 0:\r | |
528 | b = a.copy()\r | |
529 | for i in range(size):\r | |
530 | ka, va = ta = a.popitem()\r | |
531 | self.assertEqual(va, int(ka))\r | |
532 | kb, vb = tb = b.popitem()\r | |
533 | self.assertEqual(vb, int(kb))\r | |
534 | self.assertTrue(not(copymode < 0 and ta != tb))\r | |
535 | self.assertTrue(not a)\r | |
536 | self.assertTrue(not b)\r | |
537 | \r | |
538 | def test_pop(self):\r | |
539 | BasicTestMappingProtocol.test_pop(self)\r | |
540 | \r | |
541 | # Tests for pop with specified key\r | |
542 | d = self._empty_mapping()\r | |
543 | k, v = 'abc', 'def'\r | |
544 | \r | |
545 | # verify longs/ints get same value when key > 32 bits (for 64-bit archs)\r | |
546 | # see SF bug #689659\r | |
547 | x = 4503599627370496L\r | |
548 | y = 4503599627370496\r | |
549 | h = self._full_mapping({x: 'anything', y: 'something else'})\r | |
550 | self.assertEqual(h[x], h[y])\r | |
551 | \r | |
552 | self.assertEqual(d.pop(k, v), v)\r | |
553 | d[k] = v\r | |
554 | self.assertEqual(d.pop(k, 1), v)\r | |
555 | \r | |
556 | \r | |
557 | class TestHashMappingProtocol(TestMappingProtocol):\r | |
558 | \r | |
559 | def test_getitem(self):\r | |
560 | TestMappingProtocol.test_getitem(self)\r | |
561 | class Exc(Exception): pass\r | |
562 | \r | |
563 | class BadEq(object):\r | |
564 | def __eq__(self, other):\r | |
565 | raise Exc()\r | |
566 | def __hash__(self):\r | |
567 | return 24\r | |
568 | \r | |
569 | d = self._empty_mapping()\r | |
570 | d[BadEq()] = 42\r | |
571 | self.assertRaises(KeyError, d.__getitem__, 23)\r | |
572 | \r | |
573 | class BadHash(object):\r | |
574 | fail = False\r | |
575 | def __hash__(self):\r | |
576 | if self.fail:\r | |
577 | raise Exc()\r | |
578 | else:\r | |
579 | return 42\r | |
580 | \r | |
581 | d = self._empty_mapping()\r | |
582 | x = BadHash()\r | |
583 | d[x] = 42\r | |
584 | x.fail = True\r | |
585 | self.assertRaises(Exc, d.__getitem__, x)\r | |
586 | \r | |
587 | def test_fromkeys(self):\r | |
588 | TestMappingProtocol.test_fromkeys(self)\r | |
589 | class mydict(self.type2test):\r | |
590 | def __new__(cls):\r | |
591 | return UserDict.UserDict()\r | |
592 | ud = mydict.fromkeys('ab')\r | |
593 | self.assertEqual(ud, {'a':None, 'b':None})\r | |
594 | self.assertIsInstance(ud, UserDict.UserDict)\r | |
595 | \r | |
596 | def test_pop(self):\r | |
597 | TestMappingProtocol.test_pop(self)\r | |
598 | \r | |
599 | class Exc(Exception): pass\r | |
600 | \r | |
601 | class BadHash(object):\r | |
602 | fail = False\r | |
603 | def __hash__(self):\r | |
604 | if self.fail:\r | |
605 | raise Exc()\r | |
606 | else:\r | |
607 | return 42\r | |
608 | \r | |
609 | d = self._empty_mapping()\r | |
610 | x = BadHash()\r | |
611 | d[x] = 42\r | |
612 | x.fail = True\r | |
613 | self.assertRaises(Exc, d.pop, x)\r | |
614 | \r | |
615 | def test_mutatingiteration(self):\r | |
616 | d = self._empty_mapping()\r | |
617 | d[1] = 1\r | |
618 | try:\r | |
619 | for i in d:\r | |
620 | d[i+1] = 1\r | |
621 | except RuntimeError:\r | |
622 | pass\r | |
623 | else:\r | |
624 | self.fail("changing dict size during iteration doesn't raise Error")\r | |
625 | \r | |
626 | def test_repr(self):\r | |
627 | d = self._empty_mapping()\r | |
628 | self.assertEqual(repr(d), '{}')\r | |
629 | d[1] = 2\r | |
630 | self.assertEqual(repr(d), '{1: 2}')\r | |
631 | d = self._empty_mapping()\r | |
632 | d[1] = d\r | |
633 | self.assertEqual(repr(d), '{1: {...}}')\r | |
634 | \r | |
635 | class Exc(Exception): pass\r | |
636 | \r | |
637 | class BadRepr(object):\r | |
638 | def __repr__(self):\r | |
639 | raise Exc()\r | |
640 | \r | |
641 | d = self._full_mapping({1: BadRepr()})\r | |
642 | self.assertRaises(Exc, repr, d)\r | |
643 | \r | |
644 | def test_le(self):\r | |
645 | self.assertTrue(not (self._empty_mapping() < self._empty_mapping()))\r | |
646 | self.assertTrue(not (self._full_mapping({1: 2}) < self._full_mapping({1L: 2L})))\r | |
647 | \r | |
648 | class Exc(Exception): pass\r | |
649 | \r | |
650 | class BadCmp(object):\r | |
651 | def __eq__(self, other):\r | |
652 | raise Exc()\r | |
653 | def __hash__(self):\r | |
654 | return 42\r | |
655 | \r | |
656 | d1 = self._full_mapping({BadCmp(): 1})\r | |
657 | d2 = self._full_mapping({1: 1})\r | |
658 | try:\r | |
659 | d1 < d2\r | |
660 | except Exc:\r | |
661 | pass\r | |
662 | else:\r | |
663 | self.fail("< didn't raise Exc")\r | |
664 | \r | |
665 | def test_setdefault(self):\r | |
666 | TestMappingProtocol.test_setdefault(self)\r | |
667 | \r | |
668 | class Exc(Exception): pass\r | |
669 | \r | |
670 | class BadHash(object):\r | |
671 | fail = False\r | |
672 | def __hash__(self):\r | |
673 | if self.fail:\r | |
674 | raise Exc()\r | |
675 | else:\r | |
676 | return 42\r | |
677 | \r | |
678 | d = self._empty_mapping()\r | |
679 | x = BadHash()\r | |
680 | d[x] = 42\r | |
681 | x.fail = True\r | |
682 | self.assertRaises(Exc, d.setdefault, x, [])\r |