blob: 86a563686713486c0bbae21a502f1cb6f4beab6f [file] [log] [blame]
Raymond Hettingera690a992003-11-16 16:17:49 +00001import unittest
2from test import test_support
Raymond Hettinger691d8052004-05-30 07:26:47 +00003from weakref import proxy
Raymond Hettingera690a992003-11-16 16:17:49 +00004import operator
5import copy
6import pickle
Raymond Hettingereae05de2004-07-09 04:51:24 +00007import os
Raymond Hettinger82cb9a22005-07-05 05:34:43 +00008from random import randrange, shuffle
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00009import sys
Raymond Hettingera690a992003-11-16 16:17:49 +000010
11class PassThru(Exception):
12 pass
13
14def check_pass_thru():
15 raise PassThru
16 yield 1
17
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000018class BadCmp:
19 def __hash__(self):
20 return 1
Guido van Rossum47b9ff62006-08-24 00:41:19 +000021 def __eq__(self, other):
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000022 raise RuntimeError
23
Thomas Wouters902d6eb2007-01-09 23:18:33 +000024class ReprWrapper:
25 'Used to test self-referential repr() calls'
26 def __repr__(self):
27 return repr(self.value)
28
Thomas Wouterscf297e42007-02-23 15:07:44 +000029class HashCountingInt(int):
30 'int-like object that counts the number of times __hash__ is called'
31 def __init__(self, *args):
32 self.hash_count = 0
33 def __hash__(self):
34 self.hash_count += 1
35 return int.__hash__(self)
36
Raymond Hettingera690a992003-11-16 16:17:49 +000037class TestJointOps(unittest.TestCase):
38 # Tests common to both set and frozenset
39
40 def setUp(self):
41 self.word = word = 'simsalabim'
42 self.otherword = 'madagascar'
43 self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
44 self.s = self.thetype(word)
45 self.d = dict.fromkeys(word)
46
Raymond Hettinger6429a472004-09-28 01:51:35 +000047 def test_new_or_init(self):
48 self.assertRaises(TypeError, self.thetype, [], 2)
49
Raymond Hettingera690a992003-11-16 16:17:49 +000050 def test_uniquification(self):
Raymond Hettinger64958a12003-12-17 20:43:33 +000051 actual = sorted(self.s)
52 expected = sorted(self.d)
Raymond Hettingera690a992003-11-16 16:17:49 +000053 self.assertEqual(actual, expected)
54 self.assertRaises(PassThru, self.thetype, check_pass_thru())
55 self.assertRaises(TypeError, self.thetype, [[]])
56
57 def test_len(self):
58 self.assertEqual(len(self.s), len(self.d))
59
60 def test_contains(self):
61 for c in self.letters:
62 self.assertEqual(c in self.s, c in self.d)
63 self.assertRaises(TypeError, self.s.__contains__, [[]])
Raymond Hettinger19c2d772003-11-21 18:36:54 +000064 s = self.thetype([frozenset(self.letters)])
65 self.assert_(self.thetype(self.letters) in s)
Raymond Hettingera690a992003-11-16 16:17:49 +000066
Raymond Hettingera690a992003-11-16 16:17:49 +000067 def test_union(self):
68 u = self.s.union(self.otherword)
69 for c in self.letters:
70 self.assertEqual(c in u, c in self.d or c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000071 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000072 self.assertEqual(type(u), self.thetype)
73 self.assertRaises(PassThru, self.s.union, check_pass_thru())
74 self.assertRaises(TypeError, self.s.union, [[]])
Guido van Rossum75a902d2007-10-19 22:06:24 +000075 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000076 self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
77 self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
78 self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
79 self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +000080
81 def test_or(self):
82 i = self.s.union(self.otherword)
83 self.assertEqual(self.s | set(self.otherword), i)
84 self.assertEqual(self.s | frozenset(self.otherword), i)
85 try:
86 self.s | self.otherword
87 except TypeError:
88 pass
89 else:
90 self.fail("s|t did not screen-out general iterables")
91
92 def test_intersection(self):
93 i = self.s.intersection(self.otherword)
94 for c in self.letters:
95 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000096 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000097 self.assertEqual(type(i), self.thetype)
98 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Guido van Rossum75a902d2007-10-19 22:06:24 +000099 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000100 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
101 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
102 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
103 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Raymond Hettingera690a992003-11-16 16:17:49 +0000104
105 def test_and(self):
106 i = self.s.intersection(self.otherword)
107 self.assertEqual(self.s & set(self.otherword), i)
108 self.assertEqual(self.s & frozenset(self.otherword), i)
109 try:
110 self.s & self.otherword
111 except TypeError:
112 pass
113 else:
114 self.fail("s&t did not screen-out general iterables")
115
116 def test_difference(self):
117 i = self.s.difference(self.otherword)
118 for c in self.letters:
119 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000120 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000121 self.assertEqual(type(i), self.thetype)
122 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
123 self.assertRaises(TypeError, self.s.difference, [[]])
Guido van Rossum75a902d2007-10-19 22:06:24 +0000124 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000125 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
126 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
127 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
128 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000129
130 def test_sub(self):
131 i = self.s.difference(self.otherword)
132 self.assertEqual(self.s - set(self.otherword), i)
133 self.assertEqual(self.s - frozenset(self.otherword), i)
134 try:
135 self.s - self.otherword
136 except TypeError:
137 pass
138 else:
139 self.fail("s-t did not screen-out general iterables")
140
141 def test_symmetric_difference(self):
142 i = self.s.symmetric_difference(self.otherword)
143 for c in self.letters:
144 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000145 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000146 self.assertEqual(type(i), self.thetype)
147 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
148 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Guido van Rossum75a902d2007-10-19 22:06:24 +0000149 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000150 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
151 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
152 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
153 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000154
155 def test_xor(self):
156 i = self.s.symmetric_difference(self.otherword)
157 self.assertEqual(self.s ^ set(self.otherword), i)
158 self.assertEqual(self.s ^ frozenset(self.otherword), i)
159 try:
160 self.s ^ self.otherword
161 except TypeError:
162 pass
163 else:
164 self.fail("s^t did not screen-out general iterables")
165
166 def test_equality(self):
167 self.assertEqual(self.s, set(self.word))
168 self.assertEqual(self.s, frozenset(self.word))
169 self.assertEqual(self.s == self.word, False)
170 self.assertNotEqual(self.s, set(self.otherword))
171 self.assertNotEqual(self.s, frozenset(self.otherword))
172 self.assertEqual(self.s != self.word, True)
173
174 def test_setOfFrozensets(self):
175 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
176 s = self.thetype(t)
177 self.assertEqual(len(s), 3)
178
179 def test_compare(self):
180 self.assertRaises(TypeError, self.s.__cmp__, self.s)
181
182 def test_sub_and_super(self):
183 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
184 self.assert_(p < q)
185 self.assert_(p <= q)
186 self.assert_(q <= q)
187 self.assert_(q > p)
188 self.assert_(q >= p)
189 self.failIf(q < r)
190 self.failIf(q <= r)
191 self.failIf(q > r)
192 self.failIf(q >= r)
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000193 self.assert_(set('a').issubset('abc'))
194 self.assert_(set('abc').issuperset('a'))
195 self.failIf(set('a').issubset('cbs'))
196 self.failIf(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000197
198 def test_pickling(self):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000199 for i in (0, 1, 2):
200 p = pickle.dumps(self.s, i)
201 dup = pickle.loads(p)
202 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
203 if type(self.s) not in (set, frozenset):
204 self.s.x = 10
205 p = pickle.dumps(self.s)
206 dup = pickle.loads(p)
207 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000208
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000209 def test_deepcopy(self):
210 class Tracer:
211 def __init__(self, value):
212 self.value = value
213 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000214 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000215 def __deepcopy__(self, memo=None):
216 return Tracer(self.value + 1)
217 t = Tracer(10)
218 s = self.thetype([t])
219 dup = copy.deepcopy(s)
220 self.assertNotEqual(id(s), id(dup))
221 for elem in dup:
222 newt = elem
223 self.assertNotEqual(id(t), id(newt))
224 self.assertEqual(t.value + 1, newt.value)
225
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000226 def test_gc(self):
227 # Create a nest of cycles to exercise overall ref count check
228 class A:
229 pass
Guido van Rossum805365e2007-05-07 22:24:25 +0000230 s = set(A() for i in range(1000))
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000231 for elem in s:
232 elem.cycle = s
233 elem.sub = elem
234 elem.set = set([elem])
235
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000236 def test_subclass_with_custom_hash(self):
237 # Bug #1257731
238 class H(self.thetype):
239 def __hash__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000240 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000241 s=H()
242 f=set()
243 f.add(s)
244 self.assert_(s in f)
245 f.remove(s)
246 f.add(s)
247 f.discard(s)
248
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000249 def test_badcmp(self):
250 s = self.thetype([BadCmp()])
251 # Detect comparison errors during insertion and lookup
252 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
253 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
254 # Detect errors during mutating operations
255 if hasattr(s, 'add'):
256 self.assertRaises(RuntimeError, s.add, BadCmp())
257 self.assertRaises(RuntimeError, s.discard, BadCmp())
258 self.assertRaises(RuntimeError, s.remove, BadCmp())
259
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000260 def test_cyclical_repr(self):
261 w = ReprWrapper()
262 s = self.thetype([w])
263 w.value = s
264 if self.thetype == set:
265 self.assertEqual(repr(s), '{set(...)}')
266 else:
267 name = repr(s).partition('(')[0] # strip class name
Guido van Rossumbdba5cf2007-08-07 22:44:20 +0000268 self.assertEqual(repr(s), '%s({%s(...)})' % (name, name))
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000269
270 def test_cyclical_print(self):
271 w = ReprWrapper()
272 s = self.thetype([w])
273 w.value = s
274 try:
Guido van Rossum292aa0d2007-05-24 18:00:35 +0000275 fo = open(test_support.TESTFN, "w")
Guido van Rossumd8c19672007-02-09 21:54:58 +0000276 fo.write(str(s))
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000277 fo.close()
Guido van Rossum292aa0d2007-05-24 18:00:35 +0000278 fo = open(test_support.TESTFN, "r")
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000279 self.assertEqual(fo.read(), repr(s))
280 finally:
281 fo.close()
282 os.remove(test_support.TESTFN)
283
Thomas Wouterscf297e42007-02-23 15:07:44 +0000284 def test_do_not_rehash_dict_keys(self):
285 n = 10
Guido van Rossum805365e2007-05-07 22:24:25 +0000286 d = dict.fromkeys(map(HashCountingInt, range(n)))
Thomas Wouterscf297e42007-02-23 15:07:44 +0000287 self.assertEqual(sum(elem.hash_count for elem in d), n)
288 s = self.thetype(d)
289 self.assertEqual(sum(elem.hash_count for elem in d), n)
290 s.difference(d)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000291 self.assertEqual(sum(elem.hash_count for elem in d), n)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000292 if hasattr(s, 'symmetric_difference_update'):
293 s.symmetric_difference_update(d)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000294 self.assertEqual(sum(elem.hash_count for elem in d), n)
295 d2 = dict.fromkeys(set(d))
296 self.assertEqual(sum(elem.hash_count for elem in d), n)
297 d3 = dict.fromkeys(frozenset(d))
298 self.assertEqual(sum(elem.hash_count for elem in d), n)
299 d3 = dict.fromkeys(frozenset(d), 123)
300 self.assertEqual(sum(elem.hash_count for elem in d), n)
301 self.assertEqual(d3, dict.fromkeys(d, 123))
Thomas Wouterscf297e42007-02-23 15:07:44 +0000302
Raymond Hettingera690a992003-11-16 16:17:49 +0000303class TestSet(TestJointOps):
304 thetype = set
305
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000306 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000307 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000308 s.__init__(self.word)
309 self.assertEqual(s, set(self.word))
310 s.__init__(self.otherword)
311 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000312 self.assertRaises(TypeError, s.__init__, s, 2);
313 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000314
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000315 def test_constructor_identity(self):
316 s = self.thetype(range(3))
317 t = self.thetype(s)
318 self.assertNotEqual(id(s), id(t))
319
Guido van Rossum86e58e22006-08-28 15:27:34 +0000320 def test_set_literal(self):
321 s = set([1,2,3])
322 t = {1,2,3}
323 self.assertEqual(s, t)
324
Raymond Hettingera690a992003-11-16 16:17:49 +0000325 def test_hash(self):
326 self.assertRaises(TypeError, hash, self.s)
327
328 def test_clear(self):
329 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000330 self.assertEqual(self.s, set())
331 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000332
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000333 def test_copy(self):
334 dup = self.s.copy()
335 self.assertEqual(self.s, dup)
336 self.assertNotEqual(id(self.s), id(dup))
337
Raymond Hettingera690a992003-11-16 16:17:49 +0000338 def test_add(self):
339 self.s.add('Q')
340 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000341 dup = self.s.copy()
342 self.s.add('Q')
343 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000344 self.assertRaises(TypeError, self.s.add, [])
345
346 def test_remove(self):
347 self.s.remove('a')
348 self.assert_('a' not in self.s)
349 self.assertRaises(KeyError, self.s.remove, 'Q')
350 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000351 s = self.thetype([frozenset(self.word)])
352 self.assert_(self.thetype(self.word) in s)
353 s.remove(self.thetype(self.word))
354 self.assert_(self.thetype(self.word) not in s)
355 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000356
Thomas Wouters89f507f2006-12-13 04:49:30 +0000357 def test_remove_keyerror_unpacking(self):
358 # bug: www.python.org/sf/1576657
359 for v1 in ['Q', (1,)]:
360 try:
361 self.s.remove(v1)
Guido van Rossumb940e112007-01-10 16:19:56 +0000362 except KeyError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000363 v2 = e.args[0]
364 self.assertEqual(v1, v2)
365 else:
366 self.fail()
367
Raymond Hettingera690a992003-11-16 16:17:49 +0000368 def test_discard(self):
369 self.s.discard('a')
370 self.assert_('a' not in self.s)
371 self.s.discard('Q')
372 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000373 s = self.thetype([frozenset(self.word)])
374 self.assert_(self.thetype(self.word) in s)
375 s.discard(self.thetype(self.word))
376 self.assert_(self.thetype(self.word) not in s)
377 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000378
379 def test_pop(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000380 for i in range(len(self.s)):
Raymond Hettingera690a992003-11-16 16:17:49 +0000381 elem = self.s.pop()
382 self.assert_(elem not in self.s)
383 self.assertRaises(KeyError, self.s.pop)
384
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000385 def test_update(self):
386 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000387 self.assertEqual(retval, None)
388 for c in (self.word + self.otherword):
389 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000390 self.assertRaises(PassThru, self.s.update, check_pass_thru())
391 self.assertRaises(TypeError, self.s.update, [[]])
392 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000393 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000394 s = self.thetype('abcba')
395 self.assertEqual(s.update(C(p)), None)
396 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000397
398 def test_ior(self):
399 self.s |= set(self.otherword)
400 for c in (self.word + self.otherword):
401 self.assert_(c in self.s)
402
403 def test_intersection_update(self):
404 retval = self.s.intersection_update(self.otherword)
405 self.assertEqual(retval, None)
406 for c in (self.word + self.otherword):
407 if c in self.otherword and c in self.word:
408 self.assert_(c in self.s)
409 else:
410 self.assert_(c not in self.s)
411 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
412 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000413 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000414 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000415 s = self.thetype('abcba')
416 self.assertEqual(s.intersection_update(C(p)), None)
417 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000418
419 def test_iand(self):
420 self.s &= set(self.otherword)
421 for c in (self.word + self.otherword):
422 if c in self.otherword and c in self.word:
423 self.assert_(c in self.s)
424 else:
425 self.assert_(c not in self.s)
426
427 def test_difference_update(self):
428 retval = self.s.difference_update(self.otherword)
429 self.assertEqual(retval, None)
430 for c in (self.word + self.otherword):
431 if c in self.word and c not in self.otherword:
432 self.assert_(c in self.s)
433 else:
434 self.assert_(c not in self.s)
435 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
436 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000437 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
438 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000439 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000440 s = self.thetype('abcba')
441 self.assertEqual(s.difference_update(C(p)), None)
442 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000443
444 def test_isub(self):
445 self.s -= set(self.otherword)
446 for c in (self.word + self.otherword):
447 if c in self.word and c not in self.otherword:
448 self.assert_(c in self.s)
449 else:
450 self.assert_(c not in self.s)
451
452 def test_symmetric_difference_update(self):
453 retval = self.s.symmetric_difference_update(self.otherword)
454 self.assertEqual(retval, None)
455 for c in (self.word + self.otherword):
456 if (c in self.word) ^ (c in self.otherword):
457 self.assert_(c in self.s)
458 else:
459 self.assert_(c not in self.s)
460 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
461 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000462 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000463 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000464 s = self.thetype('abcba')
465 self.assertEqual(s.symmetric_difference_update(C(p)), None)
466 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000467
468 def test_ixor(self):
469 self.s ^= set(self.otherword)
470 for c in (self.word + self.otherword):
471 if (c in self.word) ^ (c in self.otherword):
472 self.assert_(c in self.s)
473 else:
474 self.assert_(c not in self.s)
475
Raymond Hettingerc991db22005-08-11 07:58:45 +0000476 def test_inplace_on_self(self):
477 t = self.s.copy()
478 t |= t
479 self.assertEqual(t, self.s)
480 t &= t
481 self.assertEqual(t, self.s)
482 t -= t
483 self.assertEqual(t, self.thetype())
484 t = self.s.copy()
485 t ^= t
486 self.assertEqual(t, self.thetype())
487
Raymond Hettinger691d8052004-05-30 07:26:47 +0000488 def test_weakref(self):
489 s = self.thetype('gallahad')
490 p = proxy(s)
491 self.assertEqual(str(p), str(s))
492 s = None
493 self.assertRaises(ReferenceError, str, p)
494
Guido van Rossum10ab4ae2007-08-23 23:57:24 +0000495 def test_rich_compare(self):
496 class TestRichSetCompare:
497 def __gt__(self, some_set):
498 self.gt_called = True
499 return False
500 def __lt__(self, some_set):
501 self.lt_called = True
502 return False
503 def __ge__(self, some_set):
504 self.ge_called = True
505 return False
506 def __le__(self, some_set):
507 self.le_called = True
508 return False
509
510 # This first tries the bulitin rich set comparison, which doesn't know
511 # how to handle the custom object. Upon returning NotImplemented, the
512 # corresponding comparison on the right object is invoked.
513 myset = {1, 2, 3}
514
515 myobj = TestRichSetCompare()
516 myset < myobj
517 self.assert_(myobj.gt_called)
518
519 myobj = TestRichSetCompare()
520 myset > myobj
521 self.assert_(myobj.lt_called)
522
523 myobj = TestRichSetCompare()
524 myset <= myobj
525 self.assert_(myobj.ge_called)
526
527 myobj = TestRichSetCompare()
528 myset >= myobj
529 self.assert_(myobj.le_called)
530
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000531 # C API test only available in a debug build
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000532 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000533 def test_c_api(self):
534 self.assertEqual(set('abc').test_c_api(), True)
535
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000536class SetSubclass(set):
537 pass
538
539class TestSetSubclass(TestSet):
540 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000541
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000542class SetSubclassWithKeywordArgs(set):
543 def __init__(self, iterable=[], newarg=None):
544 set.__init__(self, iterable)
545
546class TestSetSubclassWithKeywordArgs(TestSet):
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000547
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000548 def test_keywords_in_subclass(self):
549 'SF bug #1486663 -- this used to erroneously raise a TypeError'
550 SetSubclassWithKeywordArgs(newarg=1)
551
Raymond Hettingera690a992003-11-16 16:17:49 +0000552class TestFrozenSet(TestJointOps):
553 thetype = frozenset
554
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000555 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000556 s = self.thetype(self.word)
557 s.__init__(self.otherword)
558 self.assertEqual(s, set(self.word))
559
Raymond Hettingerd7946662005-08-01 21:39:29 +0000560 def test_singleton_empty_frozenset(self):
561 f = frozenset()
562 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
563 frozenset(), frozenset([]), frozenset(()), frozenset(''),
Guido van Rossum805365e2007-05-07 22:24:25 +0000564 frozenset(range(0)), frozenset(frozenset()),
Raymond Hettingerd7946662005-08-01 21:39:29 +0000565 frozenset(f), f]
566 # All of the empty frozensets should have just one id()
567 self.assertEqual(len(set(map(id, efs))), 1)
568
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000569 def test_constructor_identity(self):
570 s = self.thetype(range(3))
571 t = self.thetype(s)
572 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000573
Raymond Hettingera690a992003-11-16 16:17:49 +0000574 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000575 self.assertEqual(hash(self.thetype('abcdeb')),
576 hash(self.thetype('ebecda')))
577
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000578 # make sure that all permutations give the same hash value
579 n = 100
Guido van Rossum805365e2007-05-07 22:24:25 +0000580 seq = [randrange(n) for i in range(n)]
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000581 results = set()
Guido van Rossum805365e2007-05-07 22:24:25 +0000582 for i in range(200):
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000583 shuffle(seq)
584 results.add(hash(self.thetype(seq)))
585 self.assertEqual(len(results), 1)
586
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000587 def test_copy(self):
588 dup = self.s.copy()
589 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000590
591 def test_frozen_as_dictkey(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000592 seq = list(range(10)) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000593 key1 = self.thetype(seq)
594 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000595 self.assertEqual(key1, key2)
596 self.assertNotEqual(id(key1), id(key2))
597 d = {}
598 d[key1] = 42
599 self.assertEqual(d[key2], 42)
600
601 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000602 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000603 self.assertEqual(hash(f), hash(f))
604
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000605 def test_hash_effectiveness(self):
606 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000607 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000608 addhashvalue = hashvalues.add
609 elemmasks = [(i+1, 1<<i) for i in range(n)]
Guido van Rossum805365e2007-05-07 22:24:25 +0000610 for i in range(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000611 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
612 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000613
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000614class FrozenSetSubclass(frozenset):
615 pass
616
617class TestFrozenSetSubclass(TestFrozenSet):
618 thetype = FrozenSetSubclass
619
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000620 def test_constructor_identity(self):
621 s = self.thetype(range(3))
622 t = self.thetype(s)
623 self.assertNotEqual(id(s), id(t))
624
625 def test_copy(self):
626 dup = self.s.copy()
627 self.assertNotEqual(id(self.s), id(dup))
628
629 def test_nested_empty_constructor(self):
630 s = self.thetype()
631 t = self.thetype(s)
632 self.assertEqual(s, t)
633
Raymond Hettingerd7946662005-08-01 21:39:29 +0000634 def test_singleton_empty_frozenset(self):
635 Frozenset = self.thetype
636 f = frozenset()
637 F = Frozenset()
638 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
639 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
Guido van Rossum805365e2007-05-07 22:24:25 +0000640 Frozenset(range(0)), Frozenset(Frozenset()),
Raymond Hettingerd7946662005-08-01 21:39:29 +0000641 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
642 # All empty frozenset subclass instances should have different ids
643 self.assertEqual(len(set(map(id, efs))), len(efs))
644
Raymond Hettingera690a992003-11-16 16:17:49 +0000645# Tests taken from test_sets.py =============================================
646
647empty_set = set()
648
649#==============================================================================
650
651class TestBasicOps(unittest.TestCase):
652
653 def test_repr(self):
654 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000655 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000656
Raymond Hettingereae05de2004-07-09 04:51:24 +0000657 def test_print(self):
658 try:
Guido van Rossum292aa0d2007-05-24 18:00:35 +0000659 fo = open(test_support.TESTFN, "w")
Guido van Rossumd8c19672007-02-09 21:54:58 +0000660 fo.write(str(self.set))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000661 fo.close()
Guido van Rossum292aa0d2007-05-24 18:00:35 +0000662 fo = open(test_support.TESTFN, "r")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000663 self.assertEqual(fo.read(), repr(self.set))
664 finally:
665 fo.close()
666 os.remove(test_support.TESTFN)
667
Raymond Hettingera690a992003-11-16 16:17:49 +0000668 def test_length(self):
669 self.assertEqual(len(self.set), self.length)
670
671 def test_self_equality(self):
672 self.assertEqual(self.set, self.set)
673
674 def test_equivalent_equality(self):
675 self.assertEqual(self.set, self.dup)
676
677 def test_copy(self):
678 self.assertEqual(self.set.copy(), self.dup)
679
680 def test_self_union(self):
681 result = self.set | self.set
682 self.assertEqual(result, self.dup)
683
684 def test_empty_union(self):
685 result = self.set | empty_set
686 self.assertEqual(result, self.dup)
687
688 def test_union_empty(self):
689 result = empty_set | self.set
690 self.assertEqual(result, self.dup)
691
692 def test_self_intersection(self):
693 result = self.set & self.set
694 self.assertEqual(result, self.dup)
695
696 def test_empty_intersection(self):
697 result = self.set & empty_set
698 self.assertEqual(result, empty_set)
699
700 def test_intersection_empty(self):
701 result = empty_set & self.set
702 self.assertEqual(result, empty_set)
703
704 def test_self_symmetric_difference(self):
705 result = self.set ^ self.set
706 self.assertEqual(result, empty_set)
707
708 def checkempty_symmetric_difference(self):
709 result = self.set ^ empty_set
710 self.assertEqual(result, self.set)
711
712 def test_self_difference(self):
713 result = self.set - self.set
714 self.assertEqual(result, empty_set)
715
716 def test_empty_difference(self):
717 result = self.set - empty_set
718 self.assertEqual(result, self.dup)
719
720 def test_empty_difference_rev(self):
721 result = empty_set - self.set
722 self.assertEqual(result, empty_set)
723
724 def test_iteration(self):
725 for v in self.set:
726 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000727 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000728 # note: __length_hint__ is an internal undocumented API,
729 # don't rely on it in your own programs
730 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000731
732 def test_pickling(self):
733 p = pickle.dumps(self.set)
734 copy = pickle.loads(p)
735 self.assertEqual(self.set, copy,
736 "%s != %s" % (self.set, copy))
737
738#------------------------------------------------------------------------------
739
740class TestBasicOpsEmpty(TestBasicOps):
741 def setUp(self):
742 self.case = "empty set"
743 self.values = []
744 self.set = set(self.values)
745 self.dup = set(self.values)
746 self.length = 0
Georg Brandlc4996ba2006-08-28 19:37:11 +0000747 self.repr = "set()"
Raymond Hettingera690a992003-11-16 16:17:49 +0000748
749#------------------------------------------------------------------------------
750
751class TestBasicOpsSingleton(TestBasicOps):
752 def setUp(self):
753 self.case = "unit set (number)"
754 self.values = [3]
755 self.set = set(self.values)
756 self.dup = set(self.values)
757 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000758 self.repr = "{3}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000759
760 def test_in(self):
761 self.failUnless(3 in self.set)
762
763 def test_not_in(self):
764 self.failUnless(2 not in self.set)
765
766#------------------------------------------------------------------------------
767
768class TestBasicOpsTuple(TestBasicOps):
769 def setUp(self):
770 self.case = "unit set (tuple)"
771 self.values = [(0, "zero")]
772 self.set = set(self.values)
773 self.dup = set(self.values)
774 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000775 self.repr = "{(0, 'zero')}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000776
777 def test_in(self):
778 self.failUnless((0, "zero") in self.set)
779
780 def test_not_in(self):
781 self.failUnless(9 not in self.set)
782
783#------------------------------------------------------------------------------
784
785class TestBasicOpsTriple(TestBasicOps):
786 def setUp(self):
787 self.case = "triple set"
788 self.values = [0, "zero", operator.add]
789 self.set = set(self.values)
790 self.dup = set(self.values)
791 self.length = 3
792 self.repr = None
793
794#==============================================================================
795
796def baditer():
797 raise TypeError
798 yield True
799
800def gooditer():
801 yield True
802
803class TestExceptionPropagation(unittest.TestCase):
804 """SF 628246: Set constructor should not trap iterator TypeErrors"""
805
806 def test_instanceWithException(self):
807 self.assertRaises(TypeError, set, baditer())
808
809 def test_instancesWithoutException(self):
810 # All of these iterables should load without exception.
811 set([1,2,3])
812 set((1,2,3))
813 set({'one':1, 'two':2, 'three':3})
Guido van Rossum805365e2007-05-07 22:24:25 +0000814 set(range(3))
Raymond Hettingera690a992003-11-16 16:17:49 +0000815 set('abc')
816 set(gooditer())
817
Neal Norwitzfcf44352005-11-27 20:37:43 +0000818 def test_changingSizeWhileIterating(self):
819 s = set([1,2,3])
820 try:
821 for i in s:
822 s.update([4])
823 except RuntimeError:
824 pass
825 else:
826 self.fail("no exception when changing size during iteration")
827
Raymond Hettingera690a992003-11-16 16:17:49 +0000828#==============================================================================
829
830class TestSetOfSets(unittest.TestCase):
831 def test_constructor(self):
832 inner = frozenset([1])
833 outer = set([inner])
834 element = outer.pop()
835 self.assertEqual(type(element), frozenset)
836 outer.add(inner) # Rebuild set of sets with .add method
837 outer.remove(inner)
838 self.assertEqual(outer, set()) # Verify that remove worked
839 outer.discard(inner) # Absence of KeyError indicates working fine
840
841#==============================================================================
842
843class TestBinaryOps(unittest.TestCase):
844 def setUp(self):
845 self.set = set((2, 4, 6))
846
847 def test_eq(self): # SF bug 643115
848 self.assertEqual(self.set, set({2:1,4:3,6:5}))
849
850 def test_union_subset(self):
851 result = self.set | set([2])
852 self.assertEqual(result, set((2, 4, 6)))
853
854 def test_union_superset(self):
855 result = self.set | set([2, 4, 6, 8])
856 self.assertEqual(result, set([2, 4, 6, 8]))
857
858 def test_union_overlap(self):
859 result = self.set | set([3, 4, 5])
860 self.assertEqual(result, set([2, 3, 4, 5, 6]))
861
862 def test_union_non_overlap(self):
863 result = self.set | set([8])
864 self.assertEqual(result, set([2, 4, 6, 8]))
865
866 def test_intersection_subset(self):
867 result = self.set & set((2, 4))
868 self.assertEqual(result, set((2, 4)))
869
870 def test_intersection_superset(self):
871 result = self.set & set([2, 4, 6, 8])
872 self.assertEqual(result, set([2, 4, 6]))
873
874 def test_intersection_overlap(self):
875 result = self.set & set([3, 4, 5])
876 self.assertEqual(result, set([4]))
877
878 def test_intersection_non_overlap(self):
879 result = self.set & set([8])
880 self.assertEqual(result, empty_set)
881
882 def test_sym_difference_subset(self):
883 result = self.set ^ set((2, 4))
884 self.assertEqual(result, set([6]))
885
886 def test_sym_difference_superset(self):
887 result = self.set ^ set((2, 4, 6, 8))
888 self.assertEqual(result, set([8]))
889
890 def test_sym_difference_overlap(self):
891 result = self.set ^ set((3, 4, 5))
892 self.assertEqual(result, set([2, 3, 5, 6]))
893
894 def test_sym_difference_non_overlap(self):
895 result = self.set ^ set([8])
896 self.assertEqual(result, set([2, 4, 6, 8]))
897
898 def test_cmp(self):
899 a, b = set('a'), set('b')
900 self.assertRaises(TypeError, cmp, a, b)
901
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000902 # In py3k, this works!
903 self.assertRaises(TypeError, cmp, a, a)
Raymond Hettingera690a992003-11-16 16:17:49 +0000904
905 self.assertRaises(TypeError, cmp, a, 12)
906 self.assertRaises(TypeError, cmp, "abc", a)
907
908#==============================================================================
909
910class TestUpdateOps(unittest.TestCase):
911 def setUp(self):
912 self.set = set((2, 4, 6))
913
914 def test_union_subset(self):
915 self.set |= set([2])
916 self.assertEqual(self.set, set((2, 4, 6)))
917
918 def test_union_superset(self):
919 self.set |= set([2, 4, 6, 8])
920 self.assertEqual(self.set, set([2, 4, 6, 8]))
921
922 def test_union_overlap(self):
923 self.set |= set([3, 4, 5])
924 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
925
926 def test_union_non_overlap(self):
927 self.set |= set([8])
928 self.assertEqual(self.set, set([2, 4, 6, 8]))
929
930 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000931 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +0000932 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
933
934 def test_intersection_subset(self):
935 self.set &= set((2, 4))
936 self.assertEqual(self.set, set((2, 4)))
937
938 def test_intersection_superset(self):
939 self.set &= set([2, 4, 6, 8])
940 self.assertEqual(self.set, set([2, 4, 6]))
941
942 def test_intersection_overlap(self):
943 self.set &= set([3, 4, 5])
944 self.assertEqual(self.set, set([4]))
945
946 def test_intersection_non_overlap(self):
947 self.set &= set([8])
948 self.assertEqual(self.set, empty_set)
949
950 def test_intersection_method_call(self):
951 self.set.intersection_update(set([3, 4, 5]))
952 self.assertEqual(self.set, set([4]))
953
954 def test_sym_difference_subset(self):
955 self.set ^= set((2, 4))
956 self.assertEqual(self.set, set([6]))
957
958 def test_sym_difference_superset(self):
959 self.set ^= set((2, 4, 6, 8))
960 self.assertEqual(self.set, set([8]))
961
962 def test_sym_difference_overlap(self):
963 self.set ^= set((3, 4, 5))
964 self.assertEqual(self.set, set([2, 3, 5, 6]))
965
966 def test_sym_difference_non_overlap(self):
967 self.set ^= set([8])
968 self.assertEqual(self.set, set([2, 4, 6, 8]))
969
970 def test_sym_difference_method_call(self):
971 self.set.symmetric_difference_update(set([3, 4, 5]))
972 self.assertEqual(self.set, set([2, 3, 5, 6]))
973
974 def test_difference_subset(self):
975 self.set -= set((2, 4))
976 self.assertEqual(self.set, set([6]))
977
978 def test_difference_superset(self):
979 self.set -= set((2, 4, 6, 8))
980 self.assertEqual(self.set, set([]))
981
982 def test_difference_overlap(self):
983 self.set -= set((3, 4, 5))
984 self.assertEqual(self.set, set([2, 6]))
985
986 def test_difference_non_overlap(self):
987 self.set -= set([8])
988 self.assertEqual(self.set, set([2, 4, 6]))
989
990 def test_difference_method_call(self):
991 self.set.difference_update(set([3, 4, 5]))
992 self.assertEqual(self.set, set([2, 6]))
993
994#==============================================================================
995
996class TestMutate(unittest.TestCase):
997 def setUp(self):
998 self.values = ["a", "b", "c"]
999 self.set = set(self.values)
1000
1001 def test_add_present(self):
1002 self.set.add("c")
1003 self.assertEqual(self.set, set("abc"))
1004
1005 def test_add_absent(self):
1006 self.set.add("d")
1007 self.assertEqual(self.set, set("abcd"))
1008
1009 def test_add_until_full(self):
1010 tmp = set()
1011 expected_len = 0
1012 for v in self.values:
1013 tmp.add(v)
1014 expected_len += 1
1015 self.assertEqual(len(tmp), expected_len)
1016 self.assertEqual(tmp, self.set)
1017
1018 def test_remove_present(self):
1019 self.set.remove("b")
1020 self.assertEqual(self.set, set("ac"))
1021
1022 def test_remove_absent(self):
1023 try:
1024 self.set.remove("d")
1025 self.fail("Removing missing element should have raised LookupError")
1026 except LookupError:
1027 pass
1028
1029 def test_remove_until_empty(self):
1030 expected_len = len(self.set)
1031 for v in self.values:
1032 self.set.remove(v)
1033 expected_len -= 1
1034 self.assertEqual(len(self.set), expected_len)
1035
1036 def test_discard_present(self):
1037 self.set.discard("c")
1038 self.assertEqual(self.set, set("ab"))
1039
1040 def test_discard_absent(self):
1041 self.set.discard("d")
1042 self.assertEqual(self.set, set("abc"))
1043
1044 def test_clear(self):
1045 self.set.clear()
1046 self.assertEqual(len(self.set), 0)
1047
1048 def test_pop(self):
1049 popped = {}
1050 while self.set:
1051 popped[self.set.pop()] = None
1052 self.assertEqual(len(popped), len(self.values))
1053 for v in self.values:
1054 self.failUnless(v in popped)
1055
1056 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001057 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001058 self.assertEqual(self.set, set(self.values))
1059
1060 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001061 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001062 self.assertEqual(self.set, set(self.values))
1063
1064 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001065 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001066 self.assertEqual(self.set, set(self.values + ["z"]))
1067
1068#==============================================================================
1069
1070class TestSubsets(unittest.TestCase):
1071
1072 case2method = {"<=": "issubset",
1073 ">=": "issuperset",
1074 }
1075
1076 reverse = {"==": "==",
1077 "!=": "!=",
1078 "<": ">",
1079 ">": "<",
1080 "<=": ">=",
1081 ">=": "<=",
1082 }
1083
1084 def test_issubset(self):
1085 x = self.left
1086 y = self.right
1087 for case in "!=", "==", "<", "<=", ">", ">=":
1088 expected = case in self.cases
1089 # Test the binary infix spelling.
1090 result = eval("x" + case + "y", locals())
1091 self.assertEqual(result, expected)
1092 # Test the "friendly" method-name spelling, if one exists.
1093 if case in TestSubsets.case2method:
1094 method = getattr(x, TestSubsets.case2method[case])
1095 result = method(y)
1096 self.assertEqual(result, expected)
1097
1098 # Now do the same for the operands reversed.
1099 rcase = TestSubsets.reverse[case]
1100 result = eval("y" + rcase + "x", locals())
1101 self.assertEqual(result, expected)
1102 if rcase in TestSubsets.case2method:
1103 method = getattr(y, TestSubsets.case2method[rcase])
1104 result = method(x)
1105 self.assertEqual(result, expected)
1106#------------------------------------------------------------------------------
1107
1108class TestSubsetEqualEmpty(TestSubsets):
1109 left = set()
1110 right = set()
1111 name = "both empty"
1112 cases = "==", "<=", ">="
1113
1114#------------------------------------------------------------------------------
1115
1116class TestSubsetEqualNonEmpty(TestSubsets):
1117 left = set([1, 2])
1118 right = set([1, 2])
1119 name = "equal pair"
1120 cases = "==", "<=", ">="
1121
1122#------------------------------------------------------------------------------
1123
1124class TestSubsetEmptyNonEmpty(TestSubsets):
1125 left = set()
1126 right = set([1, 2])
1127 name = "one empty, one non-empty"
1128 cases = "!=", "<", "<="
1129
1130#------------------------------------------------------------------------------
1131
1132class TestSubsetPartial(TestSubsets):
1133 left = set([1])
1134 right = set([1, 2])
1135 name = "one a non-empty proper subset of other"
1136 cases = "!=", "<", "<="
1137
1138#------------------------------------------------------------------------------
1139
1140class TestSubsetNonOverlap(TestSubsets):
1141 left = set([1])
1142 right = set([2])
1143 name = "neither empty, neither contains"
1144 cases = "!="
1145
1146#==============================================================================
1147
1148class TestOnlySetsInBinaryOps(unittest.TestCase):
1149
1150 def test_eq_ne(self):
1151 # Unlike the others, this is testing that == and != *are* allowed.
1152 self.assertEqual(self.other == self.set, False)
1153 self.assertEqual(self.set == self.other, False)
1154 self.assertEqual(self.other != self.set, True)
1155 self.assertEqual(self.set != self.other, True)
1156
1157 def test_ge_gt_le_lt(self):
1158 self.assertRaises(TypeError, lambda: self.set < self.other)
1159 self.assertRaises(TypeError, lambda: self.set <= self.other)
1160 self.assertRaises(TypeError, lambda: self.set > self.other)
1161 self.assertRaises(TypeError, lambda: self.set >= self.other)
1162
1163 self.assertRaises(TypeError, lambda: self.other < self.set)
1164 self.assertRaises(TypeError, lambda: self.other <= self.set)
1165 self.assertRaises(TypeError, lambda: self.other > self.set)
1166 self.assertRaises(TypeError, lambda: self.other >= self.set)
1167
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001168 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001169 try:
1170 self.set |= self.other
1171 except TypeError:
1172 pass
1173 else:
1174 self.fail("expected TypeError")
1175
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001176 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001177 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001178 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001179 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001180 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001181
1182 def test_union(self):
1183 self.assertRaises(TypeError, lambda: self.set | self.other)
1184 self.assertRaises(TypeError, lambda: self.other | self.set)
1185 if self.otherIsIterable:
1186 self.set.union(self.other)
1187 else:
1188 self.assertRaises(TypeError, self.set.union, self.other)
1189
1190 def test_intersection_update_operator(self):
1191 try:
1192 self.set &= self.other
1193 except TypeError:
1194 pass
1195 else:
1196 self.fail("expected TypeError")
1197
1198 def test_intersection_update(self):
1199 if self.otherIsIterable:
1200 self.set.intersection_update(self.other)
1201 else:
1202 self.assertRaises(TypeError,
1203 self.set.intersection_update,
1204 self.other)
1205
1206 def test_intersection(self):
1207 self.assertRaises(TypeError, lambda: self.set & self.other)
1208 self.assertRaises(TypeError, lambda: self.other & self.set)
1209 if self.otherIsIterable:
1210 self.set.intersection(self.other)
1211 else:
1212 self.assertRaises(TypeError, self.set.intersection, self.other)
1213
1214 def test_sym_difference_update_operator(self):
1215 try:
1216 self.set ^= self.other
1217 except TypeError:
1218 pass
1219 else:
1220 self.fail("expected TypeError")
1221
1222 def test_sym_difference_update(self):
1223 if self.otherIsIterable:
1224 self.set.symmetric_difference_update(self.other)
1225 else:
1226 self.assertRaises(TypeError,
1227 self.set.symmetric_difference_update,
1228 self.other)
1229
1230 def test_sym_difference(self):
1231 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1232 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1233 if self.otherIsIterable:
1234 self.set.symmetric_difference(self.other)
1235 else:
1236 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1237
1238 def test_difference_update_operator(self):
1239 try:
1240 self.set -= self.other
1241 except TypeError:
1242 pass
1243 else:
1244 self.fail("expected TypeError")
1245
1246 def test_difference_update(self):
1247 if self.otherIsIterable:
1248 self.set.difference_update(self.other)
1249 else:
1250 self.assertRaises(TypeError,
1251 self.set.difference_update,
1252 self.other)
1253
1254 def test_difference(self):
1255 self.assertRaises(TypeError, lambda: self.set - self.other)
1256 self.assertRaises(TypeError, lambda: self.other - self.set)
1257 if self.otherIsIterable:
1258 self.set.difference(self.other)
1259 else:
1260 self.assertRaises(TypeError, self.set.difference, self.other)
1261
1262#------------------------------------------------------------------------------
1263
1264class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1265 def setUp(self):
1266 self.set = set((1, 2, 3))
1267 self.other = 19
1268 self.otherIsIterable = False
1269
1270#------------------------------------------------------------------------------
1271
1272class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1273 def setUp(self):
1274 self.set = set((1, 2, 3))
1275 self.other = {1:2, 3:4}
1276 self.otherIsIterable = True
1277
1278#------------------------------------------------------------------------------
1279
1280class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1281 def setUp(self):
1282 self.set = set((1, 2, 3))
1283 self.other = operator.add
1284 self.otherIsIterable = False
1285
1286#------------------------------------------------------------------------------
1287
1288class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1289 def setUp(self):
1290 self.set = set((1, 2, 3))
1291 self.other = (2, 4, 6)
1292 self.otherIsIterable = True
1293
1294#------------------------------------------------------------------------------
1295
1296class TestOnlySetsString(TestOnlySetsInBinaryOps):
1297 def setUp(self):
1298 self.set = set((1, 2, 3))
1299 self.other = 'abc'
1300 self.otherIsIterable = True
1301
1302#------------------------------------------------------------------------------
1303
1304class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1305 def setUp(self):
1306 def gen():
Guido van Rossum805365e2007-05-07 22:24:25 +00001307 for i in range(0, 10, 2):
Raymond Hettingera690a992003-11-16 16:17:49 +00001308 yield i
1309 self.set = set((1, 2, 3))
1310 self.other = gen()
1311 self.otherIsIterable = True
1312
1313#==============================================================================
1314
1315class TestCopying(unittest.TestCase):
1316
1317 def test_copy(self):
1318 dup = self.set.copy()
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001319 dup_list = sorted(dup, key=repr)
1320 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001321 self.assertEqual(len(dup_list), len(set_list))
1322 for i in range(len(dup_list)):
1323 self.failUnless(dup_list[i] is set_list[i])
1324
1325 def test_deep_copy(self):
1326 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001327 ##print type(dup), repr(dup)
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001328 dup_list = sorted(dup, key=repr)
1329 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001330 self.assertEqual(len(dup_list), len(set_list))
1331 for i in range(len(dup_list)):
1332 self.assertEqual(dup_list[i], set_list[i])
1333
1334#------------------------------------------------------------------------------
1335
1336class TestCopyingEmpty(TestCopying):
1337 def setUp(self):
1338 self.set = set()
1339
1340#------------------------------------------------------------------------------
1341
1342class TestCopyingSingleton(TestCopying):
1343 def setUp(self):
1344 self.set = set(["hello"])
1345
1346#------------------------------------------------------------------------------
1347
1348class TestCopyingTriple(TestCopying):
1349 def setUp(self):
1350 self.set = set(["zero", 0, None])
1351
1352#------------------------------------------------------------------------------
1353
1354class TestCopyingTuple(TestCopying):
1355 def setUp(self):
1356 self.set = set([(1, 2)])
1357
1358#------------------------------------------------------------------------------
1359
1360class TestCopyingNested(TestCopying):
1361 def setUp(self):
1362 self.set = set([((1, 2), (3, 4))])
1363
1364#==============================================================================
1365
1366class TestIdentities(unittest.TestCase):
1367 def setUp(self):
1368 self.a = set('abracadabra')
1369 self.b = set('alacazam')
1370
1371 def test_binopsVsSubsets(self):
1372 a, b = self.a, self.b
1373 self.assert_(a - b < a)
1374 self.assert_(b - a < b)
1375 self.assert_(a & b < a)
1376 self.assert_(a & b < b)
1377 self.assert_(a | b > a)
1378 self.assert_(a | b > b)
1379 self.assert_(a ^ b < a | b)
1380
1381 def test_commutativity(self):
1382 a, b = self.a, self.b
1383 self.assertEqual(a&b, b&a)
1384 self.assertEqual(a|b, b|a)
1385 self.assertEqual(a^b, b^a)
1386 if a != b:
1387 self.assertNotEqual(a-b, b-a)
1388
1389 def test_summations(self):
1390 # check that sums of parts equal the whole
1391 a, b = self.a, self.b
1392 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1393 self.assertEqual((a&b)|(a^b), a|b)
1394 self.assertEqual(a|(b-a), a|b)
1395 self.assertEqual((a-b)|b, a|b)
1396 self.assertEqual((a-b)|(a&b), a)
1397 self.assertEqual((b-a)|(a&b), b)
1398 self.assertEqual((a-b)|(b-a), a^b)
1399
1400 def test_exclusion(self):
1401 # check that inverse operations show non-overlap
1402 a, b, zero = self.a, self.b, set()
1403 self.assertEqual((a-b)&b, zero)
1404 self.assertEqual((b-a)&a, zero)
1405 self.assertEqual((a&b)&(a^b), zero)
1406
1407# Tests derived from test_itertools.py =======================================
1408
1409def R(seqn):
1410 'Regular generator'
1411 for i in seqn:
1412 yield i
1413
1414class G:
1415 'Sequence using __getitem__'
1416 def __init__(self, seqn):
1417 self.seqn = seqn
1418 def __getitem__(self, i):
1419 return self.seqn[i]
1420
1421class I:
1422 'Sequence using iterator protocol'
1423 def __init__(self, seqn):
1424 self.seqn = seqn
1425 self.i = 0
1426 def __iter__(self):
1427 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001428 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001429 if self.i >= len(self.seqn): raise StopIteration
1430 v = self.seqn[self.i]
1431 self.i += 1
1432 return v
1433
1434class Ig:
1435 'Sequence using iterator protocol defined with a generator'
1436 def __init__(self, seqn):
1437 self.seqn = seqn
1438 self.i = 0
1439 def __iter__(self):
1440 for val in self.seqn:
1441 yield val
1442
1443class X:
1444 'Missing __getitem__ and __iter__'
1445 def __init__(self, seqn):
1446 self.seqn = seqn
1447 self.i = 0
Georg Brandla18af4e2007-04-21 15:47:16 +00001448 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001449 if self.i >= len(self.seqn): raise StopIteration
1450 v = self.seqn[self.i]
1451 self.i += 1
1452 return v
1453
1454class N:
Georg Brandla18af4e2007-04-21 15:47:16 +00001455 'Iterator missing __next__()'
Raymond Hettingera690a992003-11-16 16:17:49 +00001456 def __init__(self, seqn):
1457 self.seqn = seqn
1458 self.i = 0
1459 def __iter__(self):
1460 return self
1461
1462class E:
1463 'Test propagation of exceptions'
1464 def __init__(self, seqn):
1465 self.seqn = seqn
1466 self.i = 0
1467 def __iter__(self):
1468 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001469 def __next__(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001470 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001471
1472class S:
1473 'Test immediate stop'
1474 def __init__(self, seqn):
1475 pass
1476 def __iter__(self):
1477 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001478 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001479 raise StopIteration
1480
1481from itertools import chain, imap
1482def L(seqn):
1483 'Test multiple tiers of iterators'
1484 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1485
1486class TestVariousIteratorArgs(unittest.TestCase):
1487
1488 def test_constructor(self):
1489 for cons in (set, frozenset):
Guido van Rossum805365e2007-05-07 22:24:25 +00001490 for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
Raymond Hettingera690a992003-11-16 16:17:49 +00001491 for g in (G, I, Ig, S, L, R):
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001492 self.assertEqual(sorted(cons(g(s)), key=repr), sorted(g(s), key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001493 self.assertRaises(TypeError, cons , X(s))
1494 self.assertRaises(TypeError, cons , N(s))
1495 self.assertRaises(ZeroDivisionError, cons , E(s))
1496
1497 def test_inline_methods(self):
1498 s = set('november')
Guido van Rossum805365e2007-05-07 22:24:25 +00001499 for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
Raymond Hettingera690a992003-11-16 16:17:49 +00001500 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference):
1501 for g in (G, I, Ig, L, R):
1502 expected = meth(data)
1503 actual = meth(G(data))
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001504 self.assertEqual(sorted(actual, key=repr), sorted(expected, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001505 self.assertRaises(TypeError, meth, X(s))
1506 self.assertRaises(TypeError, meth, N(s))
1507 self.assertRaises(ZeroDivisionError, meth, E(s))
1508
1509 def test_inplace_methods(self):
Guido van Rossum805365e2007-05-07 22:24:25 +00001510 for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001511 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001512 'difference_update', 'symmetric_difference_update'):
1513 for g in (G, I, Ig, S, L, R):
1514 s = set('january')
1515 t = s.copy()
1516 getattr(s, methname)(list(g(data)))
1517 getattr(t, methname)(g(data))
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001518 self.assertEqual(sorted(s, key=repr), sorted(t, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001519
1520 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1521 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1522 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1523
1524#==============================================================================
1525
1526def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001527 test_classes = (
1528 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001529 TestSetSubclass,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001530 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001531 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001532 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001533 TestSetOfSets,
1534 TestExceptionPropagation,
1535 TestBasicOpsEmpty,
1536 TestBasicOpsSingleton,
1537 TestBasicOpsTuple,
1538 TestBasicOpsTriple,
1539 TestBinaryOps,
1540 TestUpdateOps,
1541 TestMutate,
1542 TestSubsetEqualEmpty,
1543 TestSubsetEqualNonEmpty,
1544 TestSubsetEmptyNonEmpty,
1545 TestSubsetPartial,
1546 TestSubsetNonOverlap,
1547 TestOnlySetsNumeric,
1548 TestOnlySetsDict,
1549 TestOnlySetsOperator,
1550 TestOnlySetsTuple,
1551 TestOnlySetsString,
1552 TestOnlySetsGenerator,
1553 TestCopyingEmpty,
1554 TestCopyingSingleton,
1555 TestCopyingTriple,
1556 TestCopyingTuple,
1557 TestCopyingNested,
1558 TestIdentities,
1559 TestVariousIteratorArgs,
1560 )
1561
1562 test_support.run_unittest(*test_classes)
1563
1564 # verify reference counting
1565 if verbose and hasattr(sys, "gettotalrefcount"):
1566 import gc
1567 counts = [None] * 5
Guido van Rossum805365e2007-05-07 22:24:25 +00001568 for i in range(len(counts)):
Raymond Hettingera690a992003-11-16 16:17:49 +00001569 test_support.run_unittest(*test_classes)
1570 gc.collect()
1571 counts[i] = sys.gettotalrefcount()
Guido van Rossumd8c19672007-02-09 21:54:58 +00001572 print(counts)
Raymond Hettingera690a992003-11-16 16:17:49 +00001573
1574if __name__ == "__main__":
1575 test_main(verbose=True)