blob: e1a98a34b9fae8583fc18722b1a2dd8b5bbc597e [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
Raymond Hettingera690a992003-11-16 16:17:49 +000029class TestJointOps(unittest.TestCase):
30 # Tests common to both set and frozenset
31
32 def setUp(self):
33 self.word = word = 'simsalabim'
34 self.otherword = 'madagascar'
35 self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
36 self.s = self.thetype(word)
37 self.d = dict.fromkeys(word)
38
Raymond Hettinger6429a472004-09-28 01:51:35 +000039 def test_new_or_init(self):
40 self.assertRaises(TypeError, self.thetype, [], 2)
41
Raymond Hettingera690a992003-11-16 16:17:49 +000042 def test_uniquification(self):
Raymond Hettinger64958a12003-12-17 20:43:33 +000043 actual = sorted(self.s)
44 expected = sorted(self.d)
Raymond Hettingera690a992003-11-16 16:17:49 +000045 self.assertEqual(actual, expected)
46 self.assertRaises(PassThru, self.thetype, check_pass_thru())
47 self.assertRaises(TypeError, self.thetype, [[]])
48
49 def test_len(self):
50 self.assertEqual(len(self.s), len(self.d))
51
52 def test_contains(self):
53 for c in self.letters:
54 self.assertEqual(c in self.s, c in self.d)
55 self.assertRaises(TypeError, self.s.__contains__, [[]])
Raymond Hettinger19c2d772003-11-21 18:36:54 +000056 s = self.thetype([frozenset(self.letters)])
57 self.assert_(self.thetype(self.letters) in s)
Raymond Hettingera690a992003-11-16 16:17:49 +000058
Raymond Hettingera690a992003-11-16 16:17:49 +000059 def test_union(self):
60 u = self.s.union(self.otherword)
61 for c in self.letters:
62 self.assertEqual(c in u, c in self.d or c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000063 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000064 self.assertEqual(type(u), self.thetype)
65 self.assertRaises(PassThru, self.s.union, check_pass_thru())
66 self.assertRaises(TypeError, self.s.union, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000067 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
68 self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
69 self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
70 self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
71 self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +000072
73 def test_or(self):
74 i = self.s.union(self.otherword)
75 self.assertEqual(self.s | set(self.otherword), i)
76 self.assertEqual(self.s | frozenset(self.otherword), i)
77 try:
78 self.s | self.otherword
79 except TypeError:
80 pass
81 else:
82 self.fail("s|t did not screen-out general iterables")
83
84 def test_intersection(self):
85 i = self.s.intersection(self.otherword)
86 for c in self.letters:
87 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000088 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000089 self.assertEqual(type(i), self.thetype)
90 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000091 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
92 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
93 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
94 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
95 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Raymond Hettingera690a992003-11-16 16:17:49 +000096
97 def test_and(self):
98 i = self.s.intersection(self.otherword)
99 self.assertEqual(self.s & set(self.otherword), i)
100 self.assertEqual(self.s & frozenset(self.otherword), i)
101 try:
102 self.s & self.otherword
103 except TypeError:
104 pass
105 else:
106 self.fail("s&t did not screen-out general iterables")
107
108 def test_difference(self):
109 i = self.s.difference(self.otherword)
110 for c in self.letters:
111 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000112 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000113 self.assertEqual(type(i), self.thetype)
114 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
115 self.assertRaises(TypeError, self.s.difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000116 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
117 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
118 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
119 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
120 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000121
122 def test_sub(self):
123 i = self.s.difference(self.otherword)
124 self.assertEqual(self.s - set(self.otherword), i)
125 self.assertEqual(self.s - frozenset(self.otherword), i)
126 try:
127 self.s - self.otherword
128 except TypeError:
129 pass
130 else:
131 self.fail("s-t did not screen-out general iterables")
132
133 def test_symmetric_difference(self):
134 i = self.s.symmetric_difference(self.otherword)
135 for c in self.letters:
136 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000137 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000138 self.assertEqual(type(i), self.thetype)
139 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
140 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000141 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
142 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
143 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
144 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
145 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000146
147 def test_xor(self):
148 i = self.s.symmetric_difference(self.otherword)
149 self.assertEqual(self.s ^ set(self.otherword), i)
150 self.assertEqual(self.s ^ frozenset(self.otherword), i)
151 try:
152 self.s ^ self.otherword
153 except TypeError:
154 pass
155 else:
156 self.fail("s^t did not screen-out general iterables")
157
158 def test_equality(self):
159 self.assertEqual(self.s, set(self.word))
160 self.assertEqual(self.s, frozenset(self.word))
161 self.assertEqual(self.s == self.word, False)
162 self.assertNotEqual(self.s, set(self.otherword))
163 self.assertNotEqual(self.s, frozenset(self.otherword))
164 self.assertEqual(self.s != self.word, True)
165
166 def test_setOfFrozensets(self):
167 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
168 s = self.thetype(t)
169 self.assertEqual(len(s), 3)
170
171 def test_compare(self):
172 self.assertRaises(TypeError, self.s.__cmp__, self.s)
173
174 def test_sub_and_super(self):
175 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
176 self.assert_(p < q)
177 self.assert_(p <= q)
178 self.assert_(q <= q)
179 self.assert_(q > p)
180 self.assert_(q >= p)
181 self.failIf(q < r)
182 self.failIf(q <= r)
183 self.failIf(q > r)
184 self.failIf(q >= r)
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000185 self.assert_(set('a').issubset('abc'))
186 self.assert_(set('abc').issuperset('a'))
187 self.failIf(set('a').issubset('cbs'))
188 self.failIf(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000189
190 def test_pickling(self):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000191 for i in (0, 1, 2):
192 p = pickle.dumps(self.s, i)
193 dup = pickle.loads(p)
194 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
195 if type(self.s) not in (set, frozenset):
196 self.s.x = 10
197 p = pickle.dumps(self.s)
198 dup = pickle.loads(p)
199 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000200
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000201 def test_deepcopy(self):
202 class Tracer:
203 def __init__(self, value):
204 self.value = value
205 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000206 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000207 def __deepcopy__(self, memo=None):
208 return Tracer(self.value + 1)
209 t = Tracer(10)
210 s = self.thetype([t])
211 dup = copy.deepcopy(s)
212 self.assertNotEqual(id(s), id(dup))
213 for elem in dup:
214 newt = elem
215 self.assertNotEqual(id(t), id(newt))
216 self.assertEqual(t.value + 1, newt.value)
217
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000218 def test_gc(self):
219 # Create a nest of cycles to exercise overall ref count check
220 class A:
221 pass
222 s = set(A() for i in xrange(1000))
223 for elem in s:
224 elem.cycle = s
225 elem.sub = elem
226 elem.set = set([elem])
227
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000228 def test_subclass_with_custom_hash(self):
229 # Bug #1257731
230 class H(self.thetype):
231 def __hash__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000232 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000233 s=H()
234 f=set()
235 f.add(s)
236 self.assert_(s in f)
237 f.remove(s)
238 f.add(s)
239 f.discard(s)
240
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000241 def test_badcmp(self):
242 s = self.thetype([BadCmp()])
243 # Detect comparison errors during insertion and lookup
244 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
245 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
246 # Detect errors during mutating operations
247 if hasattr(s, 'add'):
248 self.assertRaises(RuntimeError, s.add, BadCmp())
249 self.assertRaises(RuntimeError, s.discard, BadCmp())
250 self.assertRaises(RuntimeError, s.remove, BadCmp())
251
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000252 def test_cyclical_repr(self):
253 w = ReprWrapper()
254 s = self.thetype([w])
255 w.value = s
256 if self.thetype == set:
257 self.assertEqual(repr(s), '{set(...)}')
258 else:
259 name = repr(s).partition('(')[0] # strip class name
260 self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
261
262 def test_cyclical_print(self):
263 w = ReprWrapper()
264 s = self.thetype([w])
265 w.value = s
266 try:
267 fo = open(test_support.TESTFN, "wb")
268 print >> fo, s,
269 fo.close()
270 fo = open(test_support.TESTFN, "rb")
271 self.assertEqual(fo.read(), repr(s))
272 finally:
273 fo.close()
274 os.remove(test_support.TESTFN)
275
Raymond Hettingera690a992003-11-16 16:17:49 +0000276class TestSet(TestJointOps):
277 thetype = set
278
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000279 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000280 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000281 s.__init__(self.word)
282 self.assertEqual(s, set(self.word))
283 s.__init__(self.otherword)
284 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000285 self.assertRaises(TypeError, s.__init__, s, 2);
286 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000287
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000288 def test_constructor_identity(self):
289 s = self.thetype(range(3))
290 t = self.thetype(s)
291 self.assertNotEqual(id(s), id(t))
292
Guido van Rossum86e58e22006-08-28 15:27:34 +0000293 def test_set_literal(self):
294 s = set([1,2,3])
295 t = {1,2,3}
296 self.assertEqual(s, t)
297
Raymond Hettingera690a992003-11-16 16:17:49 +0000298 def test_hash(self):
299 self.assertRaises(TypeError, hash, self.s)
300
301 def test_clear(self):
302 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000303 self.assertEqual(self.s, set())
304 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000305
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000306 def test_copy(self):
307 dup = self.s.copy()
308 self.assertEqual(self.s, dup)
309 self.assertNotEqual(id(self.s), id(dup))
310
Raymond Hettingera690a992003-11-16 16:17:49 +0000311 def test_add(self):
312 self.s.add('Q')
313 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000314 dup = self.s.copy()
315 self.s.add('Q')
316 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000317 self.assertRaises(TypeError, self.s.add, [])
318
319 def test_remove(self):
320 self.s.remove('a')
321 self.assert_('a' not in self.s)
322 self.assertRaises(KeyError, self.s.remove, 'Q')
323 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000324 s = self.thetype([frozenset(self.word)])
325 self.assert_(self.thetype(self.word) in s)
326 s.remove(self.thetype(self.word))
327 self.assert_(self.thetype(self.word) not in s)
328 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000329
Thomas Wouters89f507f2006-12-13 04:49:30 +0000330 def test_remove_keyerror_unpacking(self):
331 # bug: www.python.org/sf/1576657
332 for v1 in ['Q', (1,)]:
333 try:
334 self.s.remove(v1)
Guido van Rossumb940e112007-01-10 16:19:56 +0000335 except KeyError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000336 v2 = e.args[0]
337 self.assertEqual(v1, v2)
338 else:
339 self.fail()
340
Raymond Hettingera690a992003-11-16 16:17:49 +0000341 def test_discard(self):
342 self.s.discard('a')
343 self.assert_('a' not in self.s)
344 self.s.discard('Q')
345 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000346 s = self.thetype([frozenset(self.word)])
347 self.assert_(self.thetype(self.word) in s)
348 s.discard(self.thetype(self.word))
349 self.assert_(self.thetype(self.word) not in s)
350 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000351
352 def test_pop(self):
353 for i in xrange(len(self.s)):
354 elem = self.s.pop()
355 self.assert_(elem not in self.s)
356 self.assertRaises(KeyError, self.s.pop)
357
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000358 def test_update(self):
359 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000360 self.assertEqual(retval, None)
361 for c in (self.word + self.otherword):
362 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000363 self.assertRaises(PassThru, self.s.update, check_pass_thru())
364 self.assertRaises(TypeError, self.s.update, [[]])
365 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
366 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
367 s = self.thetype('abcba')
368 self.assertEqual(s.update(C(p)), None)
369 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000370
371 def test_ior(self):
372 self.s |= set(self.otherword)
373 for c in (self.word + self.otherword):
374 self.assert_(c in self.s)
375
376 def test_intersection_update(self):
377 retval = self.s.intersection_update(self.otherword)
378 self.assertEqual(retval, None)
379 for c in (self.word + self.otherword):
380 if c in self.otherword and c in self.word:
381 self.assert_(c in self.s)
382 else:
383 self.assert_(c not in self.s)
384 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
385 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000386 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
387 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
388 s = self.thetype('abcba')
389 self.assertEqual(s.intersection_update(C(p)), None)
390 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000391
392 def test_iand(self):
393 self.s &= set(self.otherword)
394 for c in (self.word + self.otherword):
395 if c in self.otherword and c in self.word:
396 self.assert_(c in self.s)
397 else:
398 self.assert_(c not in self.s)
399
400 def test_difference_update(self):
401 retval = self.s.difference_update(self.otherword)
402 self.assertEqual(retval, None)
403 for c in (self.word + self.otherword):
404 if c in self.word and c not in self.otherword:
405 self.assert_(c in self.s)
406 else:
407 self.assert_(c not in self.s)
408 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
409 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000410 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
411 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
412 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
413 s = self.thetype('abcba')
414 self.assertEqual(s.difference_update(C(p)), None)
415 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000416
417 def test_isub(self):
418 self.s -= set(self.otherword)
419 for c in (self.word + self.otherword):
420 if c in self.word and c not in self.otherword:
421 self.assert_(c in self.s)
422 else:
423 self.assert_(c not in self.s)
424
425 def test_symmetric_difference_update(self):
426 retval = self.s.symmetric_difference_update(self.otherword)
427 self.assertEqual(retval, None)
428 for c in (self.word + self.otherword):
429 if (c in self.word) ^ (c in self.otherword):
430 self.assert_(c in self.s)
431 else:
432 self.assert_(c not in self.s)
433 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
434 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000435 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
436 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
437 s = self.thetype('abcba')
438 self.assertEqual(s.symmetric_difference_update(C(p)), None)
439 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000440
441 def test_ixor(self):
442 self.s ^= set(self.otherword)
443 for c in (self.word + self.otherword):
444 if (c in self.word) ^ (c in self.otherword):
445 self.assert_(c in self.s)
446 else:
447 self.assert_(c not in self.s)
448
Raymond Hettingerc991db22005-08-11 07:58:45 +0000449 def test_inplace_on_self(self):
450 t = self.s.copy()
451 t |= t
452 self.assertEqual(t, self.s)
453 t &= t
454 self.assertEqual(t, self.s)
455 t -= t
456 self.assertEqual(t, self.thetype())
457 t = self.s.copy()
458 t ^= t
459 self.assertEqual(t, self.thetype())
460
Raymond Hettinger691d8052004-05-30 07:26:47 +0000461 def test_weakref(self):
462 s = self.thetype('gallahad')
463 p = proxy(s)
464 self.assertEqual(str(p), str(s))
465 s = None
466 self.assertRaises(ReferenceError, str, p)
467
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000468 # C API test only available in a debug build
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000469 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000470 def test_c_api(self):
471 self.assertEqual(set('abc').test_c_api(), True)
472
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000473class SetSubclass(set):
474 pass
475
476class TestSetSubclass(TestSet):
477 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000478
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000479class SetSubclassWithKeywordArgs(set):
480 def __init__(self, iterable=[], newarg=None):
481 set.__init__(self, iterable)
482
483class TestSetSubclassWithKeywordArgs(TestSet):
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000484
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000485 def test_keywords_in_subclass(self):
486 'SF bug #1486663 -- this used to erroneously raise a TypeError'
487 SetSubclassWithKeywordArgs(newarg=1)
488
Raymond Hettingera690a992003-11-16 16:17:49 +0000489class TestFrozenSet(TestJointOps):
490 thetype = frozenset
491
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000492 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000493 s = self.thetype(self.word)
494 s.__init__(self.otherword)
495 self.assertEqual(s, set(self.word))
496
Raymond Hettingerd7946662005-08-01 21:39:29 +0000497 def test_singleton_empty_frozenset(self):
498 f = frozenset()
499 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
500 frozenset(), frozenset([]), frozenset(()), frozenset(''),
501 frozenset(xrange(0)), frozenset(frozenset()),
502 frozenset(f), f]
503 # All of the empty frozensets should have just one id()
504 self.assertEqual(len(set(map(id, efs))), 1)
505
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000506 def test_constructor_identity(self):
507 s = self.thetype(range(3))
508 t = self.thetype(s)
509 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000510
Raymond Hettingera690a992003-11-16 16:17:49 +0000511 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000512 self.assertEqual(hash(self.thetype('abcdeb')),
513 hash(self.thetype('ebecda')))
514
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000515 # make sure that all permutations give the same hash value
516 n = 100
517 seq = [randrange(n) for i in xrange(n)]
518 results = set()
519 for i in xrange(200):
520 shuffle(seq)
521 results.add(hash(self.thetype(seq)))
522 self.assertEqual(len(results), 1)
523
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000524 def test_copy(self):
525 dup = self.s.copy()
526 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000527
528 def test_frozen_as_dictkey(self):
529 seq = range(10) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000530 key1 = self.thetype(seq)
531 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000532 self.assertEqual(key1, key2)
533 self.assertNotEqual(id(key1), id(key2))
534 d = {}
535 d[key1] = 42
536 self.assertEqual(d[key2], 42)
537
538 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000539 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000540 self.assertEqual(hash(f), hash(f))
541
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000542 def test_hash_effectiveness(self):
543 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000544 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000545 addhashvalue = hashvalues.add
546 elemmasks = [(i+1, 1<<i) for i in range(n)]
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000547 for i in xrange(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000548 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
549 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000550
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000551class FrozenSetSubclass(frozenset):
552 pass
553
554class TestFrozenSetSubclass(TestFrozenSet):
555 thetype = FrozenSetSubclass
556
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000557 def test_constructor_identity(self):
558 s = self.thetype(range(3))
559 t = self.thetype(s)
560 self.assertNotEqual(id(s), id(t))
561
562 def test_copy(self):
563 dup = self.s.copy()
564 self.assertNotEqual(id(self.s), id(dup))
565
566 def test_nested_empty_constructor(self):
567 s = self.thetype()
568 t = self.thetype(s)
569 self.assertEqual(s, t)
570
Raymond Hettingerd7946662005-08-01 21:39:29 +0000571 def test_singleton_empty_frozenset(self):
572 Frozenset = self.thetype
573 f = frozenset()
574 F = Frozenset()
575 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
576 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
577 Frozenset(xrange(0)), Frozenset(Frozenset()),
578 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
579 # All empty frozenset subclass instances should have different ids
580 self.assertEqual(len(set(map(id, efs))), len(efs))
581
Raymond Hettingera690a992003-11-16 16:17:49 +0000582# Tests taken from test_sets.py =============================================
583
584empty_set = set()
585
586#==============================================================================
587
588class TestBasicOps(unittest.TestCase):
589
590 def test_repr(self):
591 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000592 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000593
Raymond Hettingereae05de2004-07-09 04:51:24 +0000594 def test_print(self):
595 try:
596 fo = open(test_support.TESTFN, "wb")
597 print >> fo, self.set,
598 fo.close()
599 fo = open(test_support.TESTFN, "rb")
600 self.assertEqual(fo.read(), repr(self.set))
601 finally:
602 fo.close()
603 os.remove(test_support.TESTFN)
604
Raymond Hettingera690a992003-11-16 16:17:49 +0000605 def test_length(self):
606 self.assertEqual(len(self.set), self.length)
607
608 def test_self_equality(self):
609 self.assertEqual(self.set, self.set)
610
611 def test_equivalent_equality(self):
612 self.assertEqual(self.set, self.dup)
613
614 def test_copy(self):
615 self.assertEqual(self.set.copy(), self.dup)
616
617 def test_self_union(self):
618 result = self.set | self.set
619 self.assertEqual(result, self.dup)
620
621 def test_empty_union(self):
622 result = self.set | empty_set
623 self.assertEqual(result, self.dup)
624
625 def test_union_empty(self):
626 result = empty_set | self.set
627 self.assertEqual(result, self.dup)
628
629 def test_self_intersection(self):
630 result = self.set & self.set
631 self.assertEqual(result, self.dup)
632
633 def test_empty_intersection(self):
634 result = self.set & empty_set
635 self.assertEqual(result, empty_set)
636
637 def test_intersection_empty(self):
638 result = empty_set & self.set
639 self.assertEqual(result, empty_set)
640
641 def test_self_symmetric_difference(self):
642 result = self.set ^ self.set
643 self.assertEqual(result, empty_set)
644
645 def checkempty_symmetric_difference(self):
646 result = self.set ^ empty_set
647 self.assertEqual(result, self.set)
648
649 def test_self_difference(self):
650 result = self.set - self.set
651 self.assertEqual(result, empty_set)
652
653 def test_empty_difference(self):
654 result = self.set - empty_set
655 self.assertEqual(result, self.dup)
656
657 def test_empty_difference_rev(self):
658 result = empty_set - self.set
659 self.assertEqual(result, empty_set)
660
661 def test_iteration(self):
662 for v in self.set:
663 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000664 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000665 # note: __length_hint__ is an internal undocumented API,
666 # don't rely on it in your own programs
667 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000668
669 def test_pickling(self):
670 p = pickle.dumps(self.set)
671 copy = pickle.loads(p)
672 self.assertEqual(self.set, copy,
673 "%s != %s" % (self.set, copy))
674
675#------------------------------------------------------------------------------
676
677class TestBasicOpsEmpty(TestBasicOps):
678 def setUp(self):
679 self.case = "empty set"
680 self.values = []
681 self.set = set(self.values)
682 self.dup = set(self.values)
683 self.length = 0
Georg Brandlc4996ba2006-08-28 19:37:11 +0000684 self.repr = "set()"
Raymond Hettingera690a992003-11-16 16:17:49 +0000685
686#------------------------------------------------------------------------------
687
688class TestBasicOpsSingleton(TestBasicOps):
689 def setUp(self):
690 self.case = "unit set (number)"
691 self.values = [3]
692 self.set = set(self.values)
693 self.dup = set(self.values)
694 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000695 self.repr = "{3}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000696
697 def test_in(self):
698 self.failUnless(3 in self.set)
699
700 def test_not_in(self):
701 self.failUnless(2 not in self.set)
702
703#------------------------------------------------------------------------------
704
705class TestBasicOpsTuple(TestBasicOps):
706 def setUp(self):
707 self.case = "unit set (tuple)"
708 self.values = [(0, "zero")]
709 self.set = set(self.values)
710 self.dup = set(self.values)
711 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000712 self.repr = "{(0, 'zero')}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000713
714 def test_in(self):
715 self.failUnless((0, "zero") in self.set)
716
717 def test_not_in(self):
718 self.failUnless(9 not in self.set)
719
720#------------------------------------------------------------------------------
721
722class TestBasicOpsTriple(TestBasicOps):
723 def setUp(self):
724 self.case = "triple set"
725 self.values = [0, "zero", operator.add]
726 self.set = set(self.values)
727 self.dup = set(self.values)
728 self.length = 3
729 self.repr = None
730
731#==============================================================================
732
733def baditer():
734 raise TypeError
735 yield True
736
737def gooditer():
738 yield True
739
740class TestExceptionPropagation(unittest.TestCase):
741 """SF 628246: Set constructor should not trap iterator TypeErrors"""
742
743 def test_instanceWithException(self):
744 self.assertRaises(TypeError, set, baditer())
745
746 def test_instancesWithoutException(self):
747 # All of these iterables should load without exception.
748 set([1,2,3])
749 set((1,2,3))
750 set({'one':1, 'two':2, 'three':3})
751 set(xrange(3))
752 set('abc')
753 set(gooditer())
754
Neal Norwitzfcf44352005-11-27 20:37:43 +0000755 def test_changingSizeWhileIterating(self):
756 s = set([1,2,3])
757 try:
758 for i in s:
759 s.update([4])
760 except RuntimeError:
761 pass
762 else:
763 self.fail("no exception when changing size during iteration")
764
Raymond Hettingera690a992003-11-16 16:17:49 +0000765#==============================================================================
766
767class TestSetOfSets(unittest.TestCase):
768 def test_constructor(self):
769 inner = frozenset([1])
770 outer = set([inner])
771 element = outer.pop()
772 self.assertEqual(type(element), frozenset)
773 outer.add(inner) # Rebuild set of sets with .add method
774 outer.remove(inner)
775 self.assertEqual(outer, set()) # Verify that remove worked
776 outer.discard(inner) # Absence of KeyError indicates working fine
777
778#==============================================================================
779
780class TestBinaryOps(unittest.TestCase):
781 def setUp(self):
782 self.set = set((2, 4, 6))
783
784 def test_eq(self): # SF bug 643115
785 self.assertEqual(self.set, set({2:1,4:3,6:5}))
786
787 def test_union_subset(self):
788 result = self.set | set([2])
789 self.assertEqual(result, set((2, 4, 6)))
790
791 def test_union_superset(self):
792 result = self.set | set([2, 4, 6, 8])
793 self.assertEqual(result, set([2, 4, 6, 8]))
794
795 def test_union_overlap(self):
796 result = self.set | set([3, 4, 5])
797 self.assertEqual(result, set([2, 3, 4, 5, 6]))
798
799 def test_union_non_overlap(self):
800 result = self.set | set([8])
801 self.assertEqual(result, set([2, 4, 6, 8]))
802
803 def test_intersection_subset(self):
804 result = self.set & set((2, 4))
805 self.assertEqual(result, set((2, 4)))
806
807 def test_intersection_superset(self):
808 result = self.set & set([2, 4, 6, 8])
809 self.assertEqual(result, set([2, 4, 6]))
810
811 def test_intersection_overlap(self):
812 result = self.set & set([3, 4, 5])
813 self.assertEqual(result, set([4]))
814
815 def test_intersection_non_overlap(self):
816 result = self.set & set([8])
817 self.assertEqual(result, empty_set)
818
819 def test_sym_difference_subset(self):
820 result = self.set ^ set((2, 4))
821 self.assertEqual(result, set([6]))
822
823 def test_sym_difference_superset(self):
824 result = self.set ^ set((2, 4, 6, 8))
825 self.assertEqual(result, set([8]))
826
827 def test_sym_difference_overlap(self):
828 result = self.set ^ set((3, 4, 5))
829 self.assertEqual(result, set([2, 3, 5, 6]))
830
831 def test_sym_difference_non_overlap(self):
832 result = self.set ^ set([8])
833 self.assertEqual(result, set([2, 4, 6, 8]))
834
835 def test_cmp(self):
836 a, b = set('a'), set('b')
837 self.assertRaises(TypeError, cmp, a, b)
838
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000839 # In py3k, this works!
840 self.assertRaises(TypeError, cmp, a, a)
Raymond Hettingera690a992003-11-16 16:17:49 +0000841
842 self.assertRaises(TypeError, cmp, a, 12)
843 self.assertRaises(TypeError, cmp, "abc", a)
844
845#==============================================================================
846
847class TestUpdateOps(unittest.TestCase):
848 def setUp(self):
849 self.set = set((2, 4, 6))
850
851 def test_union_subset(self):
852 self.set |= set([2])
853 self.assertEqual(self.set, set((2, 4, 6)))
854
855 def test_union_superset(self):
856 self.set |= set([2, 4, 6, 8])
857 self.assertEqual(self.set, set([2, 4, 6, 8]))
858
859 def test_union_overlap(self):
860 self.set |= set([3, 4, 5])
861 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
862
863 def test_union_non_overlap(self):
864 self.set |= set([8])
865 self.assertEqual(self.set, set([2, 4, 6, 8]))
866
867 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000868 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +0000869 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
870
871 def test_intersection_subset(self):
872 self.set &= set((2, 4))
873 self.assertEqual(self.set, set((2, 4)))
874
875 def test_intersection_superset(self):
876 self.set &= set([2, 4, 6, 8])
877 self.assertEqual(self.set, set([2, 4, 6]))
878
879 def test_intersection_overlap(self):
880 self.set &= set([3, 4, 5])
881 self.assertEqual(self.set, set([4]))
882
883 def test_intersection_non_overlap(self):
884 self.set &= set([8])
885 self.assertEqual(self.set, empty_set)
886
887 def test_intersection_method_call(self):
888 self.set.intersection_update(set([3, 4, 5]))
889 self.assertEqual(self.set, set([4]))
890
891 def test_sym_difference_subset(self):
892 self.set ^= set((2, 4))
893 self.assertEqual(self.set, set([6]))
894
895 def test_sym_difference_superset(self):
896 self.set ^= set((2, 4, 6, 8))
897 self.assertEqual(self.set, set([8]))
898
899 def test_sym_difference_overlap(self):
900 self.set ^= set((3, 4, 5))
901 self.assertEqual(self.set, set([2, 3, 5, 6]))
902
903 def test_sym_difference_non_overlap(self):
904 self.set ^= set([8])
905 self.assertEqual(self.set, set([2, 4, 6, 8]))
906
907 def test_sym_difference_method_call(self):
908 self.set.symmetric_difference_update(set([3, 4, 5]))
909 self.assertEqual(self.set, set([2, 3, 5, 6]))
910
911 def test_difference_subset(self):
912 self.set -= set((2, 4))
913 self.assertEqual(self.set, set([6]))
914
915 def test_difference_superset(self):
916 self.set -= set((2, 4, 6, 8))
917 self.assertEqual(self.set, set([]))
918
919 def test_difference_overlap(self):
920 self.set -= set((3, 4, 5))
921 self.assertEqual(self.set, set([2, 6]))
922
923 def test_difference_non_overlap(self):
924 self.set -= set([8])
925 self.assertEqual(self.set, set([2, 4, 6]))
926
927 def test_difference_method_call(self):
928 self.set.difference_update(set([3, 4, 5]))
929 self.assertEqual(self.set, set([2, 6]))
930
931#==============================================================================
932
933class TestMutate(unittest.TestCase):
934 def setUp(self):
935 self.values = ["a", "b", "c"]
936 self.set = set(self.values)
937
938 def test_add_present(self):
939 self.set.add("c")
940 self.assertEqual(self.set, set("abc"))
941
942 def test_add_absent(self):
943 self.set.add("d")
944 self.assertEqual(self.set, set("abcd"))
945
946 def test_add_until_full(self):
947 tmp = set()
948 expected_len = 0
949 for v in self.values:
950 tmp.add(v)
951 expected_len += 1
952 self.assertEqual(len(tmp), expected_len)
953 self.assertEqual(tmp, self.set)
954
955 def test_remove_present(self):
956 self.set.remove("b")
957 self.assertEqual(self.set, set("ac"))
958
959 def test_remove_absent(self):
960 try:
961 self.set.remove("d")
962 self.fail("Removing missing element should have raised LookupError")
963 except LookupError:
964 pass
965
966 def test_remove_until_empty(self):
967 expected_len = len(self.set)
968 for v in self.values:
969 self.set.remove(v)
970 expected_len -= 1
971 self.assertEqual(len(self.set), expected_len)
972
973 def test_discard_present(self):
974 self.set.discard("c")
975 self.assertEqual(self.set, set("ab"))
976
977 def test_discard_absent(self):
978 self.set.discard("d")
979 self.assertEqual(self.set, set("abc"))
980
981 def test_clear(self):
982 self.set.clear()
983 self.assertEqual(len(self.set), 0)
984
985 def test_pop(self):
986 popped = {}
987 while self.set:
988 popped[self.set.pop()] = None
989 self.assertEqual(len(popped), len(self.values))
990 for v in self.values:
991 self.failUnless(v in popped)
992
993 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000994 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +0000995 self.assertEqual(self.set, set(self.values))
996
997 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000998 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +0000999 self.assertEqual(self.set, set(self.values))
1000
1001 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001002 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001003 self.assertEqual(self.set, set(self.values + ["z"]))
1004
1005#==============================================================================
1006
1007class TestSubsets(unittest.TestCase):
1008
1009 case2method = {"<=": "issubset",
1010 ">=": "issuperset",
1011 }
1012
1013 reverse = {"==": "==",
1014 "!=": "!=",
1015 "<": ">",
1016 ">": "<",
1017 "<=": ">=",
1018 ">=": "<=",
1019 }
1020
1021 def test_issubset(self):
1022 x = self.left
1023 y = self.right
1024 for case in "!=", "==", "<", "<=", ">", ">=":
1025 expected = case in self.cases
1026 # Test the binary infix spelling.
1027 result = eval("x" + case + "y", locals())
1028 self.assertEqual(result, expected)
1029 # Test the "friendly" method-name spelling, if one exists.
1030 if case in TestSubsets.case2method:
1031 method = getattr(x, TestSubsets.case2method[case])
1032 result = method(y)
1033 self.assertEqual(result, expected)
1034
1035 # Now do the same for the operands reversed.
1036 rcase = TestSubsets.reverse[case]
1037 result = eval("y" + rcase + "x", locals())
1038 self.assertEqual(result, expected)
1039 if rcase in TestSubsets.case2method:
1040 method = getattr(y, TestSubsets.case2method[rcase])
1041 result = method(x)
1042 self.assertEqual(result, expected)
1043#------------------------------------------------------------------------------
1044
1045class TestSubsetEqualEmpty(TestSubsets):
1046 left = set()
1047 right = set()
1048 name = "both empty"
1049 cases = "==", "<=", ">="
1050
1051#------------------------------------------------------------------------------
1052
1053class TestSubsetEqualNonEmpty(TestSubsets):
1054 left = set([1, 2])
1055 right = set([1, 2])
1056 name = "equal pair"
1057 cases = "==", "<=", ">="
1058
1059#------------------------------------------------------------------------------
1060
1061class TestSubsetEmptyNonEmpty(TestSubsets):
1062 left = set()
1063 right = set([1, 2])
1064 name = "one empty, one non-empty"
1065 cases = "!=", "<", "<="
1066
1067#------------------------------------------------------------------------------
1068
1069class TestSubsetPartial(TestSubsets):
1070 left = set([1])
1071 right = set([1, 2])
1072 name = "one a non-empty proper subset of other"
1073 cases = "!=", "<", "<="
1074
1075#------------------------------------------------------------------------------
1076
1077class TestSubsetNonOverlap(TestSubsets):
1078 left = set([1])
1079 right = set([2])
1080 name = "neither empty, neither contains"
1081 cases = "!="
1082
1083#==============================================================================
1084
1085class TestOnlySetsInBinaryOps(unittest.TestCase):
1086
1087 def test_eq_ne(self):
1088 # Unlike the others, this is testing that == and != *are* allowed.
1089 self.assertEqual(self.other == self.set, False)
1090 self.assertEqual(self.set == self.other, False)
1091 self.assertEqual(self.other != self.set, True)
1092 self.assertEqual(self.set != self.other, True)
1093
1094 def test_ge_gt_le_lt(self):
1095 self.assertRaises(TypeError, lambda: self.set < self.other)
1096 self.assertRaises(TypeError, lambda: self.set <= self.other)
1097 self.assertRaises(TypeError, lambda: self.set > self.other)
1098 self.assertRaises(TypeError, lambda: self.set >= self.other)
1099
1100 self.assertRaises(TypeError, lambda: self.other < self.set)
1101 self.assertRaises(TypeError, lambda: self.other <= self.set)
1102 self.assertRaises(TypeError, lambda: self.other > self.set)
1103 self.assertRaises(TypeError, lambda: self.other >= self.set)
1104
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001105 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001106 try:
1107 self.set |= self.other
1108 except TypeError:
1109 pass
1110 else:
1111 self.fail("expected TypeError")
1112
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001113 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001114 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001115 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001116 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001117 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001118
1119 def test_union(self):
1120 self.assertRaises(TypeError, lambda: self.set | self.other)
1121 self.assertRaises(TypeError, lambda: self.other | self.set)
1122 if self.otherIsIterable:
1123 self.set.union(self.other)
1124 else:
1125 self.assertRaises(TypeError, self.set.union, self.other)
1126
1127 def test_intersection_update_operator(self):
1128 try:
1129 self.set &= self.other
1130 except TypeError:
1131 pass
1132 else:
1133 self.fail("expected TypeError")
1134
1135 def test_intersection_update(self):
1136 if self.otherIsIterable:
1137 self.set.intersection_update(self.other)
1138 else:
1139 self.assertRaises(TypeError,
1140 self.set.intersection_update,
1141 self.other)
1142
1143 def test_intersection(self):
1144 self.assertRaises(TypeError, lambda: self.set & self.other)
1145 self.assertRaises(TypeError, lambda: self.other & self.set)
1146 if self.otherIsIterable:
1147 self.set.intersection(self.other)
1148 else:
1149 self.assertRaises(TypeError, self.set.intersection, self.other)
1150
1151 def test_sym_difference_update_operator(self):
1152 try:
1153 self.set ^= self.other
1154 except TypeError:
1155 pass
1156 else:
1157 self.fail("expected TypeError")
1158
1159 def test_sym_difference_update(self):
1160 if self.otherIsIterable:
1161 self.set.symmetric_difference_update(self.other)
1162 else:
1163 self.assertRaises(TypeError,
1164 self.set.symmetric_difference_update,
1165 self.other)
1166
1167 def test_sym_difference(self):
1168 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1169 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1170 if self.otherIsIterable:
1171 self.set.symmetric_difference(self.other)
1172 else:
1173 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1174
1175 def test_difference_update_operator(self):
1176 try:
1177 self.set -= self.other
1178 except TypeError:
1179 pass
1180 else:
1181 self.fail("expected TypeError")
1182
1183 def test_difference_update(self):
1184 if self.otherIsIterable:
1185 self.set.difference_update(self.other)
1186 else:
1187 self.assertRaises(TypeError,
1188 self.set.difference_update,
1189 self.other)
1190
1191 def test_difference(self):
1192 self.assertRaises(TypeError, lambda: self.set - self.other)
1193 self.assertRaises(TypeError, lambda: self.other - self.set)
1194 if self.otherIsIterable:
1195 self.set.difference(self.other)
1196 else:
1197 self.assertRaises(TypeError, self.set.difference, self.other)
1198
1199#------------------------------------------------------------------------------
1200
1201class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1202 def setUp(self):
1203 self.set = set((1, 2, 3))
1204 self.other = 19
1205 self.otherIsIterable = False
1206
1207#------------------------------------------------------------------------------
1208
1209class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1210 def setUp(self):
1211 self.set = set((1, 2, 3))
1212 self.other = {1:2, 3:4}
1213 self.otherIsIterable = True
1214
1215#------------------------------------------------------------------------------
1216
1217class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1218 def setUp(self):
1219 self.set = set((1, 2, 3))
1220 self.other = operator.add
1221 self.otherIsIterable = False
1222
1223#------------------------------------------------------------------------------
1224
1225class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1226 def setUp(self):
1227 self.set = set((1, 2, 3))
1228 self.other = (2, 4, 6)
1229 self.otherIsIterable = True
1230
1231#------------------------------------------------------------------------------
1232
1233class TestOnlySetsString(TestOnlySetsInBinaryOps):
1234 def setUp(self):
1235 self.set = set((1, 2, 3))
1236 self.other = 'abc'
1237 self.otherIsIterable = True
1238
1239#------------------------------------------------------------------------------
1240
1241class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1242 def setUp(self):
1243 def gen():
1244 for i in xrange(0, 10, 2):
1245 yield i
1246 self.set = set((1, 2, 3))
1247 self.other = gen()
1248 self.otherIsIterable = True
1249
1250#==============================================================================
1251
1252class TestCopying(unittest.TestCase):
1253
1254 def test_copy(self):
1255 dup = self.set.copy()
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001256 dup_list = sorted(dup, key=repr)
1257 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001258 self.assertEqual(len(dup_list), len(set_list))
1259 for i in range(len(dup_list)):
1260 self.failUnless(dup_list[i] is set_list[i])
1261
1262 def test_deep_copy(self):
1263 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001264 ##print type(dup), repr(dup)
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001265 dup_list = sorted(dup, key=repr)
1266 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001267 self.assertEqual(len(dup_list), len(set_list))
1268 for i in range(len(dup_list)):
1269 self.assertEqual(dup_list[i], set_list[i])
1270
1271#------------------------------------------------------------------------------
1272
1273class TestCopyingEmpty(TestCopying):
1274 def setUp(self):
1275 self.set = set()
1276
1277#------------------------------------------------------------------------------
1278
1279class TestCopyingSingleton(TestCopying):
1280 def setUp(self):
1281 self.set = set(["hello"])
1282
1283#------------------------------------------------------------------------------
1284
1285class TestCopyingTriple(TestCopying):
1286 def setUp(self):
1287 self.set = set(["zero", 0, None])
1288
1289#------------------------------------------------------------------------------
1290
1291class TestCopyingTuple(TestCopying):
1292 def setUp(self):
1293 self.set = set([(1, 2)])
1294
1295#------------------------------------------------------------------------------
1296
1297class TestCopyingNested(TestCopying):
1298 def setUp(self):
1299 self.set = set([((1, 2), (3, 4))])
1300
1301#==============================================================================
1302
1303class TestIdentities(unittest.TestCase):
1304 def setUp(self):
1305 self.a = set('abracadabra')
1306 self.b = set('alacazam')
1307
1308 def test_binopsVsSubsets(self):
1309 a, b = self.a, self.b
1310 self.assert_(a - b < a)
1311 self.assert_(b - a < b)
1312 self.assert_(a & b < a)
1313 self.assert_(a & b < b)
1314 self.assert_(a | b > a)
1315 self.assert_(a | b > b)
1316 self.assert_(a ^ b < a | b)
1317
1318 def test_commutativity(self):
1319 a, b = self.a, self.b
1320 self.assertEqual(a&b, b&a)
1321 self.assertEqual(a|b, b|a)
1322 self.assertEqual(a^b, b^a)
1323 if a != b:
1324 self.assertNotEqual(a-b, b-a)
1325
1326 def test_summations(self):
1327 # check that sums of parts equal the whole
1328 a, b = self.a, self.b
1329 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1330 self.assertEqual((a&b)|(a^b), a|b)
1331 self.assertEqual(a|(b-a), a|b)
1332 self.assertEqual((a-b)|b, a|b)
1333 self.assertEqual((a-b)|(a&b), a)
1334 self.assertEqual((b-a)|(a&b), b)
1335 self.assertEqual((a-b)|(b-a), a^b)
1336
1337 def test_exclusion(self):
1338 # check that inverse operations show non-overlap
1339 a, b, zero = self.a, self.b, set()
1340 self.assertEqual((a-b)&b, zero)
1341 self.assertEqual((b-a)&a, zero)
1342 self.assertEqual((a&b)&(a^b), zero)
1343
1344# Tests derived from test_itertools.py =======================================
1345
1346def R(seqn):
1347 'Regular generator'
1348 for i in seqn:
1349 yield i
1350
1351class G:
1352 'Sequence using __getitem__'
1353 def __init__(self, seqn):
1354 self.seqn = seqn
1355 def __getitem__(self, i):
1356 return self.seqn[i]
1357
1358class I:
1359 'Sequence using iterator protocol'
1360 def __init__(self, seqn):
1361 self.seqn = seqn
1362 self.i = 0
1363 def __iter__(self):
1364 return self
1365 def next(self):
1366 if self.i >= len(self.seqn): raise StopIteration
1367 v = self.seqn[self.i]
1368 self.i += 1
1369 return v
1370
1371class Ig:
1372 'Sequence using iterator protocol defined with a generator'
1373 def __init__(self, seqn):
1374 self.seqn = seqn
1375 self.i = 0
1376 def __iter__(self):
1377 for val in self.seqn:
1378 yield val
1379
1380class X:
1381 'Missing __getitem__ and __iter__'
1382 def __init__(self, seqn):
1383 self.seqn = seqn
1384 self.i = 0
1385 def next(self):
1386 if self.i >= len(self.seqn): raise StopIteration
1387 v = self.seqn[self.i]
1388 self.i += 1
1389 return v
1390
1391class N:
1392 'Iterator missing next()'
1393 def __init__(self, seqn):
1394 self.seqn = seqn
1395 self.i = 0
1396 def __iter__(self):
1397 return self
1398
1399class E:
1400 'Test propagation of exceptions'
1401 def __init__(self, seqn):
1402 self.seqn = seqn
1403 self.i = 0
1404 def __iter__(self):
1405 return self
1406 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001407 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001408
1409class S:
1410 'Test immediate stop'
1411 def __init__(self, seqn):
1412 pass
1413 def __iter__(self):
1414 return self
1415 def next(self):
1416 raise StopIteration
1417
1418from itertools import chain, imap
1419def L(seqn):
1420 'Test multiple tiers of iterators'
1421 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1422
1423class TestVariousIteratorArgs(unittest.TestCase):
1424
1425 def test_constructor(self):
1426 for cons in (set, frozenset):
1427 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1428 for g in (G, I, Ig, S, L, R):
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001429 self.assertEqual(sorted(cons(g(s)), key=repr), sorted(g(s), key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001430 self.assertRaises(TypeError, cons , X(s))
1431 self.assertRaises(TypeError, cons , N(s))
1432 self.assertRaises(ZeroDivisionError, cons , E(s))
1433
1434 def test_inline_methods(self):
1435 s = set('november')
1436 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
1437 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference):
1438 for g in (G, I, Ig, L, R):
1439 expected = meth(data)
1440 actual = meth(G(data))
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001441 self.assertEqual(sorted(actual, key=repr), sorted(expected, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001442 self.assertRaises(TypeError, meth, X(s))
1443 self.assertRaises(TypeError, meth, N(s))
1444 self.assertRaises(ZeroDivisionError, meth, E(s))
1445
1446 def test_inplace_methods(self):
1447 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001448 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001449 'difference_update', 'symmetric_difference_update'):
1450 for g in (G, I, Ig, S, L, R):
1451 s = set('january')
1452 t = s.copy()
1453 getattr(s, methname)(list(g(data)))
1454 getattr(t, methname)(g(data))
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001455 self.assertEqual(sorted(s, key=repr), sorted(t, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001456
1457 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1458 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1459 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1460
1461#==============================================================================
1462
1463def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001464 test_classes = (
1465 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001466 TestSetSubclass,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001467 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001468 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001469 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001470 TestSetOfSets,
1471 TestExceptionPropagation,
1472 TestBasicOpsEmpty,
1473 TestBasicOpsSingleton,
1474 TestBasicOpsTuple,
1475 TestBasicOpsTriple,
1476 TestBinaryOps,
1477 TestUpdateOps,
1478 TestMutate,
1479 TestSubsetEqualEmpty,
1480 TestSubsetEqualNonEmpty,
1481 TestSubsetEmptyNonEmpty,
1482 TestSubsetPartial,
1483 TestSubsetNonOverlap,
1484 TestOnlySetsNumeric,
1485 TestOnlySetsDict,
1486 TestOnlySetsOperator,
1487 TestOnlySetsTuple,
1488 TestOnlySetsString,
1489 TestOnlySetsGenerator,
1490 TestCopyingEmpty,
1491 TestCopyingSingleton,
1492 TestCopyingTriple,
1493 TestCopyingTuple,
1494 TestCopyingNested,
1495 TestIdentities,
1496 TestVariousIteratorArgs,
1497 )
1498
1499 test_support.run_unittest(*test_classes)
1500
1501 # verify reference counting
1502 if verbose and hasattr(sys, "gettotalrefcount"):
1503 import gc
1504 counts = [None] * 5
1505 for i in xrange(len(counts)):
1506 test_support.run_unittest(*test_classes)
1507 gc.collect()
1508 counts[i] = sys.gettotalrefcount()
1509 print counts
1510
1511if __name__ == "__main__":
1512 test_main(verbose=True)