1import collections.abc 2import copy 3import pickle 4import sys 5import unittest 6 7class DictSetTest(unittest.TestCase): 8 9 def test_constructors_not_callable(self): 10 kt = type({}.keys()) 11 self.assertRaises(TypeError, kt, {}) 12 self.assertRaises(TypeError, kt) 13 it = type({}.items()) 14 self.assertRaises(TypeError, it, {}) 15 self.assertRaises(TypeError, it) 16 vt = type({}.values()) 17 self.assertRaises(TypeError, vt, {}) 18 self.assertRaises(TypeError, vt) 19 20 def test_dict_keys(self): 21 d = {1: 10, "a": "ABC"} 22 keys = d.keys() 23 self.assertEqual(len(keys), 2) 24 self.assertEqual(set(keys), {1, "a"}) 25 self.assertEqual(keys, {1, "a"}) 26 self.assertNotEqual(keys, {1, "a", "b"}) 27 self.assertNotEqual(keys, {1, "b"}) 28 self.assertNotEqual(keys, {1}) 29 self.assertNotEqual(keys, 42) 30 self.assertIn(1, keys) 31 self.assertIn("a", keys) 32 self.assertNotIn(10, keys) 33 self.assertNotIn("Z", keys) 34 self.assertEqual(d.keys(), d.keys()) 35 e = {1: 11, "a": "def"} 36 self.assertEqual(d.keys(), e.keys()) 37 del e["a"] 38 self.assertNotEqual(d.keys(), e.keys()) 39 40 def test_dict_items(self): 41 d = {1: 10, "a": "ABC"} 42 items = d.items() 43 self.assertEqual(len(items), 2) 44 self.assertEqual(set(items), {(1, 10), ("a", "ABC")}) 45 self.assertEqual(items, {(1, 10), ("a", "ABC")}) 46 self.assertNotEqual(items, {(1, 10), ("a", "ABC"), "junk"}) 47 self.assertNotEqual(items, {(1, 10), ("a", "def")}) 48 self.assertNotEqual(items, {(1, 10)}) 49 self.assertNotEqual(items, 42) 50 self.assertIn((1, 10), items) 51 self.assertIn(("a", "ABC"), items) 52 self.assertNotIn((1, 11), items) 53 self.assertNotIn(1, items) 54 self.assertNotIn((), items) 55 self.assertNotIn((1,), items) 56 self.assertNotIn((1, 2, 3), items) 57 self.assertEqual(d.items(), d.items()) 58 e = d.copy() 59 self.assertEqual(d.items(), e.items()) 60 e["a"] = "def" 61 self.assertNotEqual(d.items(), e.items()) 62 63 def test_dict_mixed_keys_items(self): 64 d = {(1, 1): 11, (2, 2): 22} 65 e = {1: 1, 2: 2} 66 self.assertEqual(d.keys(), e.items()) 67 self.assertNotEqual(d.items(), e.keys()) 68 69 def test_dict_values(self): 70 d = {1: 10, "a": "ABC"} 71 values = d.values() 72 self.assertEqual(set(values), {10, "ABC"}) 73 self.assertEqual(len(values), 2) 74 75 def test_dict_repr(self): 76 d = {1: 10, "a": "ABC"} 77 self.assertIsInstance(repr(d), str) 78 r = repr(d.items()) 79 self.assertIsInstance(r, str) 80 self.assertTrue(r == "dict_items([('a', 'ABC'), (1, 10)])" or 81 r == "dict_items([(1, 10), ('a', 'ABC')])") 82 r = repr(d.keys()) 83 self.assertIsInstance(r, str) 84 self.assertTrue(r == "dict_keys(['a', 1])" or 85 r == "dict_keys([1, 'a'])") 86 r = repr(d.values()) 87 self.assertIsInstance(r, str) 88 self.assertTrue(r == "dict_values(['ABC', 10])" or 89 r == "dict_values([10, 'ABC'])") 90 91 def test_keys_set_operations(self): 92 d1 = {'a': 1, 'b': 2} 93 d2 = {'b': 3, 'c': 2} 94 d3 = {'d': 4, 'e': 5} 95 d4 = {'d': 4} 96 97 class CustomSet(set): 98 def intersection(self, other): 99 return CustomSet(super().intersection(other)) 100 101 self.assertEqual(d1.keys() & d1.keys(), {'a', 'b'}) 102 self.assertEqual(d1.keys() & d2.keys(), {'b'}) 103 self.assertEqual(d1.keys() & d3.keys(), set()) 104 self.assertEqual(d1.keys() & set(d1.keys()), {'a', 'b'}) 105 self.assertEqual(d1.keys() & set(d2.keys()), {'b'}) 106 self.assertEqual(d1.keys() & set(d3.keys()), set()) 107 self.assertEqual(d1.keys() & tuple(d1.keys()), {'a', 'b'}) 108 self.assertEqual(d3.keys() & d4.keys(), {'d'}) 109 self.assertEqual(d4.keys() & d3.keys(), {'d'}) 110 self.assertEqual(d4.keys() & set(d3.keys()), {'d'}) 111 self.assertIsInstance(d4.keys() & frozenset(d3.keys()), set) 112 self.assertIsInstance(frozenset(d3.keys()) & d4.keys(), set) 113 self.assertIs(type(d4.keys() & CustomSet(d3.keys())), set) 114 self.assertIs(type(d1.keys() & []), set) 115 self.assertIs(type([] & d1.keys()), set) 116 117 self.assertEqual(d1.keys() | d1.keys(), {'a', 'b'}) 118 self.assertEqual(d1.keys() | d2.keys(), {'a', 'b', 'c'}) 119 self.assertEqual(d1.keys() | d3.keys(), {'a', 'b', 'd', 'e'}) 120 self.assertEqual(d1.keys() | set(d1.keys()), {'a', 'b'}) 121 self.assertEqual(d1.keys() | set(d2.keys()), {'a', 'b', 'c'}) 122 self.assertEqual(d1.keys() | set(d3.keys()), 123 {'a', 'b', 'd', 'e'}) 124 self.assertEqual(d1.keys() | (1, 2), {'a', 'b', 1, 2}) 125 126 self.assertEqual(d1.keys() ^ d1.keys(), set()) 127 self.assertEqual(d1.keys() ^ d2.keys(), {'a', 'c'}) 128 self.assertEqual(d1.keys() ^ d3.keys(), {'a', 'b', 'd', 'e'}) 129 self.assertEqual(d1.keys() ^ set(d1.keys()), set()) 130 self.assertEqual(d1.keys() ^ set(d2.keys()), {'a', 'c'}) 131 self.assertEqual(d1.keys() ^ set(d3.keys()), 132 {'a', 'b', 'd', 'e'}) 133 self.assertEqual(d1.keys() ^ tuple(d2.keys()), {'a', 'c'}) 134 135 self.assertEqual(d1.keys() - d1.keys(), set()) 136 self.assertEqual(d1.keys() - d2.keys(), {'a'}) 137 self.assertEqual(d1.keys() - d3.keys(), {'a', 'b'}) 138 self.assertEqual(d1.keys() - set(d1.keys()), set()) 139 self.assertEqual(d1.keys() - set(d2.keys()), {'a'}) 140 self.assertEqual(d1.keys() - set(d3.keys()), {'a', 'b'}) 141 self.assertEqual(d1.keys() - (0, 1), {'a', 'b'}) 142 143 self.assertFalse(d1.keys().isdisjoint(d1.keys())) 144 self.assertFalse(d1.keys().isdisjoint(d2.keys())) 145 self.assertFalse(d1.keys().isdisjoint(list(d2.keys()))) 146 self.assertFalse(d1.keys().isdisjoint(set(d2.keys()))) 147 self.assertTrue(d1.keys().isdisjoint({'x', 'y', 'z'})) 148 self.assertTrue(d1.keys().isdisjoint(['x', 'y', 'z'])) 149 self.assertTrue(d1.keys().isdisjoint(set(['x', 'y', 'z']))) 150 self.assertTrue(d1.keys().isdisjoint(set(['x', 'y']))) 151 self.assertTrue(d1.keys().isdisjoint(['x', 'y'])) 152 self.assertTrue(d1.keys().isdisjoint({})) 153 self.assertTrue(d1.keys().isdisjoint(d3.keys())) 154 155 de = {} 156 self.assertTrue(de.keys().isdisjoint(set())) 157 self.assertTrue(de.keys().isdisjoint([])) 158 self.assertTrue(de.keys().isdisjoint(de.keys())) 159 self.assertTrue(de.keys().isdisjoint([1])) 160 161 def test_items_set_operations(self): 162 d1 = {'a': 1, 'b': 2} 163 d2 = {'a': 2, 'b': 2} 164 d3 = {'d': 4, 'e': 5} 165 self.assertEqual( 166 d1.items() & d1.items(), {('a', 1), ('b', 2)}) 167 self.assertEqual(d1.items() & d2.items(), {('b', 2)}) 168 self.assertEqual(d1.items() & d3.items(), set()) 169 self.assertEqual(d1.items() & set(d1.items()), 170 {('a', 1), ('b', 2)}) 171 self.assertEqual(d1.items() & set(d2.items()), {('b', 2)}) 172 self.assertEqual(d1.items() & set(d3.items()), set()) 173 174 self.assertEqual(d1.items() | d1.items(), 175 {('a', 1), ('b', 2)}) 176 self.assertEqual(d1.items() | d2.items(), 177 {('a', 1), ('a', 2), ('b', 2)}) 178 self.assertEqual(d1.items() | d3.items(), 179 {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) 180 self.assertEqual(d1.items() | set(d1.items()), 181 {('a', 1), ('b', 2)}) 182 self.assertEqual(d1.items() | set(d2.items()), 183 {('a', 1), ('a', 2), ('b', 2)}) 184 self.assertEqual(d1.items() | set(d3.items()), 185 {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) 186 187 self.assertEqual(d1.items() ^ d1.items(), set()) 188 self.assertEqual(d1.items() ^ d2.items(), 189 {('a', 1), ('a', 2)}) 190 self.assertEqual(d1.items() ^ d3.items(), 191 {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) 192 193 self.assertEqual(d1.items() - d1.items(), set()) 194 self.assertEqual(d1.items() - d2.items(), {('a', 1)}) 195 self.assertEqual(d1.items() - d3.items(), {('a', 1), ('b', 2)}) 196 self.assertEqual(d1.items() - set(d1.items()), set()) 197 self.assertEqual(d1.items() - set(d2.items()), {('a', 1)}) 198 self.assertEqual(d1.items() - set(d3.items()), {('a', 1), ('b', 2)}) 199 200 self.assertFalse(d1.items().isdisjoint(d1.items())) 201 self.assertFalse(d1.items().isdisjoint(d2.items())) 202 self.assertFalse(d1.items().isdisjoint(list(d2.items()))) 203 self.assertFalse(d1.items().isdisjoint(set(d2.items()))) 204 self.assertTrue(d1.items().isdisjoint({'x', 'y', 'z'})) 205 self.assertTrue(d1.items().isdisjoint(['x', 'y', 'z'])) 206 self.assertTrue(d1.items().isdisjoint(set(['x', 'y', 'z']))) 207 self.assertTrue(d1.items().isdisjoint(set(['x', 'y']))) 208 self.assertTrue(d1.items().isdisjoint({})) 209 self.assertTrue(d1.items().isdisjoint(d3.items())) 210 211 de = {} 212 self.assertTrue(de.items().isdisjoint(set())) 213 self.assertTrue(de.items().isdisjoint([])) 214 self.assertTrue(de.items().isdisjoint(de.items())) 215 self.assertTrue(de.items().isdisjoint([1])) 216 217 def test_set_operations_with_iterator(self): 218 origin = {1: 2, 3: 4} 219 self.assertEqual(origin.keys() & iter([1, 2]), {1}) 220 self.assertEqual(origin.keys() | iter([1, 2]), {1, 2, 3}) 221 self.assertEqual(origin.keys() ^ iter([1, 2]), {2, 3}) 222 self.assertEqual(origin.keys() - iter([1, 2]), {3}) 223 224 items = origin.items() 225 self.assertEqual(items & iter([(1, 2)]), {(1, 2)}) 226 self.assertEqual(items ^ iter([(1, 2)]), {(3, 4)}) 227 self.assertEqual(items | iter([(1, 2)]), {(1, 2), (3, 4)}) 228 self.assertEqual(items - iter([(1, 2)]), {(3, 4)}) 229 230 def test_set_operations_with_noniterable(self): 231 with self.assertRaises(TypeError): 232 {}.keys() & 1 233 with self.assertRaises(TypeError): 234 {}.keys() | 1 235 with self.assertRaises(TypeError): 236 {}.keys() ^ 1 237 with self.assertRaises(TypeError): 238 {}.keys() - 1 239 240 with self.assertRaises(TypeError): 241 {}.items() & 1 242 with self.assertRaises(TypeError): 243 {}.items() | 1 244 with self.assertRaises(TypeError): 245 {}.items() ^ 1 246 with self.assertRaises(TypeError): 247 {}.items() - 1 248 249 def test_recursive_repr(self): 250 d = {} 251 d[42] = d.values() 252 r = repr(d) 253 # Cannot perform a stronger test, as the contents of the repr 254 # are implementation-dependent. All we can say is that we 255 # want a str result, not an exception of any sort. 256 self.assertIsInstance(r, str) 257 d[42] = d.items() 258 r = repr(d) 259 # Again. 260 self.assertIsInstance(r, str) 261 262 def test_deeply_nested_repr(self): 263 d = {} 264 for i in range(sys.getrecursionlimit() + 100): 265 d = {42: d.values()} 266 self.assertRaises(RecursionError, repr, d) 267 268 def test_copy(self): 269 d = {1: 10, "a": "ABC"} 270 self.assertRaises(TypeError, copy.copy, d.keys()) 271 self.assertRaises(TypeError, copy.copy, d.values()) 272 self.assertRaises(TypeError, copy.copy, d.items()) 273 274 def test_compare_error(self): 275 class Exc(Exception): 276 pass 277 278 class BadEq: 279 def __hash__(self): 280 return 7 281 def __eq__(self, other): 282 raise Exc 283 284 k1, k2 = BadEq(), BadEq() 285 v1, v2 = BadEq(), BadEq() 286 d = {k1: v1} 287 288 self.assertIn(k1, d) 289 self.assertIn(k1, d.keys()) 290 self.assertIn(v1, d.values()) 291 self.assertIn((k1, v1), d.items()) 292 293 self.assertRaises(Exc, d.__contains__, k2) 294 self.assertRaises(Exc, d.keys().__contains__, k2) 295 self.assertRaises(Exc, d.items().__contains__, (k2, v1)) 296 self.assertRaises(Exc, d.items().__contains__, (k1, v2)) 297 with self.assertRaises(Exc): 298 v2 in d.values() 299 300 def test_pickle(self): 301 d = {1: 10, "a": "ABC"} 302 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 303 self.assertRaises((TypeError, pickle.PicklingError), 304 pickle.dumps, d.keys(), proto) 305 self.assertRaises((TypeError, pickle.PicklingError), 306 pickle.dumps, d.values(), proto) 307 self.assertRaises((TypeError, pickle.PicklingError), 308 pickle.dumps, d.items(), proto) 309 310 def test_abc_registry(self): 311 d = dict(a=1) 312 313 self.assertIsInstance(d.keys(), collections.abc.KeysView) 314 self.assertIsInstance(d.keys(), collections.abc.MappingView) 315 self.assertIsInstance(d.keys(), collections.abc.Set) 316 self.assertIsInstance(d.keys(), collections.abc.Sized) 317 self.assertIsInstance(d.keys(), collections.abc.Iterable) 318 self.assertIsInstance(d.keys(), collections.abc.Container) 319 320 self.assertIsInstance(d.values(), collections.abc.ValuesView) 321 self.assertIsInstance(d.values(), collections.abc.MappingView) 322 self.assertIsInstance(d.values(), collections.abc.Sized) 323 324 self.assertIsInstance(d.items(), collections.abc.ItemsView) 325 self.assertIsInstance(d.items(), collections.abc.MappingView) 326 self.assertIsInstance(d.items(), collections.abc.Set) 327 self.assertIsInstance(d.items(), collections.abc.Sized) 328 self.assertIsInstance(d.items(), collections.abc.Iterable) 329 self.assertIsInstance(d.items(), collections.abc.Container) 330 331 332if __name__ == "__main__": 333 unittest.main() 334