blob: 4d54576d15b6730d77dc9a1b9f53e97fd47f7f4d [file] [log] [blame]
Georg Brandl9dba5d92008-05-18 16:27:29 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Georg Brandl9dba5d92008-05-18 16:27:29 +00003from weakref import proxy, ref, WeakSet
4import operator
5import copy
6import string
7import os
8from random import randrange, shuffle
9import sys
10import warnings
11import collections
12from collections import UserString as ustr
13
14
15class Foo:
16 pass
17
18
19class TestWeakSet(unittest.TestCase):
20
21 def setUp(self):
22 # need to keep references to them
23 self.items = [ustr(c) for c in ('a', 'b', 'c')]
24 self.items2 = [ustr(c) for c in ('x', 'y', 'z')]
25 self.letters = [ustr(c) for c in string.ascii_letters]
26 self.s = WeakSet(self.items)
27 self.d = dict.fromkeys(self.items)
28 self.obj = ustr('F')
29 self.fs = WeakSet([self.obj])
30
31 def test_methods(self):
32 weaksetmethods = dir(WeakSet)
33 for method in dir(set):
Georg Brandl02c0bbb2008-05-18 21:04:46 +000034 if method == 'test_c_api' or method.startswith('_'):
Georg Brandl9dba5d92008-05-18 16:27:29 +000035 continue
Georg Brandl19219702008-05-18 17:10:40 +000036 self.assert_(method in weaksetmethods,
37 "WeakSet missing method " + method)
Georg Brandl9dba5d92008-05-18 16:27:29 +000038
39 def test_new_or_init(self):
40 self.assertRaises(TypeError, WeakSet, [], 2)
41
42 def test_len(self):
43 self.assertEqual(len(self.s), len(self.d))
44 self.assertEqual(len(self.fs), 1)
45 del self.obj
46 self.assertEqual(len(self.fs), 0)
47
48 def test_contains(self):
49 for c in self.letters:
50 self.assertEqual(c in self.s, c in self.d)
51 self.assertRaises(TypeError, self.s.__contains__, [[]])
52 self.assert_(self.obj in self.fs)
53 del self.obj
54 self.assert_(ustr('F') not in self.fs)
55
56 def test_union(self):
57 u = self.s.union(self.items2)
58 for c in self.letters:
59 self.assertEqual(c in u, c in self.d or c in self.items2)
60 self.assertEqual(self.s, WeakSet(self.items))
61 self.assertEqual(type(u), WeakSet)
62 self.assertRaises(TypeError, self.s.union, [[]])
63 for C in set, frozenset, dict.fromkeys, list, tuple:
64 x = WeakSet(self.items + self.items2)
65 c = C(self.items2)
66 self.assertEqual(self.s.union(c), x)
67
68 def test_or(self):
69 i = self.s.union(self.items2)
70 self.assertEqual(self.s | set(self.items2), i)
71 self.assertEqual(self.s | frozenset(self.items2), i)
72
73 def test_intersection(self):
74 i = self.s.intersection(self.items2)
75 for c in self.letters:
76 self.assertEqual(c in i, c in self.d and c in self.items2)
77 self.assertEqual(self.s, WeakSet(self.items))
78 self.assertEqual(type(i), WeakSet)
79 for C in set, frozenset, dict.fromkeys, list, tuple:
80 x = WeakSet([])
81 self.assertEqual(self.s.intersection(C(self.items2)), x)
82
83 def test_isdisjoint(self):
84 self.assert_(self.s.isdisjoint(WeakSet(self.items2)))
85 self.assert_(not self.s.isdisjoint(WeakSet(self.letters)))
86
87 def test_and(self):
88 i = self.s.intersection(self.items2)
89 self.assertEqual(self.s & set(self.items2), i)
90 self.assertEqual(self.s & frozenset(self.items2), i)
91
92 def test_difference(self):
93 i = self.s.difference(self.items2)
94 for c in self.letters:
95 self.assertEqual(c in i, c in self.d and c not in self.items2)
96 self.assertEqual(self.s, WeakSet(self.items))
97 self.assertEqual(type(i), WeakSet)
98 self.assertRaises(TypeError, self.s.difference, [[]])
99
100 def test_sub(self):
101 i = self.s.difference(self.items2)
102 self.assertEqual(self.s - set(self.items2), i)
103 self.assertEqual(self.s - frozenset(self.items2), i)
104
105 def test_symmetric_difference(self):
106 i = self.s.symmetric_difference(self.items2)
107 for c in self.letters:
108 self.assertEqual(c in i, (c in self.d) ^ (c in self.items2))
109 self.assertEqual(self.s, WeakSet(self.items))
110 self.assertEqual(type(i), WeakSet)
111 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
112
113 def test_xor(self):
114 i = self.s.symmetric_difference(self.items2)
115 self.assertEqual(self.s ^ set(self.items2), i)
116 self.assertEqual(self.s ^ frozenset(self.items2), i)
117
118 def test_sub_and_super(self):
119 pl, ql, rl = map(lambda s: [ustr(c) for c in s], ['ab', 'abcde', 'def'])
120 p, q, r = map(WeakSet, (pl, ql, rl))
121 self.assert_(p < q)
122 self.assert_(p <= q)
123 self.assert_(q <= q)
124 self.assert_(q > p)
125 self.assert_(q >= p)
126 self.failIf(q < r)
127 self.failIf(q <= r)
128 self.failIf(q > r)
129 self.failIf(q >= r)
130 self.assert_(set('a').issubset('abc'))
131 self.assert_(set('abc').issuperset('a'))
132 self.failIf(set('a').issubset('cbs'))
133 self.failIf(set('cbs').issuperset('a'))
134
135 def test_gc(self):
136 # Create a nest of cycles to exercise overall ref count check
Robert Schuppenies4ad1d6f2009-05-17 17:32:20 +0000137 s = WeakSet(Foo() for i in range(1000))
Georg Brandl9dba5d92008-05-18 16:27:29 +0000138 for elem in s:
139 elem.cycle = s
140 elem.sub = elem
Robert Schuppenies4ad1d6f2009-05-17 17:32:20 +0000141 elem.set = WeakSet([elem])
Georg Brandl9dba5d92008-05-18 16:27:29 +0000142
143 def test_subclass_with_custom_hash(self):
144 # Bug #1257731
145 class H(WeakSet):
146 def __hash__(self):
147 return int(id(self) & 0x7fffffff)
148 s=H()
149 f=set()
150 f.add(s)
151 self.assert_(s in f)
152 f.remove(s)
153 f.add(s)
154 f.discard(s)
155
156 def test_init(self):
157 s = WeakSet()
158 s.__init__(self.items)
159 self.assertEqual(s, self.s)
160 s.__init__(self.items2)
161 self.assertEqual(s, WeakSet(self.items2))
162 self.assertRaises(TypeError, s.__init__, s, 2);
163 self.assertRaises(TypeError, s.__init__, 1);
164
165 def test_constructor_identity(self):
166 s = WeakSet(self.items)
167 t = WeakSet(s)
168 self.assertNotEqual(id(s), id(t))
169
Georg Brandl9dba5d92008-05-18 16:27:29 +0000170 def test_hash(self):
171 self.assertRaises(TypeError, hash, self.s)
172
173 def test_clear(self):
174 self.s.clear()
Robert Schuppenies4ad1d6f2009-05-17 17:32:20 +0000175 self.assertEqual(self.s, WeakSet([]))
Georg Brandl9dba5d92008-05-18 16:27:29 +0000176 self.assertEqual(len(self.s), 0)
177
178 def test_copy(self):
179 dup = self.s.copy()
180 self.assertEqual(self.s, dup)
181 self.assertNotEqual(id(self.s), id(dup))
182
183 def test_add(self):
184 x = ustr('Q')
185 self.s.add(x)
186 self.assert_(x in self.s)
187 dup = self.s.copy()
188 self.s.add(x)
189 self.assertEqual(self.s, dup)
190 self.assertRaises(TypeError, self.s.add, [])
191 self.fs.add(Foo())
192 self.assert_(len(self.fs) == 1)
193 self.fs.add(self.obj)
194 self.assert_(len(self.fs) == 1)
195
196 def test_remove(self):
197 x = ustr('a')
198 self.s.remove(x)
199 self.assert_(x not in self.s)
200 self.assertRaises(KeyError, self.s.remove, x)
201 self.assertRaises(TypeError, self.s.remove, [])
202
203 def test_discard(self):
204 a, q = ustr('a'), ustr('Q')
205 self.s.discard(a)
206 self.assert_(a not in self.s)
207 self.s.discard(q)
208 self.assertRaises(TypeError, self.s.discard, [])
209
210 def test_pop(self):
211 for i in range(len(self.s)):
212 elem = self.s.pop()
213 self.assert_(elem not in self.s)
214 self.assertRaises(KeyError, self.s.pop)
215
216 def test_update(self):
217 retval = self.s.update(self.items2)
218 self.assertEqual(retval, None)
219 for c in (self.items + self.items2):
220 self.assert_(c in self.s)
221 self.assertRaises(TypeError, self.s.update, [[]])
222
223 def test_update_set(self):
224 self.s.update(set(self.items2))
225 for c in (self.items + self.items2):
226 self.assert_(c in self.s)
227
228 def test_ior(self):
229 self.s |= set(self.items2)
230 for c in (self.items + self.items2):
231 self.assert_(c in self.s)
232
233 def test_intersection_update(self):
234 retval = self.s.intersection_update(self.items2)
235 self.assertEqual(retval, None)
236 for c in (self.items + self.items2):
237 if c in self.items2 and c in self.items:
238 self.assert_(c in self.s)
239 else:
240 self.assert_(c not in self.s)
241 self.assertRaises(TypeError, self.s.intersection_update, [[]])
242
243 def test_iand(self):
244 self.s &= set(self.items2)
245 for c in (self.items + self.items2):
246 if c in self.items2 and c in self.items:
247 self.assert_(c in self.s)
248 else:
249 self.assert_(c not in self.s)
250
251 def test_difference_update(self):
252 retval = self.s.difference_update(self.items2)
253 self.assertEqual(retval, None)
254 for c in (self.items + self.items2):
255 if c in self.items and c not in self.items2:
256 self.assert_(c in self.s)
257 else:
258 self.assert_(c not in self.s)
259 self.assertRaises(TypeError, self.s.difference_update, [[]])
260 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
261
262 def test_isub(self):
263 self.s -= set(self.items2)
264 for c in (self.items + self.items2):
265 if c in self.items and c not in self.items2:
266 self.assert_(c in self.s)
267 else:
268 self.assert_(c not in self.s)
269
270 def test_symmetric_difference_update(self):
271 retval = self.s.symmetric_difference_update(self.items2)
272 self.assertEqual(retval, None)
273 for c in (self.items + self.items2):
274 if (c in self.items) ^ (c in self.items2):
275 self.assert_(c in self.s)
276 else:
277 self.assert_(c not in self.s)
278 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
279
280 def test_ixor(self):
281 self.s ^= set(self.items2)
282 for c in (self.items + self.items2):
283 if (c in self.items) ^ (c in self.items2):
284 self.assert_(c in self.s)
285 else:
286 self.assert_(c not in self.s)
287
288 def test_inplace_on_self(self):
289 t = self.s.copy()
290 t |= t
291 self.assertEqual(t, self.s)
292 t &= t
293 self.assertEqual(t, self.s)
294 t -= t
295 self.assertEqual(t, WeakSet())
296 t = self.s.copy()
297 t ^= t
298 self.assertEqual(t, WeakSet())
299
Robert Schuppenies4ad1d6f2009-05-17 17:32:20 +0000300 def test_eq(self):
301 # issue 5964
302 self.assertTrue(self.s == self.s)
303 self.assertTrue(self.s == WeakSet(self.items))
304 self.assertFalse(self.s == set(self.items))
305 self.assertFalse(self.s == list(self.items))
306 self.assertFalse(self.s == tuple(self.items))
307 self.assertFalse(self.s == WeakSet([Foo]))
308 self.assertFalse(self.s == 1)
309
Georg Brandl9dba5d92008-05-18 16:27:29 +0000310
311def test_main(verbose=None):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000312 support.run_unittest(TestWeakSet)
Georg Brandl9dba5d92008-05-18 16:27:29 +0000313
314if __name__ == "__main__":
315 test_main(verbose=True)