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 self.assertEqual(d1.keys() & d1.keys(), {'a', 'b'}) 96 self.assertEqual(d1.keys() & d2.keys(), {'b'}) 97 self.assertEqual(d1.keys() & d3.keys(), set()) 98 self.assertEqual(d1.keys() & set(d1.keys()), {'a', 'b'}) 99 self.assertEqual(d1.keys() & set(d2.keys()), {'b'}) 100 self.assertEqual(d1.keys() & set(d3.keys()), set()) 101 self.assertEqual(d1.keys() & tuple(d1.keys()), {'a', 'b'}) 102 103 self.assertEqual(d1.keys() | d1.keys(), {'a', 'b'}) 104 self.assertEqual(d1.keys() | d2.keys(), {'a', 'b', 'c'}) 105 self.assertEqual(d1.keys() | d3.keys(), {'a', 'b', 'd', 'e'}) 106 self.assertEqual(d1.keys() | set(d1.keys()), {'a', 'b'}) 107 self.assertEqual(d1.keys() | set(d2.keys()), {'a', 'b', 'c'}) 108 self.assertEqual(d1.keys() | set(d3.keys()), 109 {'a', 'b', 'd', 'e'}) 110 self.assertEqual(d1.keys() | (1, 2), {'a', 'b', 1, 2}) 111 112 self.assertEqual(d1.keys() ^ d1.keys(), set()) 113 self.assertEqual(d1.keys() ^ d2.keys(), {'a', 'c'}) 114 self.assertEqual(d1.keys() ^ d3.keys(), {'a', 'b', 'd', 'e'}) 115 self.assertEqual(d1.keys() ^ set(d1.keys()), set()) 116 self.assertEqual(d1.keys() ^ set(d2.keys()), {'a', 'c'}) 117 self.assertEqual(d1.keys() ^ set(d3.keys()), 118 {'a', 'b', 'd', 'e'}) 119 self.assertEqual(d1.keys() ^ tuple(d2.keys()), {'a', 'c'}) 120 121 self.assertEqual(d1.keys() - d1.keys(), set()) 122 self.assertEqual(d1.keys() - d2.keys(), {'a'}) 123 self.assertEqual(d1.keys() - d3.keys(), {'a', 'b'}) 124 self.assertEqual(d1.keys() - set(d1.keys()), set()) 125 self.assertEqual(d1.keys() - set(d2.keys()), {'a'}) 126 self.assertEqual(d1.keys() - set(d3.keys()), {'a', 'b'}) 127 self.assertEqual(d1.keys() - (0, 1), {'a', 'b'}) 128 129 self.assertFalse(d1.keys().isdisjoint(d1.keys())) 130 self.assertFalse(d1.keys().isdisjoint(d2.keys())) 131 self.assertFalse(d1.keys().isdisjoint(list(d2.keys()))) 132 self.assertFalse(d1.keys().isdisjoint(set(d2.keys()))) 133 self.assertTrue(d1.keys().isdisjoint({'x', 'y', 'z'})) 134 self.assertTrue(d1.keys().isdisjoint(['x', 'y', 'z'])) 135 self.assertTrue(d1.keys().isdisjoint(set(['x', 'y', 'z']))) 136 self.assertTrue(d1.keys().isdisjoint(set(['x', 'y']))) 137 self.assertTrue(d1.keys().isdisjoint(['x', 'y'])) 138 self.assertTrue(d1.keys().isdisjoint({})) 139 self.assertTrue(d1.keys().isdisjoint(d3.keys())) 140 141 de = {} 142 self.assertTrue(de.keys().isdisjoint(set())) 143 self.assertTrue(de.keys().isdisjoint([])) 144 self.assertTrue(de.keys().isdisjoint(de.keys())) 145 self.assertTrue(de.keys().isdisjoint([1])) 146 147 def test_items_set_operations(self): 148 d1 = {'a': 1, 'b': 2} 149 d2 = {'a': 2, 'b': 2} 150 d3 = {'d': 4, 'e': 5} 151 self.assertEqual( 152 d1.items() & d1.items(), {('a', 1), ('b', 2)}) 153 self.assertEqual(d1.items() & d2.items(), {('b', 2)}) 154 self.assertEqual(d1.items() & d3.items(), set()) 155 self.assertEqual(d1.items() & set(d1.items()), 156 {('a', 1), ('b', 2)}) 157 self.assertEqual(d1.items() & set(d2.items()), {('b', 2)}) 158 self.assertEqual(d1.items() & set(d3.items()), set()) 159 160 self.assertEqual(d1.items() | d1.items(), 161 {('a', 1), ('b', 2)}) 162 self.assertEqual(d1.items() | d2.items(), 163 {('a', 1), ('a', 2), ('b', 2)}) 164 self.assertEqual(d1.items() | d3.items(), 165 {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) 166 self.assertEqual(d1.items() | set(d1.items()), 167 {('a', 1), ('b', 2)}) 168 self.assertEqual(d1.items() | set(d2.items()), 169 {('a', 1), ('a', 2), ('b', 2)}) 170 self.assertEqual(d1.items() | set(d3.items()), 171 {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) 172 173 self.assertEqual(d1.items() ^ d1.items(), set()) 174 self.assertEqual(d1.items() ^ d2.items(), 175 {('a', 1), ('a', 2)}) 176 self.assertEqual(d1.items() ^ d3.items(), 177 {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) 178 179 self.assertEqual(d1.items() - d1.items(), set()) 180 self.assertEqual(d1.items() - d2.items(), {('a', 1)}) 181 self.assertEqual(d1.items() - d3.items(), {('a', 1), ('b', 2)}) 182 self.assertEqual(d1.items() - set(d1.items()), set()) 183 self.assertEqual(d1.items() - set(d2.items()), {('a', 1)}) 184 self.assertEqual(d1.items() - set(d3.items()), {('a', 1), ('b', 2)}) 185 186 self.assertFalse(d1.items().isdisjoint(d1.items())) 187 self.assertFalse(d1.items().isdisjoint(d2.items())) 188 self.assertFalse(d1.items().isdisjoint(list(d2.items()))) 189 self.assertFalse(d1.items().isdisjoint(set(d2.items()))) 190 self.assertTrue(d1.items().isdisjoint({'x', 'y', 'z'})) 191 self.assertTrue(d1.items().isdisjoint(['x', 'y', 'z'])) 192 self.assertTrue(d1.items().isdisjoint(set(['x', 'y', 'z']))) 193 self.assertTrue(d1.items().isdisjoint(set(['x', 'y']))) 194 self.assertTrue(d1.items().isdisjoint({})) 195 self.assertTrue(d1.items().isdisjoint(d3.items())) 196 197 de = {} 198 self.assertTrue(de.items().isdisjoint(set())) 199 self.assertTrue(de.items().isdisjoint([])) 200 self.assertTrue(de.items().isdisjoint(de.items())) 201 self.assertTrue(de.items().isdisjoint([1])) 202 203 def test_recursive_repr(self): 204 d = {} 205 d[42] = d.values() 206 r = repr(d) 207 # Cannot perform a stronger test, as the contents of the repr 208 # are implementation-dependent. All we can say is that we 209 # want a str result, not an exception of any sort. 210 self.assertIsInstance(r, str) 211 d[42] = d.items() 212 r = repr(d) 213 # Again. 214 self.assertIsInstance(r, str) 215 216 def test_deeply_nested_repr(self): 217 d = {} 218 for i in range(sys.getrecursionlimit() + 100): 219 d = {42: d.values()} 220 self.assertRaises(RecursionError, repr, d) 221 222 def test_copy(self): 223 d = {1: 10, "a": "ABC"} 224 self.assertRaises(TypeError, copy.copy, d.keys()) 225 self.assertRaises(TypeError, copy.copy, d.values()) 226 self.assertRaises(TypeError, copy.copy, d.items()) 227 228 def test_compare_error(self): 229 class Exc(Exception): 230 pass 231 232 class BadEq: 233 def __hash__(self): 234 return 7 235 def __eq__(self, other): 236 raise Exc 237 238 k1, k2 = BadEq(), BadEq() 239 v1, v2 = BadEq(), BadEq() 240 d = {k1: v1} 241 242 self.assertIn(k1, d) 243 self.assertIn(k1, d.keys()) 244 self.assertIn(v1, d.values()) 245 self.assertIn((k1, v1), d.items()) 246 247 self.assertRaises(Exc, d.__contains__, k2) 248 self.assertRaises(Exc, d.keys().__contains__, k2) 249 self.assertRaises(Exc, d.items().__contains__, (k2, v1)) 250 self.assertRaises(Exc, d.items().__contains__, (k1, v2)) 251 with self.assertRaises(Exc): 252 v2 in d.values() 253 254 def test_pickle(self): 255 d = {1: 10, "a": "ABC"} 256 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 257 self.assertRaises((TypeError, pickle.PicklingError), 258 pickle.dumps, d.keys(), proto) 259 self.assertRaises((TypeError, pickle.PicklingError), 260 pickle.dumps, d.values(), proto) 261 self.assertRaises((TypeError, pickle.PicklingError), 262 pickle.dumps, d.items(), proto) 263 264 def test_abc_registry(self): 265 d = dict(a=1) 266 267 self.assertIsInstance(d.keys(), collections.abc.KeysView) 268 self.assertIsInstance(d.keys(), collections.abc.MappingView) 269 self.assertIsInstance(d.keys(), collections.abc.Set) 270 self.assertIsInstance(d.keys(), collections.abc.Sized) 271 self.assertIsInstance(d.keys(), collections.abc.Iterable) 272 self.assertIsInstance(d.keys(), collections.abc.Container) 273 274 self.assertIsInstance(d.values(), collections.abc.ValuesView) 275 self.assertIsInstance(d.values(), collections.abc.MappingView) 276 self.assertIsInstance(d.values(), collections.abc.Sized) 277 278 self.assertIsInstance(d.items(), collections.abc.ItemsView) 279 self.assertIsInstance(d.items(), collections.abc.MappingView) 280 self.assertIsInstance(d.items(), collections.abc.Set) 281 self.assertIsInstance(d.items(), collections.abc.Sized) 282 self.assertIsInstance(d.items(), collections.abc.Iterable) 283 self.assertIsInstance(d.items(), collections.abc.Container) 284 285 286if __name__ == "__main__": 287 unittest.main() 288