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