aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_dict.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_dict.py')
-rw-r--r--Lib/test/test_dict.py223
1 files changed, 163 insertions, 60 deletions
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 0840f59799b..9666f9a31cf 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -1,11 +1,21 @@
import unittest
-from test import test_support
+from test import support
-import UserDict, random, string
+import collections, random, string
import gc, weakref
class DictTest(unittest.TestCase):
+
+ def test_invalid_keyword_arguments(self):
+ class Custom(dict):
+ pass
+ for invalid in {1 : 2}, Custom({1 : 2}):
+ with self.assertRaises(TypeError):
+ dict(**invalid)
+ with self.assertRaises(TypeError):
+ {}.update(**invalid)
+
def test_constructor(self):
# calling built-in types without argument must return empty
self.assertEqual(dict(), {})
@@ -15,7 +25,7 @@ class DictTest(unittest.TestCase):
# check literal constructor for different sized dicts
# (to exercise the BUILD_MAP oparg).
for n in (0, 1, 6, 256, 400):
- items = [(''.join(random.sample(string.letters, 8)), i)
+ items = [(''.join(random.sample(string.ascii_letters, 8)), i)
for i in range(n)]
random.shuffle(items)
formatted_items = ('{!r}: {:d}'.format(k, v) for k, v in items)
@@ -30,40 +40,30 @@ class DictTest(unittest.TestCase):
def test_keys(self):
d = {}
- self.assertEqual(d.keys(), [])
+ self.assertEqual(set(d.keys()), set())
d = {'a': 1, 'b': 2}
k = d.keys()
- self.assertTrue(d.has_key('a'))
- self.assertTrue(d.has_key('b'))
-
+ self.assertIn('a', d)
+ self.assertIn('b', d)
self.assertRaises(TypeError, d.keys, None)
+ self.assertEqual(repr(dict(a=1).keys()), "dict_keys(['a'])")
def test_values(self):
d = {}
- self.assertEqual(d.values(), [])
+ self.assertEqual(set(d.values()), set())
d = {1:2}
- self.assertEqual(d.values(), [2])
-
+ self.assertEqual(set(d.values()), {2})
self.assertRaises(TypeError, d.values, None)
+ self.assertEqual(repr(dict(a=1).values()), "dict_values([1])")
def test_items(self):
d = {}
- self.assertEqual(d.items(), [])
+ self.assertEqual(set(d.items()), set())
d = {1:2}
- self.assertEqual(d.items(), [(1, 2)])
-
+ self.assertEqual(set(d.items()), {(1, 2)})
self.assertRaises(TypeError, d.items, None)
-
- def test_has_key(self):
- d = {}
- self.assertFalse(d.has_key('a'))
- d = {'a': 1, 'b': 2}
- k = d.keys()
- k.sort()
- self.assertEqual(k, ['a', 'b'])
-
- self.assertRaises(TypeError, d.has_key)
+ self.assertEqual(repr(dict(a=1).items()), "dict_items([('a', 1)])")
def test_contains(self):
d = {}
@@ -166,7 +166,7 @@ class DictTest(unittest.TestCase):
self.i = 1
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
if self.i:
self.i = 0
return 'a'
@@ -183,7 +183,7 @@ class DictTest(unittest.TestCase):
self.i = ord('a')
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
if self.i <= ord('z'):
rtn = chr(self.i)
self.i += 1
@@ -197,7 +197,7 @@ class DictTest(unittest.TestCase):
class badseq(object):
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
raise Exc()
self.assertRaises(Exc, {}.update, badseq())
@@ -222,10 +222,10 @@ class DictTest(unittest.TestCase):
self.assertIsInstance(dictlike().fromkeys('a'), dictlike)
class mydict(dict):
def __new__(cls):
- return UserDict.UserDict()
+ return collections.UserDict()
ud = mydict.fromkeys('ab')
self.assertEqual(ud, {'a':None, 'b':None})
- self.assertIsInstance(ud, UserDict.UserDict)
+ self.assertIsInstance(ud, collections.UserDict)
self.assertRaises(TypeError, dict.fromkeys)
class Exc(Exception): pass
@@ -239,7 +239,7 @@ class DictTest(unittest.TestCase):
class BadSeq(object):
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
raise Exc()
self.assertRaises(Exc, dict.fromkeys, BadSeq())
@@ -366,13 +366,6 @@ class DictTest(unittest.TestCase):
self.assertRaises(KeyError, d.pop, k)
- # verify longs/ints get same value when key > 32 bits
- # (for 64-bit archs). See SF bug #689659.
- x = 4503599627370496L
- y = 4503599627370496
- h = {x: 'anything', y: 'something else'}
- self.assertEqual(h[x], h[y])
-
self.assertEqual(d.pop(k, v), v)
d[k] = v
self.assertEqual(d.pop(k, 1), v)
@@ -420,9 +413,9 @@ class DictTest(unittest.TestCase):
d = {1: BadRepr()}
self.assertRaises(Exc, repr, d)
- def test_le(self):
- self.assertFalse({} < {})
- self.assertFalse({1: 2} < {1L: 2L})
+ def test_eq(self):
+ self.assertEqual({}, {})
+ self.assertEqual({1: 2}, {1: 2})
class Exc(Exception): pass
@@ -430,13 +423,125 @@ class DictTest(unittest.TestCase):
def __eq__(self, other):
raise Exc()
def __hash__(self):
- return 42
+ return 1
d1 = {BadCmp(): 1}
d2 = {1: 1}
with self.assertRaises(Exc):
- d1 < d2
+ d1 == d2
+
+ def test_keys_contained(self):
+ self.helper_keys_contained(lambda x: x.keys())
+ self.helper_keys_contained(lambda x: x.items())
+
+ def helper_keys_contained(self, fn):
+ # Test rich comparisons against dict key views, which should behave the
+ # same as sets.
+ empty = fn(dict())
+ empty2 = fn(dict())
+ smaller = fn({1:1, 2:2})
+ larger = fn({1:1, 2:2, 3:3})
+ larger2 = fn({1:1, 2:2, 3:3})
+ larger3 = fn({4:1, 2:2, 3:3})
+
+ self.assertTrue(smaller < larger)
+ self.assertTrue(smaller <= larger)
+ self.assertTrue(larger > smaller)
+ self.assertTrue(larger >= smaller)
+
+ self.assertFalse(smaller >= larger)
+ self.assertFalse(smaller > larger)
+ self.assertFalse(larger <= smaller)
+ self.assertFalse(larger < smaller)
+
+ self.assertFalse(smaller < larger3)
+ self.assertFalse(smaller <= larger3)
+ self.assertFalse(larger3 > smaller)
+ self.assertFalse(larger3 >= smaller)
+
+ # Inequality strictness
+ self.assertTrue(larger2 >= larger)
+ self.assertTrue(larger2 <= larger)
+ self.assertFalse(larger2 > larger)
+ self.assertFalse(larger2 < larger)
+
+ self.assertTrue(larger == larger2)
+ self.assertTrue(smaller != larger)
+
+ # There is an optimization on the zero-element case.
+ self.assertTrue(empty == empty2)
+ self.assertFalse(empty != empty2)
+ self.assertFalse(empty == smaller)
+ self.assertTrue(empty != smaller)
+
+ # With the same size, an elementwise compare happens
+ self.assertTrue(larger != larger3)
+ self.assertFalse(larger == larger3)
+
+ def test_errors_in_view_containment_check(self):
+ class C:
+ def __eq__(self, other):
+ raise RuntimeError
+
+ d1 = {1: C()}
+ d2 = {1: C()}
+ with self.assertRaises(RuntimeError):
+ d1.items() == d2.items()
+ with self.assertRaises(RuntimeError):
+ d1.items() != d2.items()
+ with self.assertRaises(RuntimeError):
+ d1.items() <= d2.items()
+ with self.assertRaises(RuntimeError):
+ d1.items() >= d2.items()
+
+ d3 = {1: C(), 2: C()}
+ with self.assertRaises(RuntimeError):
+ d2.items() < d3.items()
+ with self.assertRaises(RuntimeError):
+ d3.items() > d2.items()
+
+ def test_dictview_set_operations_on_keys(self):
+ k1 = {1:1, 2:2}.keys()
+ k2 = {1:1, 2:2, 3:3}.keys()
+ k3 = {4:4}.keys()
+
+ self.assertEqual(k1 - k2, set())
+ self.assertEqual(k1 - k3, {1,2})
+ self.assertEqual(k2 - k1, {3})
+ self.assertEqual(k3 - k1, {4})
+ self.assertEqual(k1 & k2, {1,2})
+ self.assertEqual(k1 & k3, set())
+ self.assertEqual(k1 | k2, {1,2,3})
+ self.assertEqual(k1 ^ k2, {3})
+ self.assertEqual(k1 ^ k3, {1,2,4})
+
+ def test_dictview_set_operations_on_items(self):
+ k1 = {1:1, 2:2}.items()
+ k2 = {1:1, 2:2, 3:3}.items()
+ k3 = {4:4}.items()
+
+ self.assertEqual(k1 - k2, set())
+ self.assertEqual(k1 - k3, {(1,1), (2,2)})
+ self.assertEqual(k2 - k1, {(3,3)})
+ self.assertEqual(k3 - k1, {(4,4)})
+ self.assertEqual(k1 & k2, {(1,1), (2,2)})
+ self.assertEqual(k1 & k3, set())
+ self.assertEqual(k1 | k2, {(1,1), (2,2), (3,3)})
+ self.assertEqual(k1 ^ k2, {(3,3)})
+ self.assertEqual(k1 ^ k3, {(1,1), (2,2), (4,4)})
+
+ def test_dictview_mixed_set_operations(self):
+ # Just a few for .keys()
+ self.assertTrue({1:1}.keys() == {1})
+ self.assertTrue({1} == {1:1}.keys())
+ self.assertEqual({1:1}.keys() | {2}, {1, 2})
+ self.assertEqual({2} | {1:1}.keys(), {1, 2})
+ # And a few for .items()
+ self.assertTrue({1:1}.items() == {(1,1)})
+ self.assertTrue({(1,1)} == {1:1}.items())
+ self.assertEqual({1:1}.items() | {2}, {(1,1), 2})
+ self.assertEqual({2} | {1:1}.items(), {(1,1), 2})
def test_missing(self):
# Make sure dict doesn't have a __missing__ method
@@ -489,7 +594,7 @@ class DictTest(unittest.TestCase):
self.assertEqual(c.exception.args, ((1,),))
def test_bad_key(self):
- # Dictionary lookups should fail if __cmp__() raises an exception.
+ # Dictionary lookups should fail if __eq__() raises an exception.
class CustomException(Exception):
pass
@@ -497,7 +602,7 @@ class DictTest(unittest.TestCase):
def __hash__(self):
return hash(self.__class__)
- def __cmp__(self, other):
+ def __eq__(self, other):
if isinstance(other, self.__class__):
raise CustomException
return other
@@ -509,13 +614,12 @@ class DictTest(unittest.TestCase):
for stmt in ['d[x2] = 2',
'z = d[x2]',
'x2 in d',
- 'd.has_key(x2)',
'd.get(x2)',
'd.setdefault(x2, 42)',
'd.pop(x2)',
'd.update({x2: 2})']:
with self.assertRaises(CustomException):
- exec stmt in locals()
+ exec(stmt, locals())
def test_resize1(self):
# Dict resizing bug, found by Jack Jansen in 2.2 CVS development.
@@ -564,15 +668,17 @@ class DictTest(unittest.TestCase):
d = {}
def test_container_iterator(self):
- # Bug #3680: tp_traverse was not implemented for dictiter objects
+ # Bug #3680: tp_traverse was not implemented for dictiter and
+ # dictview objects.
class C(object):
pass
- iterators = (dict.iteritems, dict.itervalues, dict.iterkeys)
- for i in iterators:
+ views = (dict.items, dict.values, dict.keys)
+ for v in views:
obj = C()
ref = weakref.ref(obj)
container = {obj: 1}
- obj.x = i(container)
+ obj.v = v(container)
+ obj.x = iter(obj.v)
del obj, container
gc.collect()
self.assertIs(ref(), None, "Cycle was not collected")
@@ -589,7 +695,7 @@ class DictTest(unittest.TestCase):
gc.collect()
self.assertTrue(gc.is_tracked(t), t)
- @test_support.cpython_only
+ @support.cpython_only
def test_track_literals(self):
# Test GC-optimization of dict literals
x, y, z, w = 1.5, "a", (1, None), []
@@ -607,7 +713,7 @@ class DictTest(unittest.TestCase):
self._tracked({1: {}})
self._tracked({1: set()})
- @test_support.cpython_only
+ @support.cpython_only
def test_track_dynamic(self):
# Test GC-optimization of dynamically-created dicts
class MyObject(object):
@@ -671,7 +777,7 @@ class DictTest(unittest.TestCase):
d.update([(x, y), (z, w)])
self._tracked(d)
- @test_support.cpython_only
+ @support.cpython_only
def test_track_subtypes(self):
# Dict subtypes are always tracked
class MyDict(dict):
@@ -691,14 +797,11 @@ class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
type2test = Dict
def test_main():
- with test_support.check_py3k_warnings(
- ('dict(.has_key..| inequality comparisons) not supported in 3.x',
- DeprecationWarning)):
- test_support.run_unittest(
- DictTest,
- GeneralMappingTests,
- SubclassMappingTests,
- )
+ support.run_unittest(
+ DictTest,
+ GeneralMappingTests,
+ SubclassMappingTests,
+ )
if __name__ == "__main__":
test_main()