1# Check every path through every method of UserDict 2 3from test import mapping_tests 4import unittest 5import collections 6 7d0 = {} 8d1 = {"one": 1} 9d2 = {"one": 1, "two": 2} 10d3 = {"one": 1, "two": 3, "three": 5} 11d4 = {"one": None, "two": None} 12d5 = {"one": 1, "two": 1} 13 14class UserDictTest(mapping_tests.TestHashMappingProtocol): 15 type2test = collections.UserDict 16 17 def test_all(self): 18 # Test constructors 19 u = collections.UserDict() 20 u0 = collections.UserDict(d0) 21 u1 = collections.UserDict(d1) 22 u2 = collections.UserDict(d2) 23 24 uu = collections.UserDict(u) 25 uu0 = collections.UserDict(u0) 26 uu1 = collections.UserDict(u1) 27 uu2 = collections.UserDict(u2) 28 29 # keyword arg constructor 30 self.assertEqual(collections.UserDict(one=1, two=2), d2) 31 # item sequence constructor 32 self.assertEqual(collections.UserDict([('one',1), ('two',2)]), d2) 33 self.assertEqual(collections.UserDict(dict=[('one',1), ('two',2)]), 34 {'dict': [('one', 1), ('two', 2)]}) 35 # both together 36 self.assertEqual(collections.UserDict([('one',1), ('two',2)], two=3, three=5), d3) 37 38 # alternate constructor 39 self.assertEqual(collections.UserDict.fromkeys('one two'.split()), d4) 40 self.assertEqual(collections.UserDict().fromkeys('one two'.split()), d4) 41 self.assertEqual(collections.UserDict.fromkeys('one two'.split(), 1), d5) 42 self.assertEqual(collections.UserDict().fromkeys('one two'.split(), 1), d5) 43 self.assertTrue(u1.fromkeys('one two'.split()) is not u1) 44 self.assertIsInstance(u1.fromkeys('one two'.split()), collections.UserDict) 45 self.assertIsInstance(u2.fromkeys('one two'.split()), collections.UserDict) 46 47 # Test __repr__ 48 self.assertEqual(str(u0), str(d0)) 49 self.assertEqual(repr(u1), repr(d1)) 50 self.assertIn(repr(u2), ("{'one': 1, 'two': 2}", 51 "{'two': 2, 'one': 1}")) 52 53 # Test rich comparison and __len__ 54 all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2] 55 for a in all: 56 for b in all: 57 self.assertEqual(a == b, len(a) == len(b)) 58 59 # Test __getitem__ 60 self.assertEqual(u2["one"], 1) 61 self.assertRaises(KeyError, u1.__getitem__, "two") 62 63 # Test __setitem__ 64 u3 = collections.UserDict(u2) 65 u3["two"] = 2 66 u3["three"] = 3 67 68 # Test __delitem__ 69 del u3["three"] 70 self.assertRaises(KeyError, u3.__delitem__, "three") 71 72 # Test clear 73 u3.clear() 74 self.assertEqual(u3, {}) 75 76 # Test copy() 77 u2a = u2.copy() 78 self.assertEqual(u2a, u2) 79 u2b = collections.UserDict(x=42, y=23) 80 u2c = u2b.copy() # making a copy of a UserDict is special cased 81 self.assertEqual(u2b, u2c) 82 83 class MyUserDict(collections.UserDict): 84 def display(self): print(self) 85 86 m2 = MyUserDict(u2) 87 m2a = m2.copy() 88 self.assertEqual(m2a, m2) 89 90 # SF bug #476616 -- copy() of UserDict subclass shared data 91 m2['foo'] = 'bar' 92 self.assertNotEqual(m2a, m2) 93 94 # Test keys, items, values 95 self.assertEqual(sorted(u2.keys()), sorted(d2.keys())) 96 self.assertEqual(sorted(u2.items()), sorted(d2.items())) 97 self.assertEqual(sorted(u2.values()), sorted(d2.values())) 98 99 # Test "in". 100 for i in u2.keys(): 101 self.assertIn(i, u2) 102 self.assertEqual(i in u1, i in d1) 103 self.assertEqual(i in u0, i in d0) 104 105 # Test update 106 t = collections.UserDict() 107 t.update(u2) 108 self.assertEqual(t, u2) 109 110 # Test get 111 for i in u2.keys(): 112 self.assertEqual(u2.get(i), u2[i]) 113 self.assertEqual(u1.get(i), d1.get(i)) 114 self.assertEqual(u0.get(i), d0.get(i)) 115 116 # Test "in" iteration. 117 for i in range(20): 118 u2[i] = str(i) 119 ikeys = [] 120 for k in u2: 121 ikeys.append(k) 122 keys = u2.keys() 123 self.assertEqual(set(ikeys), set(keys)) 124 125 # Test setdefault 126 t = collections.UserDict() 127 self.assertEqual(t.setdefault("x", 42), 42) 128 self.assertIn("x", t) 129 self.assertEqual(t.setdefault("x", 23), 42) 130 131 # Test pop 132 t = collections.UserDict(x=42) 133 self.assertEqual(t.pop("x"), 42) 134 self.assertRaises(KeyError, t.pop, "x") 135 self.assertEqual(t.pop("x", 1), 1) 136 t["x"] = 42 137 self.assertEqual(t.pop("x", 1), 42) 138 139 # Test popitem 140 t = collections.UserDict(x=42) 141 self.assertEqual(t.popitem(), ("x", 42)) 142 self.assertRaises(KeyError, t.popitem) 143 144 def test_init(self): 145 for kw in 'self', 'other', 'iterable': 146 self.assertEqual(list(collections.UserDict(**{kw: 42}).items()), 147 [(kw, 42)]) 148 self.assertEqual(list(collections.UserDict({}, dict=42).items()), 149 [('dict', 42)]) 150 self.assertEqual(list(collections.UserDict({}, dict=None).items()), 151 [('dict', None)]) 152 self.assertEqual(list(collections.UserDict(dict={'a': 42}).items()), 153 [('dict', {'a': 42})]) 154 self.assertRaises(TypeError, collections.UserDict, 42) 155 self.assertRaises(TypeError, collections.UserDict, (), ()) 156 self.assertRaises(TypeError, collections.UserDict.__init__) 157 158 def test_update(self): 159 for kw in 'self', 'dict', 'other', 'iterable': 160 d = collections.UserDict() 161 d.update(**{kw: 42}) 162 self.assertEqual(list(d.items()), [(kw, 42)]) 163 self.assertRaises(TypeError, collections.UserDict().update, 42) 164 self.assertRaises(TypeError, collections.UserDict().update, {}, {}) 165 self.assertRaises(TypeError, collections.UserDict.update) 166 167 def test_missing(self): 168 # Make sure UserDict doesn't have a __missing__ method 169 self.assertEqual(hasattr(collections.UserDict, "__missing__"), False) 170 # Test several cases: 171 # (D) subclass defines __missing__ method returning a value 172 # (E) subclass defines __missing__ method raising RuntimeError 173 # (F) subclass sets __missing__ instance variable (no effect) 174 # (G) subclass doesn't define __missing__ at all 175 class D(collections.UserDict): 176 def __missing__(self, key): 177 return 42 178 d = D({1: 2, 3: 4}) 179 self.assertEqual(d[1], 2) 180 self.assertEqual(d[3], 4) 181 self.assertNotIn(2, d) 182 self.assertNotIn(2, d.keys()) 183 self.assertEqual(d[2], 42) 184 class E(collections.UserDict): 185 def __missing__(self, key): 186 raise RuntimeError(key) 187 e = E() 188 try: 189 e[42] 190 except RuntimeError as err: 191 self.assertEqual(err.args, (42,)) 192 else: 193 self.fail("e[42] didn't raise RuntimeError") 194 class F(collections.UserDict): 195 def __init__(self): 196 # An instance variable __missing__ should have no effect 197 self.__missing__ = lambda key: None 198 collections.UserDict.__init__(self) 199 f = F() 200 try: 201 f[42] 202 except KeyError as err: 203 self.assertEqual(err.args, (42,)) 204 else: 205 self.fail("f[42] didn't raise KeyError") 206 class G(collections.UserDict): 207 pass 208 g = G() 209 try: 210 g[42] 211 except KeyError as err: 212 self.assertEqual(err.args, (42,)) 213 else: 214 self.fail("g[42] didn't raise KeyError") 215 216 217 218if __name__ == "__main__": 219 unittest.main() 220