blob: 25fec4e795fd097247857d7de30212fbb9e451fb [file] [log] [blame]
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +00001# tests common to dict and UserDict
2import unittest
3import UserDict
4
5
6class 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
Walter Dörwald118f9312004-06-02 18:42:25 +000012 type2test = None # which class is being tested (overwrite in subclasses)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000013
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"""
Walter Dörwald118f9312004-06-02 18:42:25 +000020 return self.type2test()
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000021 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))
Guido van Rossume2b70bc2006-08-18 22:13:04 +000057 #__contains__
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000058 for k in self.reference:
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000059 self.assert_(k in d)
60 for k in self.other:
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000061 self.failIf(k in d)
62 #cmp
Guido van Rossum47b9ff62006-08-24 00:41:19 +000063 self.assertEqual(p, p)
64 self.assertEqual(d, d)
65 self.assertNotEqual(p, d)
66 self.assertNotEqual(d, p)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000067 #__non__zero__
68 if p: self.fail("Empty mapping must compare to False")
69 if not d: self.fail("Full mapping must compare to True")
70 # keys(), items(), iterkeys() ...
71 def check_iterandlist(iter, lst, ref):
72 self.assert_(hasattr(iter, 'next'))
73 self.assert_(hasattr(iter, '__iter__'))
74 x = list(iter)
75 self.assert_(set(x)==set(lst)==set(ref))
Guido van Rossumcc2b0162007-02-11 06:12:03 +000076 check_iterandlist(d.keys(), d.keys(), self.reference.keys())
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000077 check_iterandlist(iter(d), d.keys(), self.reference.keys())
Guido van Rossumcc2b0162007-02-11 06:12:03 +000078 check_iterandlist(d.values(), d.values(), self.reference.values())
79 check_iterandlist(d.items(), d.items(), self.reference.items())
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000080 #get
Guido van Rossumcc2b0162007-02-11 06:12:03 +000081 key, value = d.items().next()
82 knownkey, knownvalue = self.other.items().next()
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000083 self.assertEqual(d.get(key, knownvalue), value)
84 self.assertEqual(d.get(knownkey, knownvalue), knownvalue)
85 self.failIf(knownkey in d)
86
87 def test_write(self):
88 # Test for write operations on mapping
89 p = self._empty_mapping()
90 #Indexing
91 for key, value in self.reference.items():
92 p[key] = value
93 self.assertEqual(p[key], value)
94 for key in self.reference.keys():
95 del p[key]
96 self.failUnlessRaises(KeyError, lambda:p[key])
97 p = self._empty_mapping()
98 #update
99 p.update(self.reference)
100 self.assertEqual(dict(p), self.reference)
101 items = p.items()
102 p = self._empty_mapping()
103 p.update(items)
104 self.assertEqual(dict(p), self.reference)
105 d = self._full_mapping(self.reference)
106 #setdefault
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000107 key, value = d.items().next()
108 knownkey, knownvalue = self.other.items().next()
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000109 self.assertEqual(d.setdefault(key, knownvalue), value)
110 self.assertEqual(d[key], value)
111 self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue)
112 self.assertEqual(d[knownkey], knownvalue)
113 #pop
114 self.assertEqual(d.pop(knownkey), knownvalue)
115 self.failIf(knownkey in d)
116 self.assertRaises(KeyError, d.pop, knownkey)
117 default = 909
118 d[knownkey] = knownvalue
119 self.assertEqual(d.pop(knownkey, default), knownvalue)
120 self.failIf(knownkey in d)
121 self.assertEqual(d.pop(knownkey, default), default)
122 #popitem
123 key, value = d.popitem()
124 self.failIf(key in d)
125 self.assertEqual(value, self.reference[key])
126 p=self._empty_mapping()
127 self.assertRaises(KeyError, p.popitem)
128
129 def test_constructor(self):
130 self.assertEqual(self._empty_mapping(), self._empty_mapping())
131
132 def test_bool(self):
133 self.assert_(not self._empty_mapping())
134 self.assert_(self.reference)
135 self.assert_(bool(self._empty_mapping()) is False)
136 self.assert_(bool(self.reference) is True)
137
138 def test_keys(self):
139 d = self._empty_mapping()
140 self.assertEqual(d.keys(), [])
141 d = self.reference
142 self.assert_(self.inmapping.keys()[0] in d.keys())
143 self.assert_(self.other.keys()[0] not in d.keys())
144 self.assertRaises(TypeError, d.keys, None)
145
146 def test_values(self):
147 d = self._empty_mapping()
148 self.assertEqual(d.values(), [])
149
150 self.assertRaises(TypeError, d.values, None)
151
152 def test_items(self):
153 d = self._empty_mapping()
154 self.assertEqual(d.items(), [])
155
156 self.assertRaises(TypeError, d.items, None)
157
158 def test_len(self):
159 d = self._empty_mapping()
160 self.assertEqual(len(d), 0)
161
162 def test_getitem(self):
163 d = self.reference
164 self.assertEqual(d[self.inmapping.keys()[0]], self.inmapping.values()[0])
165
166 self.assertRaises(TypeError, d.__getitem__)
167
168 def test_update(self):
169 # mapping argument
170 d = self._empty_mapping()
171 d.update(self.other)
172 self.assertEqual(d.items(), self.other.items())
173
174 # No argument
175 d = self._empty_mapping()
176 d.update()
177 self.assertEqual(d, self._empty_mapping())
178
179 # item sequence
180 d = self._empty_mapping()
181 d.update(self.other.items())
182 self.assertEqual(d.items(), self.other.items())
183
184 # Iterator
185 d = self._empty_mapping()
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000186 d.update(self.other.items())
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000187 self.assertEqual(d.items(), self.other.items())
188
189 # FIXME: Doesn't work with UserDict
190 # self.assertRaises((TypeError, AttributeError), d.update, None)
191 self.assertRaises((TypeError, AttributeError), d.update, 42)
192
193 outerself = self
194 class SimpleUserDict:
195 def __init__(self):
196 self.d = outerself.reference
197 def keys(self):
198 return self.d.keys()
199 def __getitem__(self, i):
200 return self.d[i]
201 d.clear()
202 d.update(SimpleUserDict())
203 i1 = d.items()
204 i2 = self.reference.items()
205 i1.sort()
206 i2.sort()
207 self.assertEqual(i1, i2)
208
209 class Exc(Exception): pass
210
211 d = self._empty_mapping()
212 class FailingUserDict:
213 def keys(self):
214 raise Exc
215 self.assertRaises(Exc, d.update, FailingUserDict())
216
217 d.clear()
218
219 class FailingUserDict:
220 def keys(self):
221 class BogonIter:
222 def __init__(self):
223 self.i = 1
224 def __iter__(self):
225 return self
226 def next(self):
227 if self.i:
228 self.i = 0
229 return 'a'
230 raise Exc
231 return BogonIter()
232 def __getitem__(self, key):
233 return key
234 self.assertRaises(Exc, d.update, FailingUserDict())
235
236 class FailingUserDict:
237 def keys(self):
238 class BogonIter:
239 def __init__(self):
240 self.i = ord('a')
241 def __iter__(self):
242 return self
243 def next(self):
244 if self.i <= ord('z'):
245 rtn = chr(self.i)
246 self.i += 1
247 return rtn
248 raise StopIteration
249 return BogonIter()
250 def __getitem__(self, key):
251 raise Exc
252 self.assertRaises(Exc, d.update, FailingUserDict())
253
254 d = self._empty_mapping()
255 class badseq(object):
256 def __iter__(self):
257 return self
258 def next(self):
259 raise Exc()
260
261 self.assertRaises(Exc, d.update, badseq())
262
263 self.assertRaises(ValueError, d.update, [(1, 2, 3)])
264
265 # no test_fromkeys or test_copy as both os.environ and selves don't support it
266
267 def test_get(self):
268 d = self._empty_mapping()
269 self.assert_(d.get(self.other.keys()[0]) is None)
270 self.assertEqual(d.get(self.other.keys()[0], 3), 3)
271 d = self.reference
272 self.assert_(d.get(self.other.keys()[0]) is None)
273 self.assertEqual(d.get(self.other.keys()[0], 3), 3)
274 self.assertEqual(d.get(self.inmapping.keys()[0]), self.inmapping.values()[0])
275 self.assertEqual(d.get(self.inmapping.keys()[0], 3), self.inmapping.values()[0])
276 self.assertRaises(TypeError, d.get)
277 self.assertRaises(TypeError, d.get, None, None, None)
278
279 def test_setdefault(self):
280 d = self._empty_mapping()
281 self.assertRaises(TypeError, d.setdefault)
282
283 def test_popitem(self):
284 d = self._empty_mapping()
285 self.assertRaises(KeyError, d.popitem)
286 self.assertRaises(TypeError, d.popitem, 42)
287
288 def test_pop(self):
289 d = self._empty_mapping()
290 k, v = self.inmapping.items()[0]
291 d[k] = v
292 self.assertRaises(KeyError, d.pop, self.other.keys()[0])
293
294 self.assertEqual(d.pop(k), v)
295 self.assertEqual(len(d), 0)
296
297 self.assertRaises(KeyError, d.pop, k)
298
299
300class TestMappingProtocol(BasicTestMappingProtocol):
301 def test_constructor(self):
302 BasicTestMappingProtocol.test_constructor(self)
303 self.assert_(self._empty_mapping() is not self._empty_mapping())
Walter Dörwald118f9312004-06-02 18:42:25 +0000304 self.assertEqual(self.type2test(x=1, y=2), {"x": 1, "y": 2})
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000305
306 def test_bool(self):
307 BasicTestMappingProtocol.test_bool(self)
308 self.assert_(not self._empty_mapping())
309 self.assert_(self._full_mapping({"x": "y"}))
310 self.assert_(bool(self._empty_mapping()) is False)
311 self.assert_(bool(self._full_mapping({"x": "y"})) is True)
312
313 def test_keys(self):
314 BasicTestMappingProtocol.test_keys(self)
315 d = self._empty_mapping()
316 self.assertEqual(d.keys(), [])
317 d = self._full_mapping({'a': 1, 'b': 2})
318 k = d.keys()
319 self.assert_('a' in k)
320 self.assert_('b' in k)
321 self.assert_('c' not in k)
322
323 def test_values(self):
324 BasicTestMappingProtocol.test_values(self)
325 d = self._full_mapping({1:2})
326 self.assertEqual(d.values(), [2])
327
328 def test_items(self):
329 BasicTestMappingProtocol.test_items(self)
330
331 d = self._full_mapping({1:2})
332 self.assertEqual(d.items(), [(1, 2)])
333
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000334 def test_contains(self):
335 d = self._empty_mapping()
336 self.assert_(not ('a' in d))
337 self.assert_('a' not in d)
338 d = self._full_mapping({'a': 1, 'b': 2})
339 self.assert_('a' in d)
340 self.assert_('b' in d)
341 self.assert_('c' not in d)
342
343 self.assertRaises(TypeError, d.__contains__)
344
345 def test_len(self):
346 BasicTestMappingProtocol.test_len(self)
347 d = self._full_mapping({'a': 1, 'b': 2})
348 self.assertEqual(len(d), 2)
349
350 def test_getitem(self):
351 BasicTestMappingProtocol.test_getitem(self)
352 d = self._full_mapping({'a': 1, 'b': 2})
353 self.assertEqual(d['a'], 1)
354 self.assertEqual(d['b'], 2)
355 d['c'] = 3
356 d['a'] = 4
357 self.assertEqual(d['c'], 3)
358 self.assertEqual(d['a'], 4)
359 del d['b']
360 self.assertEqual(d, {'a': 4, 'c': 3})
361
362 self.assertRaises(TypeError, d.__getitem__)
363
364 def test_clear(self):
365 d = self._full_mapping({1:1, 2:2, 3:3})
366 d.clear()
367 self.assertEqual(d, {})
368
369 self.assertRaises(TypeError, d.clear, None)
370
371 def test_update(self):
372 BasicTestMappingProtocol.test_update(self)
373 # mapping argument
374 d = self._empty_mapping()
375 d.update({1:100})
376 d.update({2:20})
377 d.update({1:1, 2:2, 3:3})
378 self.assertEqual(d, {1:1, 2:2, 3:3})
379
380 # no argument
381 d.update()
382 self.assertEqual(d, {1:1, 2:2, 3:3})
383
384 # keyword arguments
385 d = self._empty_mapping()
386 d.update(x=100)
387 d.update(y=20)
388 d.update(x=1, y=2, z=3)
389 self.assertEqual(d, {"x":1, "y":2, "z":3})
390
391 # item sequence
392 d = self._empty_mapping()
393 d.update([("x", 100), ("y", 20)])
394 self.assertEqual(d, {"x":100, "y":20})
395
396 # Both item sequence and keyword arguments
397 d = self._empty_mapping()
398 d.update([("x", 100), ("y", 20)], x=1, y=2)
399 self.assertEqual(d, {"x":1, "y":2})
400
401 # iterator
402 d = self._full_mapping({1:3, 2:4})
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000403 d.update(self._full_mapping({1:2, 3:4, 5:6}).items())
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000404 self.assertEqual(d, {1:2, 2:4, 3:4, 5:6})
405
406 class SimpleUserDict:
407 def __init__(self):
408 self.d = {1:1, 2:2, 3:3}
409 def keys(self):
410 return self.d.keys()
411 def __getitem__(self, i):
412 return self.d[i]
413 d.clear()
414 d.update(SimpleUserDict())
415 self.assertEqual(d, {1:1, 2:2, 3:3})
416
417 def test_fromkeys(self):
Walter Dörwald118f9312004-06-02 18:42:25 +0000418 self.assertEqual(self.type2test.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000419 d = self._empty_mapping()
420 self.assert_(not(d.fromkeys('abc') is d))
421 self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
422 self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0})
423 self.assertEqual(d.fromkeys([]), {})
424 def g():
425 yield 1
426 self.assertEqual(d.fromkeys(g()), {1:None})
427 self.assertRaises(TypeError, {}.fromkeys, 3)
Walter Dörwald118f9312004-06-02 18:42:25 +0000428 class dictlike(self.type2test): pass
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000429 self.assertEqual(dictlike.fromkeys('a'), {'a':None})
430 self.assertEqual(dictlike().fromkeys('a'), {'a':None})
431 self.assert_(dictlike.fromkeys('a').__class__ is dictlike)
432 self.assert_(dictlike().fromkeys('a').__class__ is dictlike)
433 # FIXME: the following won't work with UserDict, because it's an old style class
434 # self.assert_(type(dictlike.fromkeys('a')) is dictlike)
Walter Dörwald118f9312004-06-02 18:42:25 +0000435 class mydict(self.type2test):
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000436 def __new__(cls):
437 return UserDict.UserDict()
438 ud = mydict.fromkeys('ab')
439 self.assertEqual(ud, {'a':None, 'b':None})
440 # FIXME: the following won't work with UserDict, because it's an old style class
441 # self.assert_(isinstance(ud, UserDict.UserDict))
442 self.assertRaises(TypeError, dict.fromkeys)
443
444 class Exc(Exception): pass
445
Walter Dörwald118f9312004-06-02 18:42:25 +0000446 class baddict1(self.type2test):
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000447 def __init__(self):
448 raise Exc()
449
450 self.assertRaises(Exc, baddict1.fromkeys, [1])
451
452 class BadSeq(object):
453 def __iter__(self):
454 return self
455 def next(self):
456 raise Exc()
457
Walter Dörwald118f9312004-06-02 18:42:25 +0000458 self.assertRaises(Exc, self.type2test.fromkeys, BadSeq())
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000459
Walter Dörwald118f9312004-06-02 18:42:25 +0000460 class baddict2(self.type2test):
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000461 def __setitem__(self, key, value):
462 raise Exc()
463
464 self.assertRaises(Exc, baddict2.fromkeys, [1])
465
466 def test_copy(self):
467 d = self._full_mapping({1:1, 2:2, 3:3})
468 self.assertEqual(d.copy(), {1:1, 2:2, 3:3})
469 d = self._empty_mapping()
470 self.assertEqual(d.copy(), d)
471 self.assert_(isinstance(d.copy(), d.__class__))
472 self.assertRaises(TypeError, d.copy, None)
473
474 def test_get(self):
475 BasicTestMappingProtocol.test_get(self)
476 d = self._empty_mapping()
477 self.assert_(d.get('c') is None)
478 self.assertEqual(d.get('c', 3), 3)
479 d = self._full_mapping({'a' : 1, 'b' : 2})
480 self.assert_(d.get('c') is None)
481 self.assertEqual(d.get('c', 3), 3)
482 self.assertEqual(d.get('a'), 1)
483 self.assertEqual(d.get('a', 3), 1)
484
485 def test_setdefault(self):
486 BasicTestMappingProtocol.test_setdefault(self)
487 d = self._empty_mapping()
488 self.assert_(d.setdefault('key0') is None)
489 d.setdefault('key0', [])
490 self.assert_(d.setdefault('key0') is None)
491 d.setdefault('key', []).append(3)
492 self.assertEqual(d['key'][0], 3)
493 d.setdefault('key', []).append(4)
494 self.assertEqual(len(d['key']), 2)
495
496 def test_popitem(self):
497 BasicTestMappingProtocol.test_popitem(self)
498 for copymode in -1, +1:
499 # -1: b has same structure as a
500 # +1: b is a.copy()
501 for log2size in range(12):
502 size = 2**log2size
503 a = self._empty_mapping()
504 b = self._empty_mapping()
505 for i in range(size):
506 a[repr(i)] = i
507 if copymode < 0:
508 b[repr(i)] = i
509 if copymode > 0:
510 b = a.copy()
511 for i in range(size):
512 ka, va = ta = a.popitem()
513 self.assertEqual(va, int(ka))
514 kb, vb = tb = b.popitem()
515 self.assertEqual(vb, int(kb))
516 self.assert_(not(copymode < 0 and ta != tb))
517 self.assert_(not a)
518 self.assert_(not b)
519
520 def test_pop(self):
521 BasicTestMappingProtocol.test_pop(self)
522
523 # Tests for pop with specified key
524 d = self._empty_mapping()
525 k, v = 'abc', 'def'
526
527 # verify longs/ints get same value when key > 32 bits (for 64-bit archs)
528 # see SF bug #689659
Guido van Rossume2a383d2007-01-15 16:59:06 +0000529 x = 4503599627370496
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000530 y = 4503599627370496
531 h = self._full_mapping({x: 'anything', y: 'something else'})
532 self.assertEqual(h[x], h[y])
533
534 self.assertEqual(d.pop(k, v), v)
535 d[k] = v
536 self.assertEqual(d.pop(k, 1), v)
537
538
539class TestHashMappingProtocol(TestMappingProtocol):
540
541 def test_getitem(self):
542 TestMappingProtocol.test_getitem(self)
543 class Exc(Exception): pass
544
545 class BadEq(object):
546 def __eq__(self, other):
547 raise Exc()
Guido van Rossum38938152006-08-21 23:36:26 +0000548 def __hash__(self):
549 return 24
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000550
551 d = self._empty_mapping()
552 d[BadEq()] = 42
553 self.assertRaises(KeyError, d.__getitem__, 23)
554
555 class BadHash(object):
556 fail = False
557 def __hash__(self):
558 if self.fail:
559 raise Exc()
560 else:
561 return 42
562
563 d = self._empty_mapping()
564 x = BadHash()
565 d[x] = 42
566 x.fail = True
567 self.assertRaises(Exc, d.__getitem__, x)
568
569 def test_fromkeys(self):
570 TestMappingProtocol.test_fromkeys(self)
Walter Dörwald118f9312004-06-02 18:42:25 +0000571 class mydict(self.type2test):
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000572 def __new__(cls):
573 return UserDict.UserDict()
574 ud = mydict.fromkeys('ab')
575 self.assertEqual(ud, {'a':None, 'b':None})
576 self.assert_(isinstance(ud, UserDict.UserDict))
577
578 def test_pop(self):
579 TestMappingProtocol.test_pop(self)
580
581 class Exc(Exception): pass
582
583 class BadHash(object):
584 fail = False
585 def __hash__(self):
586 if self.fail:
587 raise Exc()
588 else:
589 return 42
590
591 d = self._empty_mapping()
592 x = BadHash()
593 d[x] = 42
594 x.fail = True
595 self.assertRaises(Exc, d.pop, x)
596
597 def test_mutatingiteration(self):
598 d = self._empty_mapping()
599 d[1] = 1
600 try:
601 for i in d:
602 d[i+1] = 1
603 except RuntimeError:
604 pass
605 else:
606 self.fail("changing dict size during iteration doesn't raise Error")
607
608 def test_repr(self):
609 d = self._empty_mapping()
610 self.assertEqual(repr(d), '{}')
611 d[1] = 2
612 self.assertEqual(repr(d), '{1: 2}')
613 d = self._empty_mapping()
614 d[1] = d
615 self.assertEqual(repr(d), '{1: {...}}')
616
617 class Exc(Exception): pass
618
619 class BadRepr(object):
620 def __repr__(self):
621 raise Exc()
622
623 d = self._full_mapping({1: BadRepr()})
624 self.assertRaises(Exc, repr, d)
625
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000626 def test_eq(self):
627 self.assertEqual(self._empty_mapping(), self._empty_mapping())
628 self.assertEqual(self._full_mapping({1: 2}),
Guido van Rossume2a383d2007-01-15 16:59:06 +0000629 self._full_mapping({1: 2}))
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000630
631 class Exc(Exception): pass
632
633 class BadCmp(object):
634 def __eq__(self, other):
635 raise Exc()
Guido van Rossum38938152006-08-21 23:36:26 +0000636 def __hash__(self):
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000637 return 1
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000638
639 d1 = self._full_mapping({BadCmp(): 1})
640 d2 = self._full_mapping({1: 1})
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000641 self.assertRaises(Exc, lambda: BadCmp()==1)
642 self.assertRaises(Exc, lambda: d1==d2)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000643
644 def test_setdefault(self):
645 TestMappingProtocol.test_setdefault(self)
646
647 class Exc(Exception): pass
648
649 class BadHash(object):
650 fail = False
651 def __hash__(self):
652 if self.fail:
653 raise Exc()
654 else:
655 return 42
656
657 d = self._empty_mapping()
658 x = BadHash()
659 d[x] = 42
660 x.fail = True
661 self.assertRaises(Exc, d.setdefault, x, [])