+++ /dev/null
-import unittest\r
-from test import test_support\r
-\r
-import UserDict, random, string\r
-import gc, weakref\r
-\r
-\r
-class DictTest(unittest.TestCase):\r
- def test_constructor(self):\r
- # calling built-in types without argument must return empty\r
- self.assertEqual(dict(), {})\r
- self.assertIsNot(dict(), {})\r
-\r
- def test_literal_constructor(self):\r
- # check literal constructor for different sized dicts\r
- # (to exercise the BUILD_MAP oparg).\r
- for n in (0, 1, 6, 256, 400):\r
- items = [(''.join(random.sample(string.letters, 8)), i)\r
- for i in range(n)]\r
- random.shuffle(items)\r
- formatted_items = ('{!r}: {:d}'.format(k, v) for k, v in items)\r
- dictliteral = '{' + ', '.join(formatted_items) + '}'\r
- self.assertEqual(eval(dictliteral), dict(items))\r
-\r
- def test_bool(self):\r
- self.assertIs(not {}, True)\r
- self.assertTrue({1: 2})\r
- self.assertIs(bool({}), False)\r
- self.assertIs(bool({1: 2}), True)\r
-\r
- def test_keys(self):\r
- d = {}\r
- self.assertEqual(d.keys(), [])\r
- d = {'a': 1, 'b': 2}\r
- k = d.keys()\r
- self.assertTrue(d.has_key('a'))\r
- self.assertTrue(d.has_key('b'))\r
-\r
- self.assertRaises(TypeError, d.keys, None)\r
-\r
- def test_values(self):\r
- d = {}\r
- self.assertEqual(d.values(), [])\r
- d = {1:2}\r
- self.assertEqual(d.values(), [2])\r
-\r
- self.assertRaises(TypeError, d.values, None)\r
-\r
- def test_items(self):\r
- d = {}\r
- self.assertEqual(d.items(), [])\r
-\r
- d = {1:2}\r
- self.assertEqual(d.items(), [(1, 2)])\r
-\r
- self.assertRaises(TypeError, d.items, None)\r
-\r
- def test_has_key(self):\r
- d = {}\r
- self.assertFalse(d.has_key('a'))\r
- d = {'a': 1, 'b': 2}\r
- k = d.keys()\r
- k.sort()\r
- self.assertEqual(k, ['a', 'b'])\r
-\r
- self.assertRaises(TypeError, d.has_key)\r
-\r
- def test_contains(self):\r
- d = {}\r
- self.assertNotIn('a', d)\r
- self.assertFalse('a' in d)\r
- self.assertTrue('a' not in d)\r
- d = {'a': 1, 'b': 2}\r
- self.assertIn('a', d)\r
- self.assertIn('b', d)\r
- self.assertNotIn('c', d)\r
-\r
- self.assertRaises(TypeError, d.__contains__)\r
-\r
- def test_len(self):\r
- d = {}\r
- self.assertEqual(len(d), 0)\r
- d = {'a': 1, 'b': 2}\r
- self.assertEqual(len(d), 2)\r
-\r
- def test_getitem(self):\r
- d = {'a': 1, 'b': 2}\r
- self.assertEqual(d['a'], 1)\r
- self.assertEqual(d['b'], 2)\r
- d['c'] = 3\r
- d['a'] = 4\r
- self.assertEqual(d['c'], 3)\r
- self.assertEqual(d['a'], 4)\r
- del d['b']\r
- self.assertEqual(d, {'a': 4, 'c': 3})\r
-\r
- self.assertRaises(TypeError, d.__getitem__)\r
-\r
- class BadEq(object):\r
- def __eq__(self, other):\r
- raise Exc()\r
- def __hash__(self):\r
- return 24\r
-\r
- d = {}\r
- d[BadEq()] = 42\r
- self.assertRaises(KeyError, d.__getitem__, 23)\r
-\r
- class Exc(Exception): pass\r
-\r
- class BadHash(object):\r
- fail = False\r
- def __hash__(self):\r
- if self.fail:\r
- raise Exc()\r
- else:\r
- return 42\r
-\r
- x = BadHash()\r
- d[x] = 42\r
- x.fail = True\r
- self.assertRaises(Exc, d.__getitem__, x)\r
-\r
- def test_clear(self):\r
- d = {1:1, 2:2, 3:3}\r
- d.clear()\r
- self.assertEqual(d, {})\r
-\r
- self.assertRaises(TypeError, d.clear, None)\r
-\r
- def test_update(self):\r
- d = {}\r
- d.update({1:100})\r
- d.update({2:20})\r
- d.update({1:1, 2:2, 3:3})\r
- self.assertEqual(d, {1:1, 2:2, 3:3})\r
-\r
- d.update()\r
- self.assertEqual(d, {1:1, 2:2, 3:3})\r
-\r
- self.assertRaises((TypeError, AttributeError), d.update, None)\r
-\r
- class SimpleUserDict:\r
- def __init__(self):\r
- self.d = {1:1, 2:2, 3:3}\r
- def keys(self):\r
- return self.d.keys()\r
- def __getitem__(self, i):\r
- return self.d[i]\r
- d.clear()\r
- d.update(SimpleUserDict())\r
- self.assertEqual(d, {1:1, 2:2, 3:3})\r
-\r
- class Exc(Exception): pass\r
-\r
- d.clear()\r
- class FailingUserDict:\r
- def keys(self):\r
- raise Exc\r
- self.assertRaises(Exc, d.update, FailingUserDict())\r
-\r
- class FailingUserDict:\r
- def keys(self):\r
- class BogonIter:\r
- def __init__(self):\r
- self.i = 1\r
- def __iter__(self):\r
- return self\r
- def next(self):\r
- if self.i:\r
- self.i = 0\r
- return 'a'\r
- raise Exc\r
- return BogonIter()\r
- def __getitem__(self, key):\r
- return key\r
- self.assertRaises(Exc, d.update, FailingUserDict())\r
-\r
- class FailingUserDict:\r
- def keys(self):\r
- class BogonIter:\r
- def __init__(self):\r
- self.i = ord('a')\r
- def __iter__(self):\r
- return self\r
- def next(self):\r
- if self.i <= ord('z'):\r
- rtn = chr(self.i)\r
- self.i += 1\r
- return rtn\r
- raise StopIteration\r
- return BogonIter()\r
- def __getitem__(self, key):\r
- raise Exc\r
- self.assertRaises(Exc, d.update, FailingUserDict())\r
-\r
- class badseq(object):\r
- def __iter__(self):\r
- return self\r
- def next(self):\r
- raise Exc()\r
-\r
- self.assertRaises(Exc, {}.update, badseq())\r
-\r
- self.assertRaises(ValueError, {}.update, [(1, 2, 3)])\r
-\r
- def test_fromkeys(self):\r
- self.assertEqual(dict.fromkeys('abc'), {'a':None, 'b':None, 'c':None})\r
- d = {}\r
- self.assertIsNot(d.fromkeys('abc'), d)\r
- self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None})\r
- self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0})\r
- self.assertEqual(d.fromkeys([]), {})\r
- def g():\r
- yield 1\r
- self.assertEqual(d.fromkeys(g()), {1:None})\r
- self.assertRaises(TypeError, {}.fromkeys, 3)\r
- class dictlike(dict): pass\r
- self.assertEqual(dictlike.fromkeys('a'), {'a':None})\r
- self.assertEqual(dictlike().fromkeys('a'), {'a':None})\r
- self.assertIsInstance(dictlike.fromkeys('a'), dictlike)\r
- self.assertIsInstance(dictlike().fromkeys('a'), dictlike)\r
- class mydict(dict):\r
- def __new__(cls):\r
- return UserDict.UserDict()\r
- ud = mydict.fromkeys('ab')\r
- self.assertEqual(ud, {'a':None, 'b':None})\r
- self.assertIsInstance(ud, UserDict.UserDict)\r
- self.assertRaises(TypeError, dict.fromkeys)\r
-\r
- class Exc(Exception): pass\r
-\r
- class baddict1(dict):\r
- def __init__(self):\r
- raise Exc()\r
-\r
- self.assertRaises(Exc, baddict1.fromkeys, [1])\r
-\r
- class BadSeq(object):\r
- def __iter__(self):\r
- return self\r
- def next(self):\r
- raise Exc()\r
-\r
- self.assertRaises(Exc, dict.fromkeys, BadSeq())\r
-\r
- class baddict2(dict):\r
- def __setitem__(self, key, value):\r
- raise Exc()\r
-\r
- self.assertRaises(Exc, baddict2.fromkeys, [1])\r
-\r
- # test fast path for dictionary inputs\r
- d = dict(zip(range(6), range(6)))\r
- self.assertEqual(dict.fromkeys(d, 0), dict(zip(range(6), [0]*6)))\r
-\r
- def test_copy(self):\r
- d = {1:1, 2:2, 3:3}\r
- self.assertEqual(d.copy(), {1:1, 2:2, 3:3})\r
- self.assertEqual({}.copy(), {})\r
- self.assertRaises(TypeError, d.copy, None)\r
-\r
- def test_get(self):\r
- d = {}\r
- self.assertIs(d.get('c'), None)\r
- self.assertEqual(d.get('c', 3), 3)\r
- d = {'a': 1, 'b': 2}\r
- self.assertIs(d.get('c'), None)\r
- self.assertEqual(d.get('c', 3), 3)\r
- self.assertEqual(d.get('a'), 1)\r
- self.assertEqual(d.get('a', 3), 1)\r
- self.assertRaises(TypeError, d.get)\r
- self.assertRaises(TypeError, d.get, None, None, None)\r
-\r
- def test_setdefault(self):\r
- # dict.setdefault()\r
- d = {}\r
- self.assertIs(d.setdefault('key0'), None)\r
- d.setdefault('key0', [])\r
- self.assertIs(d.setdefault('key0'), None)\r
- d.setdefault('key', []).append(3)\r
- self.assertEqual(d['key'][0], 3)\r
- d.setdefault('key', []).append(4)\r
- self.assertEqual(len(d['key']), 2)\r
- self.assertRaises(TypeError, d.setdefault)\r
-\r
- class Exc(Exception): pass\r
-\r
- class BadHash(object):\r
- fail = False\r
- def __hash__(self):\r
- if self.fail:\r
- raise Exc()\r
- else:\r
- return 42\r
-\r
- x = BadHash()\r
- d[x] = 42\r
- x.fail = True\r
- self.assertRaises(Exc, d.setdefault, x, [])\r
-\r
- def test_popitem(self):\r
- # dict.popitem()\r
- for copymode in -1, +1:\r
- # -1: b has same structure as a\r
- # +1: b is a.copy()\r
- for log2size in range(12):\r
- size = 2**log2size\r
- a = {}\r
- b = {}\r
- for i in range(size):\r
- a[repr(i)] = i\r
- if copymode < 0:\r
- b[repr(i)] = i\r
- if copymode > 0:\r
- b = a.copy()\r
- for i in range(size):\r
- ka, va = ta = a.popitem()\r
- self.assertEqual(va, int(ka))\r
- kb, vb = tb = b.popitem()\r
- self.assertEqual(vb, int(kb))\r
- self.assertFalse(copymode < 0 and ta != tb)\r
- self.assertFalse(a)\r
- self.assertFalse(b)\r
-\r
- d = {}\r
- self.assertRaises(KeyError, d.popitem)\r
-\r
- def test_pop(self):\r
- # Tests for pop with specified key\r
- d = {}\r
- k, v = 'abc', 'def'\r
- d[k] = v\r
- self.assertRaises(KeyError, d.pop, 'ghi')\r
-\r
- self.assertEqual(d.pop(k), v)\r
- self.assertEqual(len(d), 0)\r
-\r
- self.assertRaises(KeyError, d.pop, k)\r
-\r
- # verify longs/ints get same value when key > 32 bits\r
- # (for 64-bit archs). See SF bug #689659.\r
- x = 4503599627370496L\r
- y = 4503599627370496\r
- h = {x: 'anything', y: 'something else'}\r
- self.assertEqual(h[x], h[y])\r
-\r
- self.assertEqual(d.pop(k, v), v)\r
- d[k] = v\r
- self.assertEqual(d.pop(k, 1), v)\r
-\r
- self.assertRaises(TypeError, d.pop)\r
-\r
- class Exc(Exception): pass\r
-\r
- class BadHash(object):\r
- fail = False\r
- def __hash__(self):\r
- if self.fail:\r
- raise Exc()\r
- else:\r
- return 42\r
-\r
- x = BadHash()\r
- d[x] = 42\r
- x.fail = True\r
- self.assertRaises(Exc, d.pop, x)\r
-\r
- def test_mutatingiteration(self):\r
- # changing dict size during iteration\r
- d = {}\r
- d[1] = 1\r
- with self.assertRaises(RuntimeError):\r
- for i in d:\r
- d[i+1] = 1\r
-\r
- def test_repr(self):\r
- d = {}\r
- self.assertEqual(repr(d), '{}')\r
- d[1] = 2\r
- self.assertEqual(repr(d), '{1: 2}')\r
- d = {}\r
- d[1] = d\r
- self.assertEqual(repr(d), '{1: {...}}')\r
-\r
- class Exc(Exception): pass\r
-\r
- class BadRepr(object):\r
- def __repr__(self):\r
- raise Exc()\r
-\r
- d = {1: BadRepr()}\r
- self.assertRaises(Exc, repr, d)\r
-\r
- def test_le(self):\r
- self.assertFalse({} < {})\r
- self.assertFalse({1: 2} < {1L: 2L})\r
-\r
- class Exc(Exception): pass\r
-\r
- class BadCmp(object):\r
- def __eq__(self, other):\r
- raise Exc()\r
- def __hash__(self):\r
- return 42\r
-\r
- d1 = {BadCmp(): 1}\r
- d2 = {1: 1}\r
-\r
- with self.assertRaises(Exc):\r
- d1 < d2\r
-\r
- def test_missing(self):\r
- # Make sure dict doesn't have a __missing__ method\r
- self.assertFalse(hasattr(dict, "__missing__"))\r
- self.assertFalse(hasattr({}, "__missing__"))\r
- # Test several cases:\r
- # (D) subclass defines __missing__ method returning a value\r
- # (E) subclass defines __missing__ method raising RuntimeError\r
- # (F) subclass sets __missing__ instance variable (no effect)\r
- # (G) subclass doesn't define __missing__ at a all\r
- class D(dict):\r
- def __missing__(self, key):\r
- return 42\r
- d = D({1: 2, 3: 4})\r
- self.assertEqual(d[1], 2)\r
- self.assertEqual(d[3], 4)\r
- self.assertNotIn(2, d)\r
- self.assertNotIn(2, d.keys())\r
- self.assertEqual(d[2], 42)\r
-\r
- class E(dict):\r
- def __missing__(self, key):\r
- raise RuntimeError(key)\r
- e = E()\r
- with self.assertRaises(RuntimeError) as c:\r
- e[42]\r
- self.assertEqual(c.exception.args, (42,))\r
-\r
- class F(dict):\r
- def __init__(self):\r
- # An instance variable __missing__ should have no effect\r
- self.__missing__ = lambda key: None\r
- f = F()\r
- with self.assertRaises(KeyError) as c:\r
- f[42]\r
- self.assertEqual(c.exception.args, (42,))\r
-\r
- class G(dict):\r
- pass\r
- g = G()\r
- with self.assertRaises(KeyError) as c:\r
- g[42]\r
- self.assertEqual(c.exception.args, (42,))\r
-\r
- def test_tuple_keyerror(self):\r
- # SF #1576657\r
- d = {}\r
- with self.assertRaises(KeyError) as c:\r
- d[(1,)]\r
- self.assertEqual(c.exception.args, ((1,),))\r
-\r
- def test_bad_key(self):\r
- # Dictionary lookups should fail if __cmp__() raises an exception.\r
- class CustomException(Exception):\r
- pass\r
-\r
- class BadDictKey:\r
- def __hash__(self):\r
- return hash(self.__class__)\r
-\r
- def __cmp__(self, other):\r
- if isinstance(other, self.__class__):\r
- raise CustomException\r
- return other\r
-\r
- d = {}\r
- x1 = BadDictKey()\r
- x2 = BadDictKey()\r
- d[x1] = 1\r
- for stmt in ['d[x2] = 2',\r
- 'z = d[x2]',\r
- 'x2 in d',\r
- 'd.has_key(x2)',\r
- 'd.get(x2)',\r
- 'd.setdefault(x2, 42)',\r
- 'd.pop(x2)',\r
- 'd.update({x2: 2})']:\r
- with self.assertRaises(CustomException):\r
- exec stmt in locals()\r
-\r
- def test_resize1(self):\r
- # Dict resizing bug, found by Jack Jansen in 2.2 CVS development.\r
- # This version got an assert failure in debug build, infinite loop in\r
- # release build. Unfortunately, provoking this kind of stuff requires\r
- # a mix of inserts and deletes hitting exactly the right hash codes in\r
- # exactly the right order, and I can't think of a randomized approach\r
- # that would be *likely* to hit a failing case in reasonable time.\r
-\r
- d = {}\r
- for i in range(5):\r
- d[i] = i\r
- for i in range(5):\r
- del d[i]\r
- for i in range(5, 9): # i==8 was the problem\r
- d[i] = i\r
-\r
- def test_resize2(self):\r
- # Another dict resizing bug (SF bug #1456209).\r
- # This caused Segmentation faults or Illegal instructions.\r
-\r
- class X(object):\r
- def __hash__(self):\r
- return 5\r
- def __eq__(self, other):\r
- if resizing:\r
- d.clear()\r
- return False\r
- d = {}\r
- resizing = False\r
- d[X()] = 1\r
- d[X()] = 2\r
- d[X()] = 3\r
- d[X()] = 4\r
- d[X()] = 5\r
- # now trigger a resize\r
- resizing = True\r
- d[9] = 6\r
-\r
- def test_empty_presized_dict_in_freelist(self):\r
- # Bug #3537: if an empty but presized dict with a size larger\r
- # than 7 was in the freelist, it triggered an assertion failure\r
- with self.assertRaises(ZeroDivisionError):\r
- d = {'a': 1 // 0, 'b': None, 'c': None, 'd': None, 'e': None,\r
- 'f': None, 'g': None, 'h': None}\r
- d = {}\r
-\r
- def test_container_iterator(self):\r
- # Bug #3680: tp_traverse was not implemented for dictiter objects\r
- class C(object):\r
- pass\r
- iterators = (dict.iteritems, dict.itervalues, dict.iterkeys)\r
- for i in iterators:\r
- obj = C()\r
- ref = weakref.ref(obj)\r
- container = {obj: 1}\r
- obj.x = i(container)\r
- del obj, container\r
- gc.collect()\r
- self.assertIs(ref(), None, "Cycle was not collected")\r
-\r
- def _not_tracked(self, t):\r
- # Nested containers can take several collections to untrack\r
- gc.collect()\r
- gc.collect()\r
- self.assertFalse(gc.is_tracked(t), t)\r
-\r
- def _tracked(self, t):\r
- self.assertTrue(gc.is_tracked(t), t)\r
- gc.collect()\r
- gc.collect()\r
- self.assertTrue(gc.is_tracked(t), t)\r
-\r
- @test_support.cpython_only\r
- def test_track_literals(self):\r
- # Test GC-optimization of dict literals\r
- x, y, z, w = 1.5, "a", (1, None), []\r
-\r
- self._not_tracked({})\r
- self._not_tracked({x:(), y:x, z:1})\r
- self._not_tracked({1: "a", "b": 2})\r
- self._not_tracked({1: 2, (None, True, False, ()): int})\r
- self._not_tracked({1: object()})\r
-\r
- # Dicts with mutable elements are always tracked, even if those\r
- # elements are not tracked right now.\r
- self._tracked({1: []})\r
- self._tracked({1: ([],)})\r
- self._tracked({1: {}})\r
- self._tracked({1: set()})\r
-\r
- @test_support.cpython_only\r
- def test_track_dynamic(self):\r
- # Test GC-optimization of dynamically-created dicts\r
- class MyObject(object):\r
- pass\r
- x, y, z, w, o = 1.5, "a", (1, object()), [], MyObject()\r
-\r
- d = dict()\r
- self._not_tracked(d)\r
- d[1] = "a"\r
- self._not_tracked(d)\r
- d[y] = 2\r
- self._not_tracked(d)\r
- d[z] = 3\r
- self._not_tracked(d)\r
- self._not_tracked(d.copy())\r
- d[4] = w\r
- self._tracked(d)\r
- self._tracked(d.copy())\r
- d[4] = None\r
- self._not_tracked(d)\r
- self._not_tracked(d.copy())\r
-\r
- # dd isn't tracked right now, but it may mutate and therefore d\r
- # which contains it must be tracked.\r
- d = dict()\r
- dd = dict()\r
- d[1] = dd\r
- self._not_tracked(dd)\r
- self._tracked(d)\r
- dd[1] = d\r
- self._tracked(dd)\r
-\r
- d = dict.fromkeys([x, y, z])\r
- self._not_tracked(d)\r
- dd = dict()\r
- dd.update(d)\r
- self._not_tracked(dd)\r
- d = dict.fromkeys([x, y, z, o])\r
- self._tracked(d)\r
- dd = dict()\r
- dd.update(d)\r
- self._tracked(dd)\r
-\r
- d = dict(x=x, y=y, z=z)\r
- self._not_tracked(d)\r
- d = dict(x=x, y=y, z=z, w=w)\r
- self._tracked(d)\r
- d = dict()\r
- d.update(x=x, y=y, z=z)\r
- self._not_tracked(d)\r
- d.update(w=w)\r
- self._tracked(d)\r
-\r
- d = dict([(x, y), (z, 1)])\r
- self._not_tracked(d)\r
- d = dict([(x, y), (z, w)])\r
- self._tracked(d)\r
- d = dict()\r
- d.update([(x, y), (z, 1)])\r
- self._not_tracked(d)\r
- d.update([(x, y), (z, w)])\r
- self._tracked(d)\r
-\r
- @test_support.cpython_only\r
- def test_track_subtypes(self):\r
- # Dict subtypes are always tracked\r
- class MyDict(dict):\r
- pass\r
- self._tracked(MyDict())\r
-\r
-\r
-from test import mapping_tests\r
-\r
-class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):\r
- type2test = dict\r
-\r
-class Dict(dict):\r
- pass\r
-\r
-class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):\r
- type2test = Dict\r
-\r
-def test_main():\r
- with test_support.check_py3k_warnings(\r
- ('dict(.has_key..| inequality comparisons) not supported in 3.x',\r
- DeprecationWarning)):\r
- test_support.run_unittest(\r
- DictTest,\r
- GeneralMappingTests,\r
- SubclassMappingTests,\r
- )\r
-\r
-if __name__ == "__main__":\r
- test_main()\r