mapping_tests.py 22 KB

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