blob: f43750bb83f62c2962b157241a54fc4232a0c150 [file] [log] [blame]
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +00001# tests common to dict and UserDict
2import unittest
3import UserDict
Florent Xicluna07627882010-03-21 01:14:24 +00004import test_support
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +00005
6
7class BasicTestMappingProtocol(unittest.TestCase):
8 # This base class can be used to check that an object conforms to the
9 # mapping protocol
10
11 # Functions that can be useful to override to adapt to dictionary
12 # semantics
Walter Dörwald118f9312004-06-02 18:42:25 +000013 type2test = None # which class is being tested (overwrite in subclasses)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000014
15 def _reference(self):
16 """Return a dictionary of values which are invariant by storage
17 in the object under test."""
18 return {1:2, "key1":"value1", "key2":(1,2,3)}
19 def _empty_mapping(self):
20 """Return an empty mapping object"""
Walter Dörwald118f9312004-06-02 18:42:25 +000021 return self.type2test()
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000022 def _full_mapping(self, data):
23 """Return a mapping object with the value contained in data
24 dictionary"""
25 x = self._empty_mapping()
26 for key, value in data.items():
27 x[key] = value
28 return x
29
30 def __init__(self, *args, **kw):
31 unittest.TestCase.__init__(self, *args, **kw)
32 self.reference = self._reference().copy()
33
34 # A (key, value) pair not in the mapping
35 key, value = self.reference.popitem()
36 self.other = {key:value}
37
38 # A (key, value) pair in the mapping
39 key, value = self.reference.popitem()
40 self.inmapping = {key:value}
41 self.reference[key] = value
42
43 def test_read(self):
44 # Test for read only operations on mapping
45 p = self._empty_mapping()
46 p1 = dict(p) #workaround for singleton objects
47 d = self._full_mapping(self.reference)
48 if d is p:
49 p = p1
50 #Indexing
51 for key, value in self.reference.items():
52 self.assertEqual(d[key], value)
53 knownkey = self.other.keys()[0]
Benjamin Peterson5c8da862009-06-30 22:57:08 +000054 self.assertRaises(KeyError, lambda:d[knownkey])
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000055 #len
56 self.assertEqual(len(p), 0)
57 self.assertEqual(len(d), len(self.reference))
Florent Xicluna07627882010-03-21 01:14:24 +000058 #in
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000059 for k in self.reference:
Ezio Melottiaa980582010-01-23 23:04:36 +000060 self.assertIn(k, d)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000061 for k in self.other:
Ezio Melottiaa980582010-01-23 23:04:36 +000062 self.assertNotIn(k, d)
Florent Xicluna07627882010-03-21 01:14:24 +000063 #has_key
64 with test_support.check_py3k_warnings(quiet=True):
65 for k in self.reference:
66 self.assertTrue(d.has_key(k))
67 for k in self.other:
68 self.assertFalse(d.has_key(k))
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000069 #cmp
70 self.assertEqual(cmp(p,p), 0)
71 self.assertEqual(cmp(d,d), 0)
72 self.assertEqual(cmp(p,d), -1)
73 self.assertEqual(cmp(d,p), 1)
74 #__non__zero__
75 if p: self.fail("Empty mapping must compare to False")
76 if not d: self.fail("Full mapping must compare to True")
77 # keys(), items(), iterkeys() ...
78 def check_iterandlist(iter, lst, ref):
Benjamin Peterson5c8da862009-06-30 22:57:08 +000079 self.assertTrue(hasattr(iter, 'next'))
80 self.assertTrue(hasattr(iter, '__iter__'))
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000081 x = list(iter)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000082 self.assertTrue(set(x)==set(lst)==set(ref))
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000083 check_iterandlist(d.iterkeys(), d.keys(), self.reference.keys())
84 check_iterandlist(iter(d), d.keys(), self.reference.keys())
85 check_iterandlist(d.itervalues(), d.values(), self.reference.values())
86 check_iterandlist(d.iteritems(), d.items(), self.reference.items())
87 #get
88 key, value = d.iteritems().next()
89 knownkey, knownvalue = self.other.iteritems().next()
90 self.assertEqual(d.get(key, knownvalue), value)
91 self.assertEqual(d.get(knownkey, knownvalue), knownvalue)
Ezio Melottiaa980582010-01-23 23:04:36 +000092 self.assertNotIn(knownkey, d)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +000093
94 def test_write(self):
95 # Test for write operations on mapping
96 p = self._empty_mapping()
97 #Indexing
98 for key, value in self.reference.items():
99 p[key] = value
100 self.assertEqual(p[key], value)
101 for key in self.reference.keys():
102 del p[key]
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000103 self.assertRaises(KeyError, lambda:p[key])
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000104 p = self._empty_mapping()
105 #update
106 p.update(self.reference)
107 self.assertEqual(dict(p), self.reference)
108 items = p.items()
109 p = self._empty_mapping()
110 p.update(items)
111 self.assertEqual(dict(p), self.reference)
112 d = self._full_mapping(self.reference)
113 #setdefault
114 key, value = d.iteritems().next()
115 knownkey, knownvalue = self.other.iteritems().next()
116 self.assertEqual(d.setdefault(key, knownvalue), value)
117 self.assertEqual(d[key], value)
118 self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue)
119 self.assertEqual(d[knownkey], knownvalue)
120 #pop
121 self.assertEqual(d.pop(knownkey), knownvalue)
Ezio Melottiaa980582010-01-23 23:04:36 +0000122 self.assertNotIn(knownkey, d)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000123 self.assertRaises(KeyError, d.pop, knownkey)
124 default = 909
125 d[knownkey] = knownvalue
126 self.assertEqual(d.pop(knownkey, default), knownvalue)
Ezio Melottiaa980582010-01-23 23:04:36 +0000127 self.assertNotIn(knownkey, d)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000128 self.assertEqual(d.pop(knownkey, default), default)
129 #popitem
130 key, value = d.popitem()
Ezio Melottiaa980582010-01-23 23:04:36 +0000131 self.assertNotIn(key, d)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000132 self.assertEqual(value, self.reference[key])
133 p=self._empty_mapping()
134 self.assertRaises(KeyError, p.popitem)
135
136 def test_constructor(self):
137 self.assertEqual(self._empty_mapping(), self._empty_mapping())
138
139 def test_bool(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000140 self.assertTrue(not self._empty_mapping())
141 self.assertTrue(self.reference)
142 self.assertTrue(bool(self._empty_mapping()) is False)
143 self.assertTrue(bool(self.reference) is True)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000144
145 def test_keys(self):
146 d = self._empty_mapping()
147 self.assertEqual(d.keys(), [])
148 d = self.reference
Ezio Melottiaa980582010-01-23 23:04:36 +0000149 self.assertIn(self.inmapping.keys()[0], d.keys())
150 self.assertNotIn(self.other.keys()[0], d.keys())
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000151 self.assertRaises(TypeError, d.keys, None)
152
153 def test_values(self):
154 d = self._empty_mapping()
155 self.assertEqual(d.values(), [])
156
157 self.assertRaises(TypeError, d.values, None)
158
159 def test_items(self):
160 d = self._empty_mapping()
161 self.assertEqual(d.items(), [])
162
163 self.assertRaises(TypeError, d.items, None)
164
165 def test_len(self):
166 d = self._empty_mapping()
167 self.assertEqual(len(d), 0)
168
169 def test_getitem(self):
170 d = self.reference
171 self.assertEqual(d[self.inmapping.keys()[0]], self.inmapping.values()[0])
172
173 self.assertRaises(TypeError, d.__getitem__)
174
175 def test_update(self):
176 # mapping argument
177 d = self._empty_mapping()
178 d.update(self.other)
179 self.assertEqual(d.items(), self.other.items())
180
181 # No argument
182 d = self._empty_mapping()
183 d.update()
184 self.assertEqual(d, self._empty_mapping())
185
186 # item sequence
187 d = self._empty_mapping()
188 d.update(self.other.items())
189 self.assertEqual(d.items(), self.other.items())
190
191 # Iterator
192 d = self._empty_mapping()
193 d.update(self.other.iteritems())
194 self.assertEqual(d.items(), self.other.items())
195
196 # FIXME: Doesn't work with UserDict
197 # self.assertRaises((TypeError, AttributeError), d.update, None)
198 self.assertRaises((TypeError, AttributeError), d.update, 42)
199
200 outerself = self
201 class SimpleUserDict:
202 def __init__(self):
203 self.d = outerself.reference
204 def keys(self):
205 return self.d.keys()
206 def __getitem__(self, i):
207 return self.d[i]
208 d.clear()
209 d.update(SimpleUserDict())
210 i1 = d.items()
211 i2 = self.reference.items()
Antoine Pitrou93291532012-02-22 00:28:46 +0100212
213 def safe_sort_key(kv):
214 k, v = kv
215 return id(type(k)), id(type(v)), k, v
216 i1.sort(key=safe_sort_key)
217 i2.sort(key=safe_sort_key)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000218 self.assertEqual(i1, i2)
219
220 class Exc(Exception): pass
221
222 d = self._empty_mapping()
223 class FailingUserDict:
224 def keys(self):
225 raise Exc
226 self.assertRaises(Exc, d.update, FailingUserDict())
227
228 d.clear()
229
230 class FailingUserDict:
231 def keys(self):
232 class BogonIter:
233 def __init__(self):
234 self.i = 1
235 def __iter__(self):
236 return self
237 def next(self):
238 if self.i:
239 self.i = 0
240 return 'a'
241 raise Exc
242 return BogonIter()
243 def __getitem__(self, key):
244 return key
245 self.assertRaises(Exc, d.update, FailingUserDict())
246
247 class FailingUserDict:
248 def keys(self):
249 class BogonIter:
250 def __init__(self):
251 self.i = ord('a')
252 def __iter__(self):
253 return self
254 def next(self):
255 if self.i <= ord('z'):
256 rtn = chr(self.i)
257 self.i += 1
258 return rtn
259 raise StopIteration
260 return BogonIter()
261 def __getitem__(self, key):
262 raise Exc
263 self.assertRaises(Exc, d.update, FailingUserDict())
264
265 d = self._empty_mapping()
266 class badseq(object):
267 def __iter__(self):
268 return self
269 def next(self):
270 raise Exc()
271
272 self.assertRaises(Exc, d.update, badseq())
273
274 self.assertRaises(ValueError, d.update, [(1, 2, 3)])
275
276 # no test_fromkeys or test_copy as both os.environ and selves don't support it
277
278 def test_get(self):
279 d = self._empty_mapping()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000280 self.assertTrue(d.get(self.other.keys()[0]) is None)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000281 self.assertEqual(d.get(self.other.keys()[0], 3), 3)
282 d = self.reference
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000283 self.assertTrue(d.get(self.other.keys()[0]) is None)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000284 self.assertEqual(d.get(self.other.keys()[0], 3), 3)
285 self.assertEqual(d.get(self.inmapping.keys()[0]), self.inmapping.values()[0])
286 self.assertEqual(d.get(self.inmapping.keys()[0], 3), self.inmapping.values()[0])
287 self.assertRaises(TypeError, d.get)
288 self.assertRaises(TypeError, d.get, None, None, None)
289
290 def test_setdefault(self):
291 d = self._empty_mapping()
292 self.assertRaises(TypeError, d.setdefault)
293
294 def test_popitem(self):
295 d = self._empty_mapping()
296 self.assertRaises(KeyError, d.popitem)
297 self.assertRaises(TypeError, d.popitem, 42)
298
299 def test_pop(self):
300 d = self._empty_mapping()
301 k, v = self.inmapping.items()[0]
302 d[k] = v
303 self.assertRaises(KeyError, d.pop, self.other.keys()[0])
304
305 self.assertEqual(d.pop(k), v)
306 self.assertEqual(len(d), 0)
307
308 self.assertRaises(KeyError, d.pop, k)
309
310
311class TestMappingProtocol(BasicTestMappingProtocol):
312 def test_constructor(self):
313 BasicTestMappingProtocol.test_constructor(self)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000314 self.assertTrue(self._empty_mapping() is not self._empty_mapping())
Walter Dörwald118f9312004-06-02 18:42:25 +0000315 self.assertEqual(self.type2test(x=1, y=2), {"x": 1, "y": 2})
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000316
317 def test_bool(self):
318 BasicTestMappingProtocol.test_bool(self)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000319 self.assertTrue(not self._empty_mapping())
320 self.assertTrue(self._full_mapping({"x": "y"}))
321 self.assertTrue(bool(self._empty_mapping()) is False)
322 self.assertTrue(bool(self._full_mapping({"x": "y"})) is True)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000323
324 def test_keys(self):
325 BasicTestMappingProtocol.test_keys(self)
326 d = self._empty_mapping()
327 self.assertEqual(d.keys(), [])
328 d = self._full_mapping({'a': 1, 'b': 2})
329 k = d.keys()
Ezio Melottiaa980582010-01-23 23:04:36 +0000330 self.assertIn('a', k)
331 self.assertIn('b', k)
332 self.assertNotIn('c', k)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000333
334 def test_values(self):
335 BasicTestMappingProtocol.test_values(self)
336 d = self._full_mapping({1:2})
337 self.assertEqual(d.values(), [2])
338
339 def test_items(self):
340 BasicTestMappingProtocol.test_items(self)
341
342 d = self._full_mapping({1:2})
343 self.assertEqual(d.items(), [(1, 2)])
344
345 def test_has_key(self):
346 d = self._empty_mapping()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000347 self.assertTrue(not d.has_key('a'))
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000348 d = self._full_mapping({'a': 1, 'b': 2})
349 k = d.keys()
Antoine Pitrou93291532012-02-22 00:28:46 +0100350 k.sort(key=lambda k: (id(type(k)), k))
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000351 self.assertEqual(k, ['a', 'b'])
352
353 self.assertRaises(TypeError, d.has_key)
354
355 def test_contains(self):
356 d = self._empty_mapping()
Ezio Melottiaa980582010-01-23 23:04:36 +0000357 self.assertNotIn('a', d)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000358 self.assertTrue(not ('a' in d))
359 self.assertTrue('a' not in d)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000360 d = self._full_mapping({'a': 1, 'b': 2})
Ezio Melottiaa980582010-01-23 23:04:36 +0000361 self.assertIn('a', d)
362 self.assertIn('b', d)
363 self.assertNotIn('c', d)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000364
365 self.assertRaises(TypeError, d.__contains__)
366
367 def test_len(self):
368 BasicTestMappingProtocol.test_len(self)
369 d = self._full_mapping({'a': 1, 'b': 2})
370 self.assertEqual(len(d), 2)
371
372 def test_getitem(self):
373 BasicTestMappingProtocol.test_getitem(self)
374 d = self._full_mapping({'a': 1, 'b': 2})
375 self.assertEqual(d['a'], 1)
376 self.assertEqual(d['b'], 2)
377 d['c'] = 3
378 d['a'] = 4
379 self.assertEqual(d['c'], 3)
380 self.assertEqual(d['a'], 4)
381 del d['b']
382 self.assertEqual(d, {'a': 4, 'c': 3})
383
384 self.assertRaises(TypeError, d.__getitem__)
385
386 def test_clear(self):
387 d = self._full_mapping({1:1, 2:2, 3:3})
388 d.clear()
389 self.assertEqual(d, {})
390
391 self.assertRaises(TypeError, d.clear, None)
392
393 def test_update(self):
394 BasicTestMappingProtocol.test_update(self)
395 # mapping argument
396 d = self._empty_mapping()
397 d.update({1:100})
398 d.update({2:20})
399 d.update({1:1, 2:2, 3:3})
400 self.assertEqual(d, {1:1, 2:2, 3:3})
401
402 # no argument
403 d.update()
404 self.assertEqual(d, {1:1, 2:2, 3:3})
405
406 # keyword arguments
407 d = self._empty_mapping()
408 d.update(x=100)
409 d.update(y=20)
410 d.update(x=1, y=2, z=3)
411 self.assertEqual(d, {"x":1, "y":2, "z":3})
412
413 # item sequence
414 d = self._empty_mapping()
415 d.update([("x", 100), ("y", 20)])
416 self.assertEqual(d, {"x":100, "y":20})
417
418 # Both item sequence and keyword arguments
419 d = self._empty_mapping()
420 d.update([("x", 100), ("y", 20)], x=1, y=2)
421 self.assertEqual(d, {"x":1, "y":2})
422
423 # iterator
424 d = self._full_mapping({1:3, 2:4})
425 d.update(self._full_mapping({1:2, 3:4, 5:6}).iteritems())
426 self.assertEqual(d, {1:2, 2:4, 3:4, 5:6})
427
428 class SimpleUserDict:
429 def __init__(self):
430 self.d = {1:1, 2:2, 3:3}
431 def keys(self):
432 return self.d.keys()
433 def __getitem__(self, i):
434 return self.d[i]
435 d.clear()
436 d.update(SimpleUserDict())
437 self.assertEqual(d, {1:1, 2:2, 3:3})
438
439 def test_fromkeys(self):
Walter Dörwald118f9312004-06-02 18:42:25 +0000440 self.assertEqual(self.type2test.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000441 d = self._empty_mapping()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000442 self.assertTrue(not(d.fromkeys('abc') is d))
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000443 self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
444 self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0})
445 self.assertEqual(d.fromkeys([]), {})
446 def g():
447 yield 1
448 self.assertEqual(d.fromkeys(g()), {1:None})
449 self.assertRaises(TypeError, {}.fromkeys, 3)
Walter Dörwald118f9312004-06-02 18:42:25 +0000450 class dictlike(self.type2test): pass
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000451 self.assertEqual(dictlike.fromkeys('a'), {'a':None})
452 self.assertEqual(dictlike().fromkeys('a'), {'a':None})
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000453 self.assertTrue(dictlike.fromkeys('a').__class__ is dictlike)
454 self.assertTrue(dictlike().fromkeys('a').__class__ is dictlike)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000455 # FIXME: the following won't work with UserDict, because it's an old style class
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000456 # self.assertTrue(type(dictlike.fromkeys('a')) is dictlike)
Walter Dörwald118f9312004-06-02 18:42:25 +0000457 class mydict(self.type2test):
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000458 def __new__(cls):
459 return UserDict.UserDict()
460 ud = mydict.fromkeys('ab')
461 self.assertEqual(ud, {'a':None, 'b':None})
462 # FIXME: the following won't work with UserDict, because it's an old style class
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000463 # self.assertIsInstance(ud, UserDict.UserDict)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000464 self.assertRaises(TypeError, dict.fromkeys)
465
466 class Exc(Exception): pass
467
Walter Dörwald118f9312004-06-02 18:42:25 +0000468 class baddict1(self.type2test):
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000469 def __init__(self):
470 raise Exc()
471
472 self.assertRaises(Exc, baddict1.fromkeys, [1])
473
474 class BadSeq(object):
475 def __iter__(self):
476 return self
477 def next(self):
478 raise Exc()
479
Walter Dörwald118f9312004-06-02 18:42:25 +0000480 self.assertRaises(Exc, self.type2test.fromkeys, BadSeq())
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000481
Walter Dörwald118f9312004-06-02 18:42:25 +0000482 class baddict2(self.type2test):
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000483 def __setitem__(self, key, value):
484 raise Exc()
485
486 self.assertRaises(Exc, baddict2.fromkeys, [1])
487
488 def test_copy(self):
489 d = self._full_mapping({1:1, 2:2, 3:3})
490 self.assertEqual(d.copy(), {1:1, 2:2, 3:3})
491 d = self._empty_mapping()
492 self.assertEqual(d.copy(), d)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000493 self.assertIsInstance(d.copy(), d.__class__)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000494 self.assertRaises(TypeError, d.copy, None)
495
496 def test_get(self):
497 BasicTestMappingProtocol.test_get(self)
498 d = self._empty_mapping()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000499 self.assertTrue(d.get('c') is None)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000500 self.assertEqual(d.get('c', 3), 3)
501 d = self._full_mapping({'a' : 1, 'b' : 2})
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000502 self.assertTrue(d.get('c') is None)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000503 self.assertEqual(d.get('c', 3), 3)
504 self.assertEqual(d.get('a'), 1)
505 self.assertEqual(d.get('a', 3), 1)
506
507 def test_setdefault(self):
508 BasicTestMappingProtocol.test_setdefault(self)
509 d = self._empty_mapping()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000510 self.assertTrue(d.setdefault('key0') is None)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000511 d.setdefault('key0', [])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000512 self.assertTrue(d.setdefault('key0') is None)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000513 d.setdefault('key', []).append(3)
514 self.assertEqual(d['key'][0], 3)
515 d.setdefault('key', []).append(4)
516 self.assertEqual(len(d['key']), 2)
517
518 def test_popitem(self):
519 BasicTestMappingProtocol.test_popitem(self)
520 for copymode in -1, +1:
521 # -1: b has same structure as a
522 # +1: b is a.copy()
523 for log2size in range(12):
524 size = 2**log2size
525 a = self._empty_mapping()
526 b = self._empty_mapping()
527 for i in range(size):
528 a[repr(i)] = i
529 if copymode < 0:
530 b[repr(i)] = i
531 if copymode > 0:
532 b = a.copy()
533 for i in range(size):
534 ka, va = ta = a.popitem()
535 self.assertEqual(va, int(ka))
536 kb, vb = tb = b.popitem()
537 self.assertEqual(vb, int(kb))
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000538 self.assertTrue(not(copymode < 0 and ta != tb))
539 self.assertTrue(not a)
540 self.assertTrue(not b)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000541
542 def test_pop(self):
543 BasicTestMappingProtocol.test_pop(self)
544
545 # Tests for pop with specified key
546 d = self._empty_mapping()
547 k, v = 'abc', 'def'
548
549 # verify longs/ints get same value when key > 32 bits (for 64-bit archs)
550 # see SF bug #689659
551 x = 4503599627370496L
552 y = 4503599627370496
553 h = self._full_mapping({x: 'anything', y: 'something else'})
554 self.assertEqual(h[x], h[y])
555
556 self.assertEqual(d.pop(k, v), v)
557 d[k] = v
558 self.assertEqual(d.pop(k, 1), v)
559
560
561class TestHashMappingProtocol(TestMappingProtocol):
562
563 def test_getitem(self):
564 TestMappingProtocol.test_getitem(self)
565 class Exc(Exception): pass
566
567 class BadEq(object):
568 def __eq__(self, other):
569 raise Exc()
Guido van Rossum64c06e32007-11-22 00:55:51 +0000570 def __hash__(self):
571 return 24
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000572
573 d = self._empty_mapping()
574 d[BadEq()] = 42
575 self.assertRaises(KeyError, d.__getitem__, 23)
576
577 class BadHash(object):
578 fail = False
579 def __hash__(self):
580 if self.fail:
581 raise Exc()
582 else:
583 return 42
584
585 d = self._empty_mapping()
586 x = BadHash()
587 d[x] = 42
588 x.fail = True
589 self.assertRaises(Exc, d.__getitem__, x)
590
591 def test_fromkeys(self):
592 TestMappingProtocol.test_fromkeys(self)
Walter Dörwald118f9312004-06-02 18:42:25 +0000593 class mydict(self.type2test):
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000594 def __new__(cls):
595 return UserDict.UserDict()
596 ud = mydict.fromkeys('ab')
597 self.assertEqual(ud, {'a':None, 'b':None})
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000598 self.assertIsInstance(ud, UserDict.UserDict)
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000599
600 def test_pop(self):
601 TestMappingProtocol.test_pop(self)
602
603 class Exc(Exception): pass
604
605 class BadHash(object):
606 fail = False
607 def __hash__(self):
608 if self.fail:
609 raise Exc()
610 else:
611 return 42
612
613 d = self._empty_mapping()
614 x = BadHash()
615 d[x] = 42
616 x.fail = True
617 self.assertRaises(Exc, d.pop, x)
618
619 def test_mutatingiteration(self):
620 d = self._empty_mapping()
621 d[1] = 1
622 try:
623 for i in d:
624 d[i+1] = 1
625 except RuntimeError:
626 pass
627 else:
628 self.fail("changing dict size during iteration doesn't raise Error")
629
630 def test_repr(self):
631 d = self._empty_mapping()
632 self.assertEqual(repr(d), '{}')
633 d[1] = 2
634 self.assertEqual(repr(d), '{1: 2}')
635 d = self._empty_mapping()
636 d[1] = d
637 self.assertEqual(repr(d), '{1: {...}}')
638
639 class Exc(Exception): pass
640
641 class BadRepr(object):
642 def __repr__(self):
643 raise Exc()
644
645 d = self._full_mapping({1: BadRepr()})
646 self.assertRaises(Exc, repr, d)
647
648 def test_le(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000649 self.assertTrue(not (self._empty_mapping() < self._empty_mapping()))
650 self.assertTrue(not (self._full_mapping({1: 2}) < self._full_mapping({1L: 2L})))
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000651
652 class Exc(Exception): pass
653
654 class BadCmp(object):
655 def __eq__(self, other):
656 raise Exc()
Guido van Rossum64c06e32007-11-22 00:55:51 +0000657 def __hash__(self):
658 return 42
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000659
660 d1 = self._full_mapping({BadCmp(): 1})
661 d2 = self._full_mapping({1: 1})
662 try:
663 d1 < d2
664 except Exc:
665 pass
666 else:
667 self.fail("< didn't raise Exc")
668
669 def test_setdefault(self):
670 TestMappingProtocol.test_setdefault(self)
671
672 class Exc(Exception): pass
673
674 class BadHash(object):
675 fail = False
676 def __hash__(self):
677 if self.fail:
678 raise Exc()
679 else:
680 return 42
681
682 d = self._empty_mapping()
683 x = BadHash()
684 d[x] = 42
685 x.fail = True
686 self.assertRaises(Exc, d.setdefault, x, [])