1import collections
2import copy
3import pickle
4import unittest
5
6class DictSetTest(unittest.TestCase):
7
8    def test_constructors_not_callable(self):
9        kt = type({}.keys())
10        self.assertRaises(TypeError, kt, {})
11        self.assertRaises(TypeError, kt)
12        it = type({}.items())
13        self.assertRaises(TypeError, it, {})
14        self.assertRaises(TypeError, it)
15        vt = type({}.values())
16        self.assertRaises(TypeError, vt, {})
17        self.assertRaises(TypeError, vt)
18
19    def test_dict_keys(self):
20        d = {1: 10, "a": "ABC"}
21        keys = d.keys()
22        self.assertEqual(len(keys), 2)
23        self.assertEqual(set(keys), {1, "a"})
24        self.assertEqual(keys, {1, "a"})
25        self.assertNotEqual(keys, {1, "a", "b"})
26        self.assertNotEqual(keys, {1, "b"})
27        self.assertNotEqual(keys, {1})
28        self.assertNotEqual(keys, 42)
29        self.assertIn(1, keys)
30        self.assertIn("a", keys)
31        self.assertNotIn(10, keys)
32        self.assertNotIn("Z", keys)
33        self.assertEqual(d.keys(), d.keys())
34        e = {1: 11, "a": "def"}
35        self.assertEqual(d.keys(), e.keys())
36        del e["a"]
37        self.assertNotEqual(d.keys(), e.keys())
38
39    def test_dict_items(self):
40        d = {1: 10, "a": "ABC"}
41        items = d.items()
42        self.assertEqual(len(items), 2)
43        self.assertEqual(set(items), {(1, 10), ("a", "ABC")})
44        self.assertEqual(items, {(1, 10), ("a", "ABC")})
45        self.assertNotEqual(items, {(1, 10), ("a", "ABC"), "junk"})
46        self.assertNotEqual(items, {(1, 10), ("a", "def")})
47        self.assertNotEqual(items, {(1, 10)})
48        self.assertNotEqual(items, 42)
49        self.assertIn((1, 10), items)
50        self.assertIn(("a", "ABC"), items)
51        self.assertNotIn((1, 11), items)
52        self.assertNotIn(1, items)
53        self.assertNotIn((), items)
54        self.assertNotIn((1,), items)
55        self.assertNotIn((1, 2, 3), items)
56        self.assertEqual(d.items(), d.items())
57        e = d.copy()
58        self.assertEqual(d.items(), e.items())
59        e["a"] = "def"
60        self.assertNotEqual(d.items(), e.items())
61
62    def test_dict_mixed_keys_items(self):
63        d = {(1, 1): 11, (2, 2): 22}
64        e = {1: 1, 2: 2}
65        self.assertEqual(d.keys(), e.items())
66        self.assertNotEqual(d.items(), e.keys())
67
68    def test_dict_values(self):
69        d = {1: 10, "a": "ABC"}
70        values = d.values()
71        self.assertEqual(set(values), {10, "ABC"})
72        self.assertEqual(len(values), 2)
73
74    def test_dict_repr(self):
75        d = {1: 10, "a": "ABC"}
76        self.assertIsInstance(repr(d), str)
77        r = repr(d.items())
78        self.assertIsInstance(r, str)
79        self.assertTrue(r == "dict_items([('a', 'ABC'), (1, 10)])" or
80                        r == "dict_items([(1, 10), ('a', 'ABC')])")
81        r = repr(d.keys())
82        self.assertIsInstance(r, str)
83        self.assertTrue(r == "dict_keys(['a', 1])" or
84                        r == "dict_keys([1, 'a'])")
85        r = repr(d.values())
86        self.assertIsInstance(r, str)
87        self.assertTrue(r == "dict_values(['ABC', 10])" or
88                        r == "dict_values([10, 'ABC'])")
89
90    def test_keys_set_operations(self):
91        d1 = {'a': 1, 'b': 2}
92        d2 = {'b': 3, 'c': 2}
93        d3 = {'d': 4, 'e': 5}
94        self.assertEqual(d1.keys() & d1.keys(), {'a', 'b'})
95        self.assertEqual(d1.keys() & d2.keys(), {'b'})
96        self.assertEqual(d1.keys() & d3.keys(), set())
97        self.assertEqual(d1.keys() & set(d1.keys()), {'a', 'b'})
98        self.assertEqual(d1.keys() & set(d2.keys()), {'b'})
99        self.assertEqual(d1.keys() & set(d3.keys()), set())
100        self.assertEqual(d1.keys() & tuple(d1.keys()), {'a', 'b'})
101
102        self.assertEqual(d1.keys() | d1.keys(), {'a', 'b'})
103        self.assertEqual(d1.keys() | d2.keys(), {'a', 'b', 'c'})
104        self.assertEqual(d1.keys() | d3.keys(), {'a', 'b', 'd', 'e'})
105        self.assertEqual(d1.keys() | set(d1.keys()), {'a', 'b'})
106        self.assertEqual(d1.keys() | set(d2.keys()), {'a', 'b', 'c'})
107        self.assertEqual(d1.keys() | set(d3.keys()),
108                         {'a', 'b', 'd', 'e'})
109        self.assertEqual(d1.keys() | (1, 2), {'a', 'b', 1, 2})
110
111        self.assertEqual(d1.keys() ^ d1.keys(), set())
112        self.assertEqual(d1.keys() ^ d2.keys(), {'a', 'c'})
113        self.assertEqual(d1.keys() ^ d3.keys(), {'a', 'b', 'd', 'e'})
114        self.assertEqual(d1.keys() ^ set(d1.keys()), set())
115        self.assertEqual(d1.keys() ^ set(d2.keys()), {'a', 'c'})
116        self.assertEqual(d1.keys() ^ set(d3.keys()),
117                         {'a', 'b', 'd', 'e'})
118        self.assertEqual(d1.keys() ^ tuple(d2.keys()), {'a', 'c'})
119
120        self.assertEqual(d1.keys() - d1.keys(), set())
121        self.assertEqual(d1.keys() - d2.keys(), {'a'})
122        self.assertEqual(d1.keys() - d3.keys(), {'a', 'b'})
123        self.assertEqual(d1.keys() - set(d1.keys()), set())
124        self.assertEqual(d1.keys() - set(d2.keys()), {'a'})
125        self.assertEqual(d1.keys() - set(d3.keys()), {'a', 'b'})
126        self.assertEqual(d1.keys() - (0, 1), {'a', 'b'})
127
128        self.assertFalse(d1.keys().isdisjoint(d1.keys()))
129        self.assertFalse(d1.keys().isdisjoint(d2.keys()))
130        self.assertFalse(d1.keys().isdisjoint(list(d2.keys())))
131        self.assertFalse(d1.keys().isdisjoint(set(d2.keys())))
132        self.assertTrue(d1.keys().isdisjoint({'x', 'y', 'z'}))
133        self.assertTrue(d1.keys().isdisjoint(['x', 'y', 'z']))
134        self.assertTrue(d1.keys().isdisjoint(set(['x', 'y', 'z'])))
135        self.assertTrue(d1.keys().isdisjoint(set(['x', 'y'])))
136        self.assertTrue(d1.keys().isdisjoint(['x', 'y']))
137        self.assertTrue(d1.keys().isdisjoint({}))
138        self.assertTrue(d1.keys().isdisjoint(d3.keys()))
139
140        de = {}
141        self.assertTrue(de.keys().isdisjoint(set()))
142        self.assertTrue(de.keys().isdisjoint([]))
143        self.assertTrue(de.keys().isdisjoint(de.keys()))
144        self.assertTrue(de.keys().isdisjoint([1]))
145
146    def test_items_set_operations(self):
147        d1 = {'a': 1, 'b': 2}
148        d2 = {'a': 2, 'b': 2}
149        d3 = {'d': 4, 'e': 5}
150        self.assertEqual(
151            d1.items() & d1.items(), {('a', 1), ('b', 2)})
152        self.assertEqual(d1.items() & d2.items(), {('b', 2)})
153        self.assertEqual(d1.items() & d3.items(), set())
154        self.assertEqual(d1.items() & set(d1.items()),
155                         {('a', 1), ('b', 2)})
156        self.assertEqual(d1.items() & set(d2.items()), {('b', 2)})
157        self.assertEqual(d1.items() & set(d3.items()), set())
158
159        self.assertEqual(d1.items() | d1.items(),
160                         {('a', 1), ('b', 2)})
161        self.assertEqual(d1.items() | d2.items(),
162                         {('a', 1), ('a', 2), ('b', 2)})
163        self.assertEqual(d1.items() | d3.items(),
164                         {('a', 1), ('b', 2), ('d', 4), ('e', 5)})
165        self.assertEqual(d1.items() | set(d1.items()),
166                         {('a', 1), ('b', 2)})
167        self.assertEqual(d1.items() | set(d2.items()),
168                         {('a', 1), ('a', 2), ('b', 2)})
169        self.assertEqual(d1.items() | set(d3.items()),
170                         {('a', 1), ('b', 2), ('d', 4), ('e', 5)})
171
172        self.assertEqual(d1.items() ^ d1.items(), set())
173        self.assertEqual(d1.items() ^ d2.items(),
174                         {('a', 1), ('a', 2)})
175        self.assertEqual(d1.items() ^ d3.items(),
176                         {('a', 1), ('b', 2), ('d', 4), ('e', 5)})
177
178        self.assertEqual(d1.items() - d1.items(), set())
179        self.assertEqual(d1.items() - d2.items(), {('a', 1)})
180        self.assertEqual(d1.items() - d3.items(), {('a', 1), ('b', 2)})
181        self.assertEqual(d1.items() - set(d1.items()), set())
182        self.assertEqual(d1.items() - set(d2.items()), {('a', 1)})
183        self.assertEqual(d1.items() - set(d3.items()), {('a', 1), ('b', 2)})
184
185        self.assertFalse(d1.items().isdisjoint(d1.items()))
186        self.assertFalse(d1.items().isdisjoint(d2.items()))
187        self.assertFalse(d1.items().isdisjoint(list(d2.items())))
188        self.assertFalse(d1.items().isdisjoint(set(d2.items())))
189        self.assertTrue(d1.items().isdisjoint({'x', 'y', 'z'}))
190        self.assertTrue(d1.items().isdisjoint(['x', 'y', 'z']))
191        self.assertTrue(d1.items().isdisjoint(set(['x', 'y', 'z'])))
192        self.assertTrue(d1.items().isdisjoint(set(['x', 'y'])))
193        self.assertTrue(d1.items().isdisjoint({}))
194        self.assertTrue(d1.items().isdisjoint(d3.items()))
195
196        de = {}
197        self.assertTrue(de.items().isdisjoint(set()))
198        self.assertTrue(de.items().isdisjoint([]))
199        self.assertTrue(de.items().isdisjoint(de.items()))
200        self.assertTrue(de.items().isdisjoint([1]))
201
202    def test_recursive_repr(self):
203        d = {}
204        d[42] = d.values()
205        self.assertRaises(RecursionError, repr, d)
206
207    def test_copy(self):
208        d = {1: 10, "a": "ABC"}
209        self.assertRaises(TypeError, copy.copy, d.keys())
210        self.assertRaises(TypeError, copy.copy, d.values())
211        self.assertRaises(TypeError, copy.copy, d.items())
212
213    def test_compare_error(self):
214        class Exc(Exception):
215            pass
216
217        class BadEq:
218            def __hash__(self):
219                return 7
220            def __eq__(self, other):
221                raise Exc
222
223        k1, k2 = BadEq(), BadEq()
224        v1, v2 = BadEq(), BadEq()
225        d = {k1: v1}
226
227        self.assertIn(k1, d)
228        self.assertIn(k1, d.keys())
229        self.assertIn(v1, d.values())
230        self.assertIn((k1, v1), d.items())
231
232        self.assertRaises(Exc, d.__contains__, k2)
233        self.assertRaises(Exc, d.keys().__contains__, k2)
234        self.assertRaises(Exc, d.items().__contains__, (k2, v1))
235        self.assertRaises(Exc, d.items().__contains__, (k1, v2))
236        with self.assertRaises(Exc):
237            v2 in d.values()
238
239    def test_pickle(self):
240        d = {1: 10, "a": "ABC"}
241        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
242            self.assertRaises((TypeError, pickle.PicklingError),
243                pickle.dumps, d.keys(), proto)
244            self.assertRaises((TypeError, pickle.PicklingError),
245                pickle.dumps, d.values(), proto)
246            self.assertRaises((TypeError, pickle.PicklingError),
247                pickle.dumps, d.items(), proto)
248
249    def test_abc_registry(self):
250        d = dict(a=1)
251
252        self.assertIsInstance(d.keys(), collections.KeysView)
253        self.assertIsInstance(d.keys(), collections.MappingView)
254        self.assertIsInstance(d.keys(), collections.Set)
255        self.assertIsInstance(d.keys(), collections.Sized)
256        self.assertIsInstance(d.keys(), collections.Iterable)
257        self.assertIsInstance(d.keys(), collections.Container)
258
259        self.assertIsInstance(d.values(), collections.ValuesView)
260        self.assertIsInstance(d.values(), collections.MappingView)
261        self.assertIsInstance(d.values(), collections.Sized)
262
263        self.assertIsInstance(d.items(), collections.ItemsView)
264        self.assertIsInstance(d.items(), collections.MappingView)
265        self.assertIsInstance(d.items(), collections.Set)
266        self.assertIsInstance(d.items(), collections.Sized)
267        self.assertIsInstance(d.items(), collections.Iterable)
268        self.assertIsInstance(d.items(), collections.Container)
269
270
271if __name__ == "__main__":
272    unittest.main()
273