1 | # tests common to dict and UserDict
|
---|
2 | import unittest
|
---|
3 | import UserDict
|
---|
4 | import test_support
|
---|
5 |
|
---|
6 |
|
---|
7 | class 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
|
---|
13 | type2test = None # which class is being tested (overwrite in subclasses)
|
---|
14 |
|
---|
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"""
|
---|
21 | return self.type2test()
|
---|
22 | 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]
|
---|
54 | self.assertRaises(KeyError, lambda:d[knownkey])
|
---|
55 | #len
|
---|
56 | self.assertEqual(len(p), 0)
|
---|
57 | self.assertEqual(len(d), len(self.reference))
|
---|
58 | #in
|
---|
59 | for k in self.reference:
|
---|
60 | self.assertIn(k, d)
|
---|
61 | for k in self.other:
|
---|
62 | self.assertNotIn(k, d)
|
---|
63 | #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))
|
---|
69 | #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):
|
---|
79 | self.assertTrue(hasattr(iter, 'next'))
|
---|
80 | self.assertTrue(hasattr(iter, '__iter__'))
|
---|
81 | x = list(iter)
|
---|
82 | self.assertTrue(set(x)==set(lst)==set(ref))
|
---|
83 | 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)
|
---|
92 | self.assertNotIn(knownkey, d)
|
---|
93 |
|
---|
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]
|
---|
103 | self.assertRaises(KeyError, lambda:p[key])
|
---|
104 | 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)
|
---|
122 | self.assertNotIn(knownkey, d)
|
---|
123 | self.assertRaises(KeyError, d.pop, knownkey)
|
---|
124 | default = 909
|
---|
125 | d[knownkey] = knownvalue
|
---|
126 | self.assertEqual(d.pop(knownkey, default), knownvalue)
|
---|
127 | self.assertNotIn(knownkey, d)
|
---|
128 | self.assertEqual(d.pop(knownkey, default), default)
|
---|
129 | #popitem
|
---|
130 | key, value = d.popitem()
|
---|
131 | self.assertNotIn(key, d)
|
---|
132 | 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):
|
---|
140 | 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)
|
---|
144 |
|
---|
145 | def test_keys(self):
|
---|
146 | d = self._empty_mapping()
|
---|
147 | self.assertEqual(d.keys(), [])
|
---|
148 | d = self.reference
|
---|
149 | self.assertIn(self.inmapping.keys()[0], d.keys())
|
---|
150 | self.assertNotIn(self.other.keys()[0], d.keys())
|
---|
151 | 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()
|
---|
212 |
|
---|
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)
|
---|
218 | 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()
|
---|
280 | self.assertTrue(d.get(self.other.keys()[0]) is None)
|
---|
281 | self.assertEqual(d.get(self.other.keys()[0], 3), 3)
|
---|
282 | d = self.reference
|
---|
283 | self.assertTrue(d.get(self.other.keys()[0]) is None)
|
---|
284 | 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 |
|
---|
311 | class TestMappingProtocol(BasicTestMappingProtocol):
|
---|
312 | def test_constructor(self):
|
---|
313 | BasicTestMappingProtocol.test_constructor(self)
|
---|
314 | self.assertTrue(self._empty_mapping() is not self._empty_mapping())
|
---|
315 | self.assertEqual(self.type2test(x=1, y=2), {"x": 1, "y": 2})
|
---|
316 |
|
---|
317 | def test_bool(self):
|
---|
318 | BasicTestMappingProtocol.test_bool(self)
|
---|
319 | 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)
|
---|
323 |
|
---|
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()
|
---|
330 | self.assertIn('a', k)
|
---|
331 | self.assertIn('b', k)
|
---|
332 | self.assertNotIn('c', k)
|
---|
333 |
|
---|
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()
|
---|
347 | self.assertTrue(not d.has_key('a'))
|
---|
348 | d = self._full_mapping({'a': 1, 'b': 2})
|
---|
349 | k = d.keys()
|
---|
350 | k.sort(key=lambda k: (id(type(k)), k))
|
---|
351 | self.assertEqual(k, ['a', 'b'])
|
---|
352 |
|
---|
353 | self.assertRaises(TypeError, d.has_key)
|
---|
354 |
|
---|
355 | def test_contains(self):
|
---|
356 | d = self._empty_mapping()
|
---|
357 | self.assertNotIn('a', d)
|
---|
358 | self.assertTrue(not ('a' in d))
|
---|
359 | self.assertTrue('a' not in d)
|
---|
360 | d = self._full_mapping({'a': 1, 'b': 2})
|
---|
361 | self.assertIn('a', d)
|
---|
362 | self.assertIn('b', d)
|
---|
363 | self.assertNotIn('c', d)
|
---|
364 |
|
---|
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):
|
---|
440 | self.assertEqual(self.type2test.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
|
---|
441 | d = self._empty_mapping()
|
---|
442 | self.assertTrue(not(d.fromkeys('abc') is d))
|
---|
443 | 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)
|
---|
450 | class dictlike(self.type2test): pass
|
---|
451 | self.assertEqual(dictlike.fromkeys('a'), {'a':None})
|
---|
452 | self.assertEqual(dictlike().fromkeys('a'), {'a':None})
|
---|
453 | self.assertTrue(dictlike.fromkeys('a').__class__ is dictlike)
|
---|
454 | self.assertTrue(dictlike().fromkeys('a').__class__ is dictlike)
|
---|
455 | # FIXME: the following won't work with UserDict, because it's an old style class
|
---|
456 | # self.assertTrue(type(dictlike.fromkeys('a')) is dictlike)
|
---|
457 | class mydict(self.type2test):
|
---|
458 | 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
|
---|
463 | # self.assertIsInstance(ud, UserDict.UserDict)
|
---|
464 | self.assertRaises(TypeError, dict.fromkeys)
|
---|
465 |
|
---|
466 | class Exc(Exception): pass
|
---|
467 |
|
---|
468 | class baddict1(self.type2test):
|
---|
469 | 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 |
|
---|
480 | self.assertRaises(Exc, self.type2test.fromkeys, BadSeq())
|
---|
481 |
|
---|
482 | class baddict2(self.type2test):
|
---|
483 | 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)
|
---|
493 | self.assertIsInstance(d.copy(), d.__class__)
|
---|
494 | self.assertRaises(TypeError, d.copy, None)
|
---|
495 |
|
---|
496 | def test_get(self):
|
---|
497 | BasicTestMappingProtocol.test_get(self)
|
---|
498 | d = self._empty_mapping()
|
---|
499 | self.assertTrue(d.get('c') is None)
|
---|
500 | self.assertEqual(d.get('c', 3), 3)
|
---|
501 | d = self._full_mapping({'a' : 1, 'b' : 2})
|
---|
502 | self.assertTrue(d.get('c') is None)
|
---|
503 | 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()
|
---|
510 | self.assertTrue(d.setdefault('key0') is None)
|
---|
511 | d.setdefault('key0', [])
|
---|
512 | self.assertTrue(d.setdefault('key0') is None)
|
---|
513 | 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))
|
---|
538 | self.assertTrue(not(copymode < 0 and ta != tb))
|
---|
539 | self.assertTrue(not a)
|
---|
540 | self.assertTrue(not b)
|
---|
541 |
|
---|
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 |
|
---|
561 | class 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()
|
---|
570 | def __hash__(self):
|
---|
571 | return 24
|
---|
572 |
|
---|
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)
|
---|
593 | class mydict(self.type2test):
|
---|
594 | def __new__(cls):
|
---|
595 | return UserDict.UserDict()
|
---|
596 | ud = mydict.fromkeys('ab')
|
---|
597 | self.assertEqual(ud, {'a':None, 'b':None})
|
---|
598 | self.assertIsInstance(ud, UserDict.UserDict)
|
---|
599 |
|
---|
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):
|
---|
649 | self.assertTrue(not (self._empty_mapping() < self._empty_mapping()))
|
---|
650 | self.assertTrue(not (self._full_mapping({1: 2}) < self._full_mapping({1L: 2L})))
|
---|
651 |
|
---|
652 | class Exc(Exception): pass
|
---|
653 |
|
---|
654 | class BadCmp(object):
|
---|
655 | def __eq__(self, other):
|
---|
656 | raise Exc()
|
---|
657 | def __hash__(self):
|
---|
658 | return 42
|
---|
659 |
|
---|
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, [])
|
---|