test_dict.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. import unittest
  2. from test import test_support
  3. import UserDict, random, string
  4. import gc, weakref
  5. class DictTest(unittest.TestCase):
  6. def test_constructor(self):
  7. # calling built-in types without argument must return empty
  8. self.assertEqual(dict(), {})
  9. self.assertIsNot(dict(), {})
  10. def test_literal_constructor(self):
  11. # check literal constructor for different sized dicts
  12. # (to exercise the BUILD_MAP oparg).
  13. for n in (0, 1, 6, 256, 400):
  14. items = [(''.join(random.sample(string.letters, 8)), i)
  15. for i in range(n)]
  16. random.shuffle(items)
  17. formatted_items = ('{!r}: {:d}'.format(k, v) for k, v in items)
  18. dictliteral = '{' + ', '.join(formatted_items) + '}'
  19. self.assertEqual(eval(dictliteral), dict(items))
  20. def test_bool(self):
  21. self.assertIs(not {}, True)
  22. self.assertTrue({1: 2})
  23. self.assertIs(bool({}), False)
  24. self.assertIs(bool({1: 2}), True)
  25. def test_keys(self):
  26. d = {}
  27. self.assertEqual(d.keys(), [])
  28. d = {'a': 1, 'b': 2}
  29. k = d.keys()
  30. self.assertEqual(set(k), {'a', 'b'})
  31. self.assertIn('a', k)
  32. self.assertIn('b', k)
  33. self.assertTrue(d.has_key('a'))
  34. self.assertTrue(d.has_key('b'))
  35. self.assertRaises(TypeError, d.keys, None)
  36. def test_values(self):
  37. d = {}
  38. self.assertEqual(d.values(), [])
  39. d = {1:2}
  40. self.assertEqual(d.values(), [2])
  41. self.assertRaises(TypeError, d.values, None)
  42. def test_items(self):
  43. d = {}
  44. self.assertEqual(d.items(), [])
  45. d = {1:2}
  46. self.assertEqual(d.items(), [(1, 2)])
  47. self.assertRaises(TypeError, d.items, None)
  48. def test_has_key(self):
  49. d = {}
  50. self.assertFalse(d.has_key('a'))
  51. d = {'a': 1, 'b': 2}
  52. k = d.keys()
  53. k.sort()
  54. self.assertEqual(k, ['a', 'b'])
  55. self.assertRaises(TypeError, d.has_key)
  56. def test_contains(self):
  57. d = {}
  58. self.assertNotIn('a', d)
  59. self.assertFalse('a' in d)
  60. self.assertTrue('a' not in d)
  61. d = {'a': 1, 'b': 2}
  62. self.assertIn('a', d)
  63. self.assertIn('b', d)
  64. self.assertNotIn('c', d)
  65. self.assertRaises(TypeError, d.__contains__)
  66. def test_len(self):
  67. d = {}
  68. self.assertEqual(len(d), 0)
  69. d = {'a': 1, 'b': 2}
  70. self.assertEqual(len(d), 2)
  71. def test_getitem(self):
  72. d = {'a': 1, 'b': 2}
  73. self.assertEqual(d['a'], 1)
  74. self.assertEqual(d['b'], 2)
  75. d['c'] = 3
  76. d['a'] = 4
  77. self.assertEqual(d['c'], 3)
  78. self.assertEqual(d['a'], 4)
  79. del d['b']
  80. self.assertEqual(d, {'a': 4, 'c': 3})
  81. self.assertRaises(TypeError, d.__getitem__)
  82. class BadEq(object):
  83. def __eq__(self, other):
  84. raise Exc()
  85. def __hash__(self):
  86. return 24
  87. d = {}
  88. d[BadEq()] = 42
  89. self.assertRaises(KeyError, d.__getitem__, 23)
  90. class Exc(Exception): pass
  91. class BadHash(object):
  92. fail = False
  93. def __hash__(self):
  94. if self.fail:
  95. raise Exc()
  96. else:
  97. return 42
  98. x = BadHash()
  99. d[x] = 42
  100. x.fail = True
  101. self.assertRaises(Exc, d.__getitem__, x)
  102. def test_clear(self):
  103. d = {1:1, 2:2, 3:3}
  104. d.clear()
  105. self.assertEqual(d, {})
  106. self.assertRaises(TypeError, d.clear, None)
  107. def test_update(self):
  108. d = {}
  109. d.update({1:100})
  110. d.update({2:20})
  111. d.update({1:1, 2:2, 3:3})
  112. self.assertEqual(d, {1:1, 2:2, 3:3})
  113. d.update()
  114. self.assertEqual(d, {1:1, 2:2, 3:3})
  115. self.assertRaises((TypeError, AttributeError), d.update, None)
  116. class SimpleUserDict:
  117. def __init__(self):
  118. self.d = {1:1, 2:2, 3:3}
  119. def keys(self):
  120. return self.d.keys()
  121. def __getitem__(self, i):
  122. return self.d[i]
  123. d.clear()
  124. d.update(SimpleUserDict())
  125. self.assertEqual(d, {1:1, 2:2, 3:3})
  126. class Exc(Exception): pass
  127. d.clear()
  128. class FailingUserDict:
  129. def keys(self):
  130. raise Exc
  131. self.assertRaises(Exc, d.update, FailingUserDict())
  132. class FailingUserDict:
  133. def keys(self):
  134. class BogonIter:
  135. def __init__(self):
  136. self.i = 1
  137. def __iter__(self):
  138. return self
  139. def next(self):
  140. if self.i:
  141. self.i = 0
  142. return 'a'
  143. raise Exc
  144. return BogonIter()
  145. def __getitem__(self, key):
  146. return key
  147. self.assertRaises(Exc, d.update, FailingUserDict())
  148. class FailingUserDict:
  149. def keys(self):
  150. class BogonIter:
  151. def __init__(self):
  152. self.i = ord('a')
  153. def __iter__(self):
  154. return self
  155. def next(self):
  156. if self.i <= ord('z'):
  157. rtn = chr(self.i)
  158. self.i += 1
  159. return rtn
  160. raise StopIteration
  161. return BogonIter()
  162. def __getitem__(self, key):
  163. raise Exc
  164. self.assertRaises(Exc, d.update, FailingUserDict())
  165. class badseq(object):
  166. def __iter__(self):
  167. return self
  168. def next(self):
  169. raise Exc()
  170. self.assertRaises(Exc, {}.update, badseq())
  171. self.assertRaises(ValueError, {}.update, [(1, 2, 3)])
  172. def test_fromkeys(self):
  173. self.assertEqual(dict.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
  174. d = {}
  175. self.assertIsNot(d.fromkeys('abc'), d)
  176. self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
  177. self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0})
  178. self.assertEqual(d.fromkeys([]), {})
  179. def g():
  180. yield 1
  181. self.assertEqual(d.fromkeys(g()), {1:None})
  182. self.assertRaises(TypeError, {}.fromkeys, 3)
  183. class dictlike(dict): pass
  184. self.assertEqual(dictlike.fromkeys('a'), {'a':None})
  185. self.assertEqual(dictlike().fromkeys('a'), {'a':None})
  186. self.assertIsInstance(dictlike.fromkeys('a'), dictlike)
  187. self.assertIsInstance(dictlike().fromkeys('a'), dictlike)
  188. class mydict(dict):
  189. def __new__(cls):
  190. return UserDict.UserDict()
  191. ud = mydict.fromkeys('ab')
  192. self.assertEqual(ud, {'a':None, 'b':None})
  193. self.assertIsInstance(ud, UserDict.UserDict)
  194. self.assertRaises(TypeError, dict.fromkeys)
  195. class Exc(Exception): pass
  196. class baddict1(dict):
  197. def __init__(self):
  198. raise Exc()
  199. self.assertRaises(Exc, baddict1.fromkeys, [1])
  200. class BadSeq(object):
  201. def __iter__(self):
  202. return self
  203. def next(self):
  204. raise Exc()
  205. self.assertRaises(Exc, dict.fromkeys, BadSeq())
  206. class baddict2(dict):
  207. def __setitem__(self, key, value):
  208. raise Exc()
  209. self.assertRaises(Exc, baddict2.fromkeys, [1])
  210. # test fast path for dictionary inputs
  211. d = dict(zip(range(6), range(6)))
  212. self.assertEqual(dict.fromkeys(d, 0), dict(zip(range(6), [0]*6)))
  213. class baddict3(dict):
  214. def __new__(cls):
  215. return d
  216. d = {i : i for i in range(10)}
  217. res = d.copy()
  218. res.update(a=None, b=None, c=None)
  219. self.assertEqual(baddict3.fromkeys({"a", "b", "c"}), res)
  220. def test_copy(self):
  221. d = {1:1, 2:2, 3:3}
  222. self.assertEqual(d.copy(), {1:1, 2:2, 3:3})
  223. self.assertEqual({}.copy(), {})
  224. self.assertRaises(TypeError, d.copy, None)
  225. def test_get(self):
  226. d = {}
  227. self.assertIs(d.get('c'), None)
  228. self.assertEqual(d.get('c', 3), 3)
  229. d = {'a': 1, 'b': 2}
  230. self.assertIs(d.get('c'), None)
  231. self.assertEqual(d.get('c', 3), 3)
  232. self.assertEqual(d.get('a'), 1)
  233. self.assertEqual(d.get('a', 3), 1)
  234. self.assertRaises(TypeError, d.get)
  235. self.assertRaises(TypeError, d.get, None, None, None)
  236. def test_setdefault(self):
  237. # dict.setdefault()
  238. d = {}
  239. self.assertIs(d.setdefault('key0'), None)
  240. d.setdefault('key0', [])
  241. self.assertIs(d.setdefault('key0'), None)
  242. d.setdefault('key', []).append(3)
  243. self.assertEqual(d['key'][0], 3)
  244. d.setdefault('key', []).append(4)
  245. self.assertEqual(len(d['key']), 2)
  246. self.assertRaises(TypeError, d.setdefault)
  247. class Exc(Exception): pass
  248. class BadHash(object):
  249. fail = False
  250. def __hash__(self):
  251. if self.fail:
  252. raise Exc()
  253. else:
  254. return 42
  255. x = BadHash()
  256. d[x] = 42
  257. x.fail = True
  258. self.assertRaises(Exc, d.setdefault, x, [])
  259. def test_setdefault_atomic(self):
  260. # Issue #13521: setdefault() calls __hash__ and __eq__ only once.
  261. class Hashed(object):
  262. def __init__(self):
  263. self.hash_count = 0
  264. self.eq_count = 0
  265. def __hash__(self):
  266. self.hash_count += 1
  267. return 42
  268. def __eq__(self, other):
  269. self.eq_count += 1
  270. return id(self) == id(other)
  271. hashed1 = Hashed()
  272. y = {hashed1: 5}
  273. hashed2 = Hashed()
  274. y.setdefault(hashed2, [])
  275. self.assertEqual(hashed1.hash_count, 1)
  276. self.assertEqual(hashed2.hash_count, 1)
  277. self.assertEqual(hashed1.eq_count + hashed2.eq_count, 1)
  278. def test_popitem(self):
  279. # dict.popitem()
  280. for copymode in -1, +1:
  281. # -1: b has same structure as a
  282. # +1: b is a.copy()
  283. for log2size in range(12):
  284. size = 2**log2size
  285. a = {}
  286. b = {}
  287. for i in range(size):
  288. a[repr(i)] = i
  289. if copymode < 0:
  290. b[repr(i)] = i
  291. if copymode > 0:
  292. b = a.copy()
  293. for i in range(size):
  294. ka, va = ta = a.popitem()
  295. self.assertEqual(va, int(ka))
  296. kb, vb = tb = b.popitem()
  297. self.assertEqual(vb, int(kb))
  298. self.assertFalse(copymode < 0 and ta != tb)
  299. self.assertFalse(a)
  300. self.assertFalse(b)
  301. d = {}
  302. self.assertRaises(KeyError, d.popitem)
  303. def test_pop(self):
  304. # Tests for pop with specified key
  305. d = {}
  306. k, v = 'abc', 'def'
  307. d[k] = v
  308. self.assertRaises(KeyError, d.pop, 'ghi')
  309. self.assertEqual(d.pop(k), v)
  310. self.assertEqual(len(d), 0)
  311. self.assertRaises(KeyError, d.pop, k)
  312. # verify longs/ints get same value when key > 32 bits
  313. # (for 64-bit archs). See SF bug #689659.
  314. x = 4503599627370496L
  315. y = 4503599627370496
  316. h = {x: 'anything', y: 'something else'}
  317. self.assertEqual(h[x], h[y])
  318. self.assertEqual(d.pop(k, v), v)
  319. d[k] = v
  320. self.assertEqual(d.pop(k, 1), v)
  321. self.assertRaises(TypeError, d.pop)
  322. class Exc(Exception): pass
  323. class BadHash(object):
  324. fail = False
  325. def __hash__(self):
  326. if self.fail:
  327. raise Exc()
  328. else:
  329. return 42
  330. x = BadHash()
  331. d[x] = 42
  332. x.fail = True
  333. self.assertRaises(Exc, d.pop, x)
  334. def test_mutatingiteration(self):
  335. # changing dict size during iteration
  336. d = {}
  337. d[1] = 1
  338. with self.assertRaises(RuntimeError):
  339. for i in d:
  340. d[i+1] = 1
  341. def test_repr(self):
  342. d = {}
  343. self.assertEqual(repr(d), '{}')
  344. d[1] = 2
  345. self.assertEqual(repr(d), '{1: 2}')
  346. d = {}
  347. d[1] = d
  348. self.assertEqual(repr(d), '{1: {...}}')
  349. class Exc(Exception): pass
  350. class BadRepr(object):
  351. def __repr__(self):
  352. raise Exc()
  353. d = {1: BadRepr()}
  354. self.assertRaises(Exc, repr, d)
  355. def test_le(self):
  356. self.assertFalse({} < {})
  357. self.assertFalse({1: 2} < {1L: 2L})
  358. class Exc(Exception): pass
  359. class BadCmp(object):
  360. def __eq__(self, other):
  361. raise Exc()
  362. def __hash__(self):
  363. return 42
  364. d1 = {BadCmp(): 1}
  365. d2 = {1: 1}
  366. with self.assertRaises(Exc):
  367. d1 < d2
  368. def test_missing(self):
  369. # Make sure dict doesn't have a __missing__ method
  370. self.assertFalse(hasattr(dict, "__missing__"))
  371. self.assertFalse(hasattr({}, "__missing__"))
  372. # Test several cases:
  373. # (D) subclass defines __missing__ method returning a value
  374. # (E) subclass defines __missing__ method raising RuntimeError
  375. # (F) subclass sets __missing__ instance variable (no effect)
  376. # (G) subclass doesn't define __missing__ at all
  377. class D(dict):
  378. def __missing__(self, key):
  379. return 42
  380. d = D({1: 2, 3: 4})
  381. self.assertEqual(d[1], 2)
  382. self.assertEqual(d[3], 4)
  383. self.assertNotIn(2, d)
  384. self.assertNotIn(2, d.keys())
  385. self.assertEqual(d[2], 42)
  386. class E(dict):
  387. def __missing__(self, key):
  388. raise RuntimeError(key)
  389. e = E()
  390. with self.assertRaises(RuntimeError) as c:
  391. e[42]
  392. self.assertEqual(c.exception.args, (42,))
  393. class F(dict):
  394. def __init__(self):
  395. # An instance variable __missing__ should have no effect
  396. self.__missing__ = lambda key: None
  397. f = F()
  398. with self.assertRaises(KeyError) as c:
  399. f[42]
  400. self.assertEqual(c.exception.args, (42,))
  401. class G(dict):
  402. pass
  403. g = G()
  404. with self.assertRaises(KeyError) as c:
  405. g[42]
  406. self.assertEqual(c.exception.args, (42,))
  407. def test_tuple_keyerror(self):
  408. # SF #1576657
  409. d = {}
  410. with self.assertRaises(KeyError) as c:
  411. d[(1,)]
  412. self.assertEqual(c.exception.args, ((1,),))
  413. def test_bad_key(self):
  414. # Dictionary lookups should fail if __cmp__() raises an exception.
  415. class CustomException(Exception):
  416. pass
  417. class BadDictKey:
  418. def __hash__(self):
  419. return hash(self.__class__)
  420. def __cmp__(self, other):
  421. if isinstance(other, self.__class__):
  422. raise CustomException
  423. return other
  424. d = {}
  425. x1 = BadDictKey()
  426. x2 = BadDictKey()
  427. d[x1] = 1
  428. for stmt in ['d[x2] = 2',
  429. 'z = d[x2]',
  430. 'x2 in d',
  431. 'd.has_key(x2)',
  432. 'd.get(x2)',
  433. 'd.setdefault(x2, 42)',
  434. 'd.pop(x2)',
  435. 'd.update({x2: 2})']:
  436. with self.assertRaises(CustomException):
  437. exec stmt in locals()
  438. def test_resize1(self):
  439. # Dict resizing bug, found by Jack Jansen in 2.2 CVS development.
  440. # This version got an assert failure in debug build, infinite loop in
  441. # release build. Unfortunately, provoking this kind of stuff requires
  442. # a mix of inserts and deletes hitting exactly the right hash codes in
  443. # exactly the right order, and I can't think of a randomized approach
  444. # that would be *likely* to hit a failing case in reasonable time.
  445. d = {}
  446. for i in range(5):
  447. d[i] = i
  448. for i in range(5):
  449. del d[i]
  450. for i in range(5, 9): # i==8 was the problem
  451. d[i] = i
  452. def test_resize2(self):
  453. # Another dict resizing bug (SF bug #1456209).
  454. # This caused Segmentation faults or Illegal instructions.
  455. class X(object):
  456. def __hash__(self):
  457. return 5
  458. def __eq__(self, other):
  459. if resizing:
  460. d.clear()
  461. return False
  462. d = {}
  463. resizing = False
  464. d[X()] = 1
  465. d[X()] = 2
  466. d[X()] = 3
  467. d[X()] = 4
  468. d[X()] = 5
  469. # now trigger a resize
  470. resizing = True
  471. d[9] = 6
  472. def test_empty_presized_dict_in_freelist(self):
  473. # Bug #3537: if an empty but presized dict with a size larger
  474. # than 7 was in the freelist, it triggered an assertion failure
  475. with self.assertRaises(ZeroDivisionError):
  476. d = {'a': 1 // 0, 'b': None, 'c': None, 'd': None, 'e': None,
  477. 'f': None, 'g': None, 'h': None}
  478. d = {}
  479. def test_container_iterator(self):
  480. # Bug #3680: tp_traverse was not implemented for dictiter objects
  481. class C(object):
  482. pass
  483. iterators = (dict.iteritems, dict.itervalues, dict.iterkeys)
  484. for i in iterators:
  485. obj = C()
  486. ref = weakref.ref(obj)
  487. container = {obj: 1}
  488. obj.x = i(container)
  489. del obj, container
  490. gc.collect()
  491. self.assertIs(ref(), None, "Cycle was not collected")
  492. def _not_tracked(self, t):
  493. # Nested containers can take several collections to untrack
  494. gc.collect()
  495. gc.collect()
  496. self.assertFalse(gc.is_tracked(t), t)
  497. def _tracked(self, t):
  498. self.assertTrue(gc.is_tracked(t), t)
  499. gc.collect()
  500. gc.collect()
  501. self.assertTrue(gc.is_tracked(t), t)
  502. @test_support.cpython_only
  503. def test_track_literals(self):
  504. # Test GC-optimization of dict literals
  505. x, y, z, w = 1.5, "a", (1, None), []
  506. self._not_tracked({})
  507. self._not_tracked({x:(), y:x, z:1})
  508. self._not_tracked({1: "a", "b": 2})
  509. self._not_tracked({1: 2, (None, True, False, ()): int})
  510. self._not_tracked({1: object()})
  511. # Dicts with mutable elements are always tracked, even if those
  512. # elements are not tracked right now.
  513. self._tracked({1: []})
  514. self._tracked({1: ([],)})
  515. self._tracked({1: {}})
  516. self._tracked({1: set()})
  517. @test_support.cpython_only
  518. def test_track_dynamic(self):
  519. # Test GC-optimization of dynamically-created dicts
  520. class MyObject(object):
  521. pass
  522. x, y, z, w, o = 1.5, "a", (1, object()), [], MyObject()
  523. d = dict()
  524. self._not_tracked(d)
  525. d[1] = "a"
  526. self._not_tracked(d)
  527. d[y] = 2
  528. self._not_tracked(d)
  529. d[z] = 3
  530. self._not_tracked(d)
  531. self._not_tracked(d.copy())
  532. d[4] = w
  533. self._tracked(d)
  534. self._tracked(d.copy())
  535. d[4] = None
  536. self._not_tracked(d)
  537. self._not_tracked(d.copy())
  538. # dd isn't tracked right now, but it may mutate and therefore d
  539. # which contains it must be tracked.
  540. d = dict()
  541. dd = dict()
  542. d[1] = dd
  543. self._not_tracked(dd)
  544. self._tracked(d)
  545. dd[1] = d
  546. self._tracked(dd)
  547. d = dict.fromkeys([x, y, z])
  548. self._not_tracked(d)
  549. dd = dict()
  550. dd.update(d)
  551. self._not_tracked(dd)
  552. d = dict.fromkeys([x, y, z, o])
  553. self._tracked(d)
  554. dd = dict()
  555. dd.update(d)
  556. self._tracked(dd)
  557. d = dict(x=x, y=y, z=z)
  558. self._not_tracked(d)
  559. d = dict(x=x, y=y, z=z, w=w)
  560. self._tracked(d)
  561. d = dict()
  562. d.update(x=x, y=y, z=z)
  563. self._not_tracked(d)
  564. d.update(w=w)
  565. self._tracked(d)
  566. d = dict([(x, y), (z, 1)])
  567. self._not_tracked(d)
  568. d = dict([(x, y), (z, w)])
  569. self._tracked(d)
  570. d = dict()
  571. d.update([(x, y), (z, 1)])
  572. self._not_tracked(d)
  573. d.update([(x, y), (z, w)])
  574. self._tracked(d)
  575. @test_support.cpython_only
  576. def test_track_subtypes(self):
  577. # Dict subtypes are always tracked
  578. class MyDict(dict):
  579. pass
  580. self._tracked(MyDict())
  581. def test_free_after_iterating(self):
  582. test_support.check_free_after_iterating(self, iter, dict)
  583. test_support.check_free_after_iterating(self, lambda d: d.iterkeys(), dict)
  584. test_support.check_free_after_iterating(self, lambda d: d.itervalues(), dict)
  585. test_support.check_free_after_iterating(self, lambda d: d.iteritems(), dict)
  586. test_support.check_free_after_iterating(self, lambda d: iter(d.viewkeys()), dict)
  587. test_support.check_free_after_iterating(self, lambda d: iter(d.viewvalues()), dict)
  588. test_support.check_free_after_iterating(self, lambda d: iter(d.viewitems()), dict)
  589. from test import mapping_tests
  590. class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
  591. type2test = dict
  592. class Dict(dict):
  593. pass
  594. class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
  595. type2test = Dict
  596. def test_main():
  597. with test_support.check_py3k_warnings(
  598. ('dict(.has_key..| inequality comparisons) not supported in 3.x',
  599. DeprecationWarning)):
  600. test_support.run_unittest(
  601. DictTest,
  602. GeneralMappingTests,
  603. SubclassMappingTests,
  604. )
  605. if __name__ == "__main__":
  606. test_main()