1 # tests common to dict and UserDict
6 class BasicTestMappingProtocol(unittest
.TestCase
):
7 # This base class can be used to check that an object conforms to the
10 # Functions that can be useful to override to adapt to dictionary
12 type2test
= None # which class is being tested (overwrite in subclasses)
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
24 x
= self
._empty
_mapping
()
25 for key
, value
in data
.items():
29 def __init__(self
, *args
, **kw
):
30 unittest
.TestCase
.__init
__(self
, *args
, **kw
)
31 self
.reference
= self
._reference
().copy()
33 # A (key, value) pair not in the mapping
34 key
, value
= self
.reference
.popitem()
35 self
.other
= {key
:value
}
37 # A (key, value) pair in the mapping
38 key
, value
= self
.reference
.popitem()
39 self
.inmapping
= {key
:value
}
40 self
.reference
[key
] = value
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
)
50 for key
, value
in self
.reference
.items():
51 self
.assertEqual(d
[key
], value
)
52 knownkey
= self
.other
.keys()[0]
53 self
.assertRaises(KeyError, lambda:d
[knownkey
])
55 self
.assertEqual(len(p
), 0)
56 self
.assertEqual(len(d
), len(self
.reference
))
58 for k
in self
.reference
:
59 self
.assertTrue(d
.has_key(k
))
60 self
.assertTrue(k
in d
)
62 self
.assertFalse(d
.has_key(k
))
63 self
.assertFalse(k
in d
)
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)
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
.assertTrue(hasattr(iter, 'next'))
75 self
.assertTrue(hasattr(iter, '__iter__'))
77 self
.assertTrue(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())
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
.assertFalse(knownkey
in d
)
90 # Test for write operations on mapping
91 p
= self
._empty
_mapping
()
93 for key
, value
in self
.reference
.items():
95 self
.assertEqual(p
[key
], value
)
96 for key
in self
.reference
.keys():
98 self
.assertRaises(KeyError, lambda:p
[key
])
99 p
= self
._empty
_mapping
()
101 p
.update(self
.reference
)
102 self
.assertEqual(dict(p
), self
.reference
)
104 p
= self
._empty
_mapping
()
106 self
.assertEqual(dict(p
), self
.reference
)
107 d
= self
._full
_mapping
(self
.reference
)
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
)
116 self
.assertEqual(d
.pop(knownkey
), knownvalue
)
117 self
.assertFalse(knownkey
in d
)
118 self
.assertRaises(KeyError, d
.pop
, knownkey
)
120 d
[knownkey
] = knownvalue
121 self
.assertEqual(d
.pop(knownkey
, default
), knownvalue
)
122 self
.assertFalse(knownkey
in d
)
123 self
.assertEqual(d
.pop(knownkey
, default
), default
)
125 key
, value
= d
.popitem()
126 self
.assertFalse(key
in d
)
127 self
.assertEqual(value
, self
.reference
[key
])
128 p
=self
._empty
_mapping
()
129 self
.assertRaises(KeyError, p
.popitem
)
131 def test_constructor(self
):
132 self
.assertEqual(self
._empty
_mapping
(), self
._empty
_mapping
())
135 self
.assertTrue(not self
._empty
_mapping
())
136 self
.assertTrue(self
.reference
)
137 self
.assertTrue(bool(self
._empty
_mapping
()) is False)
138 self
.assertTrue(bool(self
.reference
) is True)
141 d
= self
._empty
_mapping
()
142 self
.assertEqual(d
.keys(), [])
144 self
.assertTrue(self
.inmapping
.keys()[0] in d
.keys())
145 self
.assertTrue(self
.other
.keys()[0] not in d
.keys())
146 self
.assertRaises(TypeError, d
.keys
, None)
148 def test_values(self
):
149 d
= self
._empty
_mapping
()
150 self
.assertEqual(d
.values(), [])
152 self
.assertRaises(TypeError, d
.values
, None)
154 def test_items(self
):
155 d
= self
._empty
_mapping
()
156 self
.assertEqual(d
.items(), [])
158 self
.assertRaises(TypeError, d
.items
, None)
161 d
= self
._empty
_mapping
()
162 self
.assertEqual(len(d
), 0)
164 def test_getitem(self
):
166 self
.assertEqual(d
[self
.inmapping
.keys()[0]], self
.inmapping
.values()[0])
168 self
.assertRaises(TypeError, d
.__getitem
__)
170 def test_update(self
):
172 d
= self
._empty
_mapping
()
174 self
.assertEqual(d
.items(), self
.other
.items())
177 d
= self
._empty
_mapping
()
179 self
.assertEqual(d
, self
._empty
_mapping
())
182 d
= self
._empty
_mapping
()
183 d
.update(self
.other
.items())
184 self
.assertEqual(d
.items(), self
.other
.items())
187 d
= self
._empty
_mapping
()
188 d
.update(self
.other
.iteritems())
189 self
.assertEqual(d
.items(), self
.other
.items())
191 # FIXME: Doesn't work with UserDict
192 # self.assertRaises((TypeError, AttributeError), d.update, None)
193 self
.assertRaises((TypeError, AttributeError), d
.update
, 42)
196 class SimpleUserDict
:
198 self
.d
= outerself
.reference
201 def __getitem__(self
, i
):
204 d
.update(SimpleUserDict())
206 i2
= self
.reference
.items()
209 self
.assertEqual(i1
, i2
)
211 class Exc(Exception): pass
213 d
= self
._empty
_mapping
()
214 class FailingUserDict
:
217 self
.assertRaises(Exc
, d
.update
, FailingUserDict())
221 class FailingUserDict
:
234 def __getitem__(self
, key
):
236 self
.assertRaises(Exc
, d
.update
, FailingUserDict())
238 class FailingUserDict
:
246 if self
.i
<= ord('z'):
252 def __getitem__(self
, key
):
254 self
.assertRaises(Exc
, d
.update
, FailingUserDict())
256 d
= self
._empty
_mapping
()
257 class badseq(object):
263 self
.assertRaises(Exc
, d
.update
, badseq())
265 self
.assertRaises(ValueError, d
.update
, [(1, 2, 3)])
267 # no test_fromkeys or test_copy as both os.environ and selves don't support it
270 d
= self
._empty
_mapping
()
271 self
.assertTrue(d
.get(self
.other
.keys()[0]) is None)
272 self
.assertEqual(d
.get(self
.other
.keys()[0], 3), 3)
274 self
.assertTrue(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)
281 def test_setdefault(self
):
282 d
= self
._empty
_mapping
()
283 self
.assertRaises(TypeError, d
.setdefault
)
285 def test_popitem(self
):
286 d
= self
._empty
_mapping
()
287 self
.assertRaises(KeyError, d
.popitem
)
288 self
.assertRaises(TypeError, d
.popitem
, 42)
291 d
= self
._empty
_mapping
()
292 k
, v
= self
.inmapping
.items()[0]
294 self
.assertRaises(KeyError, d
.pop
, self
.other
.keys()[0])
296 self
.assertEqual(d
.pop(k
), v
)
297 self
.assertEqual(len(d
), 0)
299 self
.assertRaises(KeyError, d
.pop
, k
)
302 class TestMappingProtocol(BasicTestMappingProtocol
):
303 def test_constructor(self
):
304 BasicTestMappingProtocol
.test_constructor(self
)
305 self
.assertTrue(self
._empty
_mapping
() is not self
._empty
_mapping
())
306 self
.assertEqual(self
.type2test(x
=1, y
=2), {"x": 1, "y": 2})
309 BasicTestMappingProtocol
.test_bool(self
)
310 self
.assertTrue(not self
._empty
_mapping
())
311 self
.assertTrue(self
._full
_mapping
({"x": "y"}))
312 self
.assertTrue(bool(self
._empty
_mapping
()) is False)
313 self
.assertTrue(bool(self
._full
_mapping
({"x": "y"})) is True)
316 BasicTestMappingProtocol
.test_keys(self
)
317 d
= self
._empty
_mapping
()
318 self
.assertEqual(d
.keys(), [])
319 d
= self
._full
_mapping
({'a': 1, 'b': 2})
321 self
.assertTrue('a' in k
)
322 self
.assertTrue('b' in k
)
323 self
.assertTrue('c' not in k
)
325 def test_values(self
):
326 BasicTestMappingProtocol
.test_values(self
)
327 d
= self
._full
_mapping
({1:2})
328 self
.assertEqual(d
.values(), [2])
330 def test_items(self
):
331 BasicTestMappingProtocol
.test_items(self
)
333 d
= self
._full
_mapping
({1:2})
334 self
.assertEqual(d
.items(), [(1, 2)])
336 def test_has_key(self
):
337 d
= self
._empty
_mapping
()
338 self
.assertTrue(not d
.has_key('a'))
339 d
= self
._full
_mapping
({'a': 1, 'b': 2})
342 self
.assertEqual(k
, ['a', 'b'])
344 self
.assertRaises(TypeError, d
.has_key
)
346 def test_contains(self
):
347 d
= self
._empty
_mapping
()
348 self
.assertTrue(not ('a' in d
))
349 self
.assertTrue('a' not in d
)
350 d
= self
._full
_mapping
({'a': 1, 'b': 2})
351 self
.assertTrue('a' in d
)
352 self
.assertTrue('b' in d
)
353 self
.assertTrue('c' not in d
)
355 self
.assertRaises(TypeError, d
.__contains
__)
358 BasicTestMappingProtocol
.test_len(self
)
359 d
= self
._full
_mapping
({'a': 1, 'b': 2})
360 self
.assertEqual(len(d
), 2)
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)
369 self
.assertEqual(d
['c'], 3)
370 self
.assertEqual(d
['a'], 4)
372 self
.assertEqual(d
, {'a': 4, 'c': 3})
374 self
.assertRaises(TypeError, d
.__getitem
__)
376 def test_clear(self
):
377 d
= self
._full
_mapping
({1:1, 2:2, 3:3})
379 self
.assertEqual(d
, {})
381 self
.assertRaises(TypeError, d
.clear
, None)
383 def test_update(self
):
384 BasicTestMappingProtocol
.test_update(self
)
386 d
= self
._empty
_mapping
()
389 d
.update({1:1, 2:2, 3:3})
390 self
.assertEqual(d
, {1:1, 2:2, 3:3})
394 self
.assertEqual(d
, {1:1, 2:2, 3:3})
397 d
= self
._empty
_mapping
()
400 d
.update(x
=1, y
=2, z
=3)
401 self
.assertEqual(d
, {"x":1, "y":2, "z":3})
404 d
= self
._empty
_mapping
()
405 d
.update([("x", 100), ("y", 20)])
406 self
.assertEqual(d
, {"x":100, "y":20})
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})
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})
418 class SimpleUserDict
:
420 self
.d
= {1:1, 2:2, 3:3}
423 def __getitem__(self
, i
):
426 d
.update(SimpleUserDict())
427 self
.assertEqual(d
, {1:1, 2:2, 3:3})
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
.assertTrue(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([]), {})
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
.assertTrue(dictlike
.fromkeys('a').__class
__ is dictlike
)
444 self
.assertTrue(dictlike().fromkeys('a').__class
__ is dictlike
)
445 # FIXME: the following won't work with UserDict, because it's an old style class
446 # self.assertTrue(type(dictlike.fromkeys('a')) is dictlike)
447 class mydict(self
.type2test
):
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.assertTrue(isinstance(ud, UserDict.UserDict))
454 self
.assertRaises(TypeError, dict.fromkeys
)
456 class Exc(Exception): pass
458 class baddict1(self
.type2test
):
462 self
.assertRaises(Exc
, baddict1
.fromkeys
, [1])
464 class BadSeq(object):
470 self
.assertRaises(Exc
, self
.type2test
.fromkeys
, BadSeq())
472 class baddict2(self
.type2test
):
473 def __setitem__(self
, key
, value
):
476 self
.assertRaises(Exc
, baddict2
.fromkeys
, [1])
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
.assertTrue(isinstance(d
.copy(), d
.__class
__))
484 self
.assertRaises(TypeError, d
.copy
, None)
487 BasicTestMappingProtocol
.test_get(self
)
488 d
= self
._empty
_mapping
()
489 self
.assertTrue(d
.get('c') is None)
490 self
.assertEqual(d
.get('c', 3), 3)
491 d
= self
._full
_mapping
({'a' : 1, 'b' : 2})
492 self
.assertTrue(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)
497 def test_setdefault(self
):
498 BasicTestMappingProtocol
.test_setdefault(self
)
499 d
= self
._empty
_mapping
()
500 self
.assertTrue(d
.setdefault('key0') is None)
501 d
.setdefault('key0', [])
502 self
.assertTrue(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)
508 def test_popitem(self
):
509 BasicTestMappingProtocol
.test_popitem(self
)
510 for copymode
in -1, +1:
511 # -1: b has same structure as a
513 for log2size
in range(12):
515 a
= self
._empty
_mapping
()
516 b
= self
._empty
_mapping
()
517 for i
in range(size
):
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
.assertTrue(not(copymode
< 0 and ta
!= tb
))
529 self
.assertTrue(not a
)
530 self
.assertTrue(not b
)
533 BasicTestMappingProtocol
.test_pop(self
)
535 # Tests for pop with specified key
536 d
= self
._empty
_mapping
()
539 # verify longs/ints get same value when key > 32 bits (for 64-bit archs)
541 x
= 4503599627370496L
543 h
= self
._full
_mapping
({x
: 'anything', y
: 'something else'})
544 self
.assertEqual(h
[x
], h
[y
])
546 self
.assertEqual(d
.pop(k
, v
), v
)
548 self
.assertEqual(d
.pop(k
, 1), v
)
551 class TestHashMappingProtocol(TestMappingProtocol
):
553 def test_getitem(self
):
554 TestMappingProtocol
.test_getitem(self
)
555 class Exc(Exception): pass
558 def __eq__(self
, other
):
563 d
= self
._empty
_mapping
()
565 self
.assertRaises(KeyError, d
.__getitem
__, 23)
567 class BadHash(object):
575 d
= self
._empty
_mapping
()
579 self
.assertRaises(Exc
, d
.__getitem
__, x
)
581 def test_fromkeys(self
):
582 TestMappingProtocol
.test_fromkeys(self
)
583 class mydict(self
.type2test
):
585 return UserDict
.UserDict()
586 ud
= mydict
.fromkeys('ab')
587 self
.assertEqual(ud
, {'a':None, 'b':None})
588 self
.assertTrue(isinstance(ud
, UserDict
.UserDict
))
591 TestMappingProtocol
.test_pop(self
)
593 class Exc(Exception): pass
595 class BadHash(object):
603 d
= self
._empty
_mapping
()
607 self
.assertRaises(Exc
, d
.pop
, x
)
609 def test_mutatingiteration(self
):
610 d
= self
._empty
_mapping
()
618 self
.fail("changing dict size during iteration doesn't raise Error")
621 d
= self
._empty
_mapping
()
622 self
.assertEqual(repr(d
), '{}')
624 self
.assertEqual(repr(d
), '{1: 2}')
625 d
= self
._empty
_mapping
()
627 self
.assertEqual(repr(d
), '{1: {...}}')
629 class Exc(Exception): pass
631 class BadRepr(object):
635 d
= self
._full
_mapping
({1: BadRepr()})
636 self
.assertRaises(Exc
, repr, d
)
639 self
.assertTrue(not (self
._empty
_mapping
() < self
._empty
_mapping
()))
640 self
.assertTrue(not (self
._full
_mapping
({1: 2}) < self
._full
_mapping
({1L: 2L})))
642 class Exc(Exception): pass
644 class BadCmp(object):
645 def __eq__(self
, other
):
650 d1
= self
._full
_mapping
({BadCmp(): 1})
651 d2
= self
._full
_mapping
({1: 1})
657 self
.fail("< didn't raise Exc")
659 def test_setdefault(self
):
660 TestMappingProtocol
.test_setdefault(self
)
662 class Exc(Exception): pass
664 class BadHash(object):
672 d
= self
._empty
_mapping
()
676 self
.assertRaises(Exc
, d
.setdefault
, x
, [])