blob: 872a467a55b03f99c562b59fd6c1f1924d6830a3 [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
21 def __cmp__(self, other):
22 raise RuntimeError
23
Raymond Hettinger53999102006-12-30 04:01:17 +000024class ReprWrapper:
25 'Used to test self-referential repr() calls'
26 def __repr__(self):
27 return repr(self.value)
28
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +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, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000075 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
76 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())
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000099 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
100 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, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000124 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
125 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, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000149 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
150 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
230 s = set(A() for i in xrange(1000))
231 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):
Tim Peters6902b442006-04-11 00:43:27 +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
Raymond Hettinger53999102006-12-30 04:01:17 +0000260 def test_cyclical_repr(self):
261 w = ReprWrapper()
262 s = self.thetype([w])
263 w.value = s
264 name = repr(s).partition('(')[0] # strip class name from repr string
265 self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
266
267 def test_cyclical_print(self):
268 w = ReprWrapper()
269 s = self.thetype([w])
270 w.value = s
271 try:
272 fo = open(test_support.TESTFN, "wb")
273 print >> fo, s,
274 fo.close()
275 fo = open(test_support.TESTFN, "rb")
276 self.assertEqual(fo.read(), repr(s))
277 finally:
278 fo.close()
279 os.remove(test_support.TESTFN)
280
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000281 def test_do_not_rehash_dict_keys(self):
282 n = 10
283 d = dict.fromkeys(map(HashCountingInt, xrange(n)))
284 self.assertEqual(sum(elem.hash_count for elem in d), n)
285 s = self.thetype(d)
286 self.assertEqual(sum(elem.hash_count for elem in d), n)
287 s.difference(d)
Tim Petersea5962f2007-03-12 18:07:52 +0000288 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000289 if hasattr(s, 'symmetric_difference_update'):
290 s.symmetric_difference_update(d)
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000291 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettinger0bbbfc42007-03-20 21:27:24 +0000292 d2 = dict.fromkeys(set(d))
293 self.assertEqual(sum(elem.hash_count for elem in d), n)
294 d3 = dict.fromkeys(frozenset(d))
Tim Petersea5962f2007-03-12 18:07:52 +0000295 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingere3146f52007-03-21 20:33:57 +0000296 d3 = dict.fromkeys(frozenset(d), 123)
297 self.assertEqual(sum(elem.hash_count for elem in d), n)
298 self.assertEqual(d3, dict.fromkeys(d, 123))
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000299
Raymond Hettingera690a992003-11-16 16:17:49 +0000300class TestSet(TestJointOps):
301 thetype = set
302
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000303 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000304 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000305 s.__init__(self.word)
306 self.assertEqual(s, set(self.word))
307 s.__init__(self.otherword)
308 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000309 self.assertRaises(TypeError, s.__init__, s, 2);
310 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000311
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000312 def test_constructor_identity(self):
313 s = self.thetype(range(3))
314 t = self.thetype(s)
315 self.assertNotEqual(id(s), id(t))
316
Raymond Hettingera690a992003-11-16 16:17:49 +0000317 def test_hash(self):
318 self.assertRaises(TypeError, hash, self.s)
319
320 def test_clear(self):
321 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000322 self.assertEqual(self.s, set())
323 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000324
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000325 def test_copy(self):
326 dup = self.s.copy()
327 self.assertEqual(self.s, dup)
328 self.assertNotEqual(id(self.s), id(dup))
329
Raymond Hettingera690a992003-11-16 16:17:49 +0000330 def test_add(self):
331 self.s.add('Q')
332 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000333 dup = self.s.copy()
334 self.s.add('Q')
335 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000336 self.assertRaises(TypeError, self.s.add, [])
337
338 def test_remove(self):
339 self.s.remove('a')
340 self.assert_('a' not in self.s)
341 self.assertRaises(KeyError, self.s.remove, 'Q')
342 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000343 s = self.thetype([frozenset(self.word)])
344 self.assert_(self.thetype(self.word) in s)
345 s.remove(self.thetype(self.word))
346 self.assert_(self.thetype(self.word) not in s)
347 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000348
Raymond Hettingerc789f342006-12-08 17:35:25 +0000349 def test_remove_keyerror_unpacking(self):
350 # bug: www.python.org/sf/1576657
351 for v1 in ['Q', (1,)]:
352 try:
353 self.s.remove(v1)
354 except KeyError, e:
355 v2 = e.args[0]
356 self.assertEqual(v1, v2)
357 else:
358 self.fail()
359
Raymond Hettingera690a992003-11-16 16:17:49 +0000360 def test_discard(self):
361 self.s.discard('a')
362 self.assert_('a' not in self.s)
363 self.s.discard('Q')
364 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000365 s = self.thetype([frozenset(self.word)])
366 self.assert_(self.thetype(self.word) in s)
367 s.discard(self.thetype(self.word))
368 self.assert_(self.thetype(self.word) not in s)
369 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000370
371 def test_pop(self):
372 for i in xrange(len(self.s)):
373 elem = self.s.pop()
374 self.assert_(elem not in self.s)
375 self.assertRaises(KeyError, self.s.pop)
376
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000377 def test_update(self):
378 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000379 self.assertEqual(retval, None)
380 for c in (self.word + self.otherword):
381 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000382 self.assertRaises(PassThru, self.s.update, check_pass_thru())
383 self.assertRaises(TypeError, self.s.update, [[]])
384 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
385 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
386 s = self.thetype('abcba')
387 self.assertEqual(s.update(C(p)), None)
388 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000389
390 def test_ior(self):
391 self.s |= set(self.otherword)
392 for c in (self.word + self.otherword):
393 self.assert_(c in self.s)
394
395 def test_intersection_update(self):
396 retval = self.s.intersection_update(self.otherword)
397 self.assertEqual(retval, None)
398 for c in (self.word + self.otherword):
399 if c in self.otherword and c in self.word:
400 self.assert_(c in self.s)
401 else:
402 self.assert_(c not in self.s)
403 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
404 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000405 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
406 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
407 s = self.thetype('abcba')
408 self.assertEqual(s.intersection_update(C(p)), None)
409 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000410
411 def test_iand(self):
412 self.s &= set(self.otherword)
413 for c in (self.word + self.otherword):
414 if c in self.otherword and c in self.word:
415 self.assert_(c in self.s)
416 else:
417 self.assert_(c not in self.s)
418
419 def test_difference_update(self):
420 retval = self.s.difference_update(self.otherword)
421 self.assertEqual(retval, None)
422 for c in (self.word + self.otherword):
423 if c in self.word and c not in self.otherword:
424 self.assert_(c in self.s)
425 else:
426 self.assert_(c not in self.s)
427 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
428 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000429 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
430 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
431 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
432 s = self.thetype('abcba')
433 self.assertEqual(s.difference_update(C(p)), None)
434 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000435
436 def test_isub(self):
437 self.s -= set(self.otherword)
438 for c in (self.word + self.otherword):
439 if c in self.word and c not in self.otherword:
440 self.assert_(c in self.s)
441 else:
442 self.assert_(c not in self.s)
443
444 def test_symmetric_difference_update(self):
445 retval = self.s.symmetric_difference_update(self.otherword)
446 self.assertEqual(retval, None)
447 for c in (self.word + self.otherword):
448 if (c in self.word) ^ (c in self.otherword):
449 self.assert_(c in self.s)
450 else:
451 self.assert_(c not in self.s)
452 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
453 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000454 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
455 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
456 s = self.thetype('abcba')
457 self.assertEqual(s.symmetric_difference_update(C(p)), None)
458 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000459
460 def test_ixor(self):
461 self.s ^= set(self.otherword)
462 for c in (self.word + self.otherword):
463 if (c in self.word) ^ (c in self.otherword):
464 self.assert_(c in self.s)
465 else:
466 self.assert_(c not in self.s)
467
Raymond Hettingerc991db22005-08-11 07:58:45 +0000468 def test_inplace_on_self(self):
469 t = self.s.copy()
470 t |= t
471 self.assertEqual(t, self.s)
472 t &= t
473 self.assertEqual(t, self.s)
474 t -= t
475 self.assertEqual(t, self.thetype())
476 t = self.s.copy()
477 t ^= t
478 self.assertEqual(t, self.thetype())
479
Raymond Hettinger691d8052004-05-30 07:26:47 +0000480 def test_weakref(self):
481 s = self.thetype('gallahad')
482 p = proxy(s)
483 self.assertEqual(str(p), str(s))
484 s = None
485 self.assertRaises(ReferenceError, str, p)
486
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000487 # C API test only available in a debug build
Barry Warsaw176014f2006-03-30 22:45:35 +0000488 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000489 def test_c_api(self):
490 self.assertEqual(set('abc').test_c_api(), True)
491
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000492class SetSubclass(set):
493 pass
494
495class TestSetSubclass(TestSet):
496 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000497
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000498class SetSubclassWithKeywordArgs(set):
499 def __init__(self, iterable=[], newarg=None):
500 set.__init__(self, iterable)
501
502class TestSetSubclassWithKeywordArgs(TestSet):
Tim Petersf733abb2007-01-30 03:03:46 +0000503
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000504 def test_keywords_in_subclass(self):
505 'SF bug #1486663 -- this used to erroneously raise a TypeError'
506 SetSubclassWithKeywordArgs(newarg=1)
507
Raymond Hettingera690a992003-11-16 16:17:49 +0000508class TestFrozenSet(TestJointOps):
509 thetype = frozenset
510
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000511 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000512 s = self.thetype(self.word)
513 s.__init__(self.otherword)
514 self.assertEqual(s, set(self.word))
515
Raymond Hettingerd7946662005-08-01 21:39:29 +0000516 def test_singleton_empty_frozenset(self):
517 f = frozenset()
518 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
519 frozenset(), frozenset([]), frozenset(()), frozenset(''),
520 frozenset(xrange(0)), frozenset(frozenset()),
521 frozenset(f), f]
522 # All of the empty frozensets should have just one id()
523 self.assertEqual(len(set(map(id, efs))), 1)
524
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000525 def test_constructor_identity(self):
526 s = self.thetype(range(3))
527 t = self.thetype(s)
528 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000529
Raymond Hettingera690a992003-11-16 16:17:49 +0000530 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000531 self.assertEqual(hash(self.thetype('abcdeb')),
532 hash(self.thetype('ebecda')))
533
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000534 # make sure that all permutations give the same hash value
535 n = 100
536 seq = [randrange(n) for i in xrange(n)]
537 results = set()
538 for i in xrange(200):
539 shuffle(seq)
540 results.add(hash(self.thetype(seq)))
541 self.assertEqual(len(results), 1)
542
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000543 def test_copy(self):
544 dup = self.s.copy()
545 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000546
547 def test_frozen_as_dictkey(self):
548 seq = range(10) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000549 key1 = self.thetype(seq)
550 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000551 self.assertEqual(key1, key2)
552 self.assertNotEqual(id(key1), id(key2))
553 d = {}
554 d[key1] = 42
555 self.assertEqual(d[key2], 42)
556
557 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000558 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000559 self.assertEqual(hash(f), hash(f))
560
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000561 def test_hash_effectiveness(self):
562 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000563 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000564 addhashvalue = hashvalues.add
565 elemmasks = [(i+1, 1<<i) for i in range(n)]
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000566 for i in xrange(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000567 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
568 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000569
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000570class FrozenSetSubclass(frozenset):
571 pass
572
573class TestFrozenSetSubclass(TestFrozenSet):
574 thetype = FrozenSetSubclass
575
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000576 def test_constructor_identity(self):
577 s = self.thetype(range(3))
578 t = self.thetype(s)
579 self.assertNotEqual(id(s), id(t))
580
581 def test_copy(self):
582 dup = self.s.copy()
583 self.assertNotEqual(id(self.s), id(dup))
584
585 def test_nested_empty_constructor(self):
586 s = self.thetype()
587 t = self.thetype(s)
588 self.assertEqual(s, t)
589
Raymond Hettingerd7946662005-08-01 21:39:29 +0000590 def test_singleton_empty_frozenset(self):
591 Frozenset = self.thetype
592 f = frozenset()
593 F = Frozenset()
594 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
595 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
596 Frozenset(xrange(0)), Frozenset(Frozenset()),
597 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
598 # All empty frozenset subclass instances should have different ids
599 self.assertEqual(len(set(map(id, efs))), len(efs))
600
Raymond Hettingera690a992003-11-16 16:17:49 +0000601# Tests taken from test_sets.py =============================================
602
603empty_set = set()
604
605#==============================================================================
606
607class TestBasicOps(unittest.TestCase):
608
609 def test_repr(self):
610 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000611 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000612
Raymond Hettingereae05de2004-07-09 04:51:24 +0000613 def test_print(self):
614 try:
615 fo = open(test_support.TESTFN, "wb")
616 print >> fo, self.set,
617 fo.close()
618 fo = open(test_support.TESTFN, "rb")
619 self.assertEqual(fo.read(), repr(self.set))
620 finally:
621 fo.close()
622 os.remove(test_support.TESTFN)
623
Raymond Hettingera690a992003-11-16 16:17:49 +0000624 def test_length(self):
625 self.assertEqual(len(self.set), self.length)
626
627 def test_self_equality(self):
628 self.assertEqual(self.set, self.set)
629
630 def test_equivalent_equality(self):
631 self.assertEqual(self.set, self.dup)
632
633 def test_copy(self):
634 self.assertEqual(self.set.copy(), self.dup)
635
636 def test_self_union(self):
637 result = self.set | self.set
638 self.assertEqual(result, self.dup)
639
640 def test_empty_union(self):
641 result = self.set | empty_set
642 self.assertEqual(result, self.dup)
643
644 def test_union_empty(self):
645 result = empty_set | self.set
646 self.assertEqual(result, self.dup)
647
648 def test_self_intersection(self):
649 result = self.set & self.set
650 self.assertEqual(result, self.dup)
651
652 def test_empty_intersection(self):
653 result = self.set & empty_set
654 self.assertEqual(result, empty_set)
655
656 def test_intersection_empty(self):
657 result = empty_set & self.set
658 self.assertEqual(result, empty_set)
659
660 def test_self_symmetric_difference(self):
661 result = self.set ^ self.set
662 self.assertEqual(result, empty_set)
663
664 def checkempty_symmetric_difference(self):
665 result = self.set ^ empty_set
666 self.assertEqual(result, self.set)
667
668 def test_self_difference(self):
669 result = self.set - self.set
670 self.assertEqual(result, empty_set)
671
672 def test_empty_difference(self):
673 result = self.set - empty_set
674 self.assertEqual(result, self.dup)
675
676 def test_empty_difference_rev(self):
677 result = empty_set - self.set
678 self.assertEqual(result, empty_set)
679
680 def test_iteration(self):
681 for v in self.set:
682 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000683 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000684 # note: __length_hint__ is an internal undocumented API,
685 # don't rely on it in your own programs
686 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000687
688 def test_pickling(self):
689 p = pickle.dumps(self.set)
690 copy = pickle.loads(p)
691 self.assertEqual(self.set, copy,
692 "%s != %s" % (self.set, copy))
693
694#------------------------------------------------------------------------------
695
696class TestBasicOpsEmpty(TestBasicOps):
697 def setUp(self):
698 self.case = "empty set"
699 self.values = []
700 self.set = set(self.values)
701 self.dup = set(self.values)
702 self.length = 0
703 self.repr = "set([])"
704
705#------------------------------------------------------------------------------
706
707class TestBasicOpsSingleton(TestBasicOps):
708 def setUp(self):
709 self.case = "unit set (number)"
710 self.values = [3]
711 self.set = set(self.values)
712 self.dup = set(self.values)
713 self.length = 1
714 self.repr = "set([3])"
715
716 def test_in(self):
717 self.failUnless(3 in self.set)
718
719 def test_not_in(self):
720 self.failUnless(2 not in self.set)
721
722#------------------------------------------------------------------------------
723
724class TestBasicOpsTuple(TestBasicOps):
725 def setUp(self):
726 self.case = "unit set (tuple)"
727 self.values = [(0, "zero")]
728 self.set = set(self.values)
729 self.dup = set(self.values)
730 self.length = 1
731 self.repr = "set([(0, 'zero')])"
732
733 def test_in(self):
734 self.failUnless((0, "zero") in self.set)
735
736 def test_not_in(self):
737 self.failUnless(9 not in self.set)
738
739#------------------------------------------------------------------------------
740
741class TestBasicOpsTriple(TestBasicOps):
742 def setUp(self):
743 self.case = "triple set"
744 self.values = [0, "zero", operator.add]
745 self.set = set(self.values)
746 self.dup = set(self.values)
747 self.length = 3
748 self.repr = None
749
750#==============================================================================
751
752def baditer():
753 raise TypeError
754 yield True
755
756def gooditer():
757 yield True
758
759class TestExceptionPropagation(unittest.TestCase):
760 """SF 628246: Set constructor should not trap iterator TypeErrors"""
761
762 def test_instanceWithException(self):
763 self.assertRaises(TypeError, set, baditer())
764
765 def test_instancesWithoutException(self):
766 # All of these iterables should load without exception.
767 set([1,2,3])
768 set((1,2,3))
769 set({'one':1, 'two':2, 'three':3})
770 set(xrange(3))
771 set('abc')
772 set(gooditer())
773
Neal Norwitzfcf44352005-11-27 20:37:43 +0000774 def test_changingSizeWhileIterating(self):
775 s = set([1,2,3])
776 try:
777 for i in s:
778 s.update([4])
779 except RuntimeError:
780 pass
781 else:
782 self.fail("no exception when changing size during iteration")
783
Raymond Hettingera690a992003-11-16 16:17:49 +0000784#==============================================================================
785
786class TestSetOfSets(unittest.TestCase):
787 def test_constructor(self):
788 inner = frozenset([1])
789 outer = set([inner])
790 element = outer.pop()
791 self.assertEqual(type(element), frozenset)
792 outer.add(inner) # Rebuild set of sets with .add method
793 outer.remove(inner)
794 self.assertEqual(outer, set()) # Verify that remove worked
795 outer.discard(inner) # Absence of KeyError indicates working fine
796
797#==============================================================================
798
799class TestBinaryOps(unittest.TestCase):
800 def setUp(self):
801 self.set = set((2, 4, 6))
802
803 def test_eq(self): # SF bug 643115
804 self.assertEqual(self.set, set({2:1,4:3,6:5}))
805
806 def test_union_subset(self):
807 result = self.set | set([2])
808 self.assertEqual(result, set((2, 4, 6)))
809
810 def test_union_superset(self):
811 result = self.set | set([2, 4, 6, 8])
812 self.assertEqual(result, set([2, 4, 6, 8]))
813
814 def test_union_overlap(self):
815 result = self.set | set([3, 4, 5])
816 self.assertEqual(result, set([2, 3, 4, 5, 6]))
817
818 def test_union_non_overlap(self):
819 result = self.set | set([8])
820 self.assertEqual(result, set([2, 4, 6, 8]))
821
822 def test_intersection_subset(self):
823 result = self.set & set((2, 4))
824 self.assertEqual(result, set((2, 4)))
825
826 def test_intersection_superset(self):
827 result = self.set & set([2, 4, 6, 8])
828 self.assertEqual(result, set([2, 4, 6]))
829
830 def test_intersection_overlap(self):
831 result = self.set & set([3, 4, 5])
832 self.assertEqual(result, set([4]))
833
834 def test_intersection_non_overlap(self):
835 result = self.set & set([8])
836 self.assertEqual(result, empty_set)
837
838 def test_sym_difference_subset(self):
839 result = self.set ^ set((2, 4))
840 self.assertEqual(result, set([6]))
841
842 def test_sym_difference_superset(self):
843 result = self.set ^ set((2, 4, 6, 8))
844 self.assertEqual(result, set([8]))
845
846 def test_sym_difference_overlap(self):
847 result = self.set ^ set((3, 4, 5))
848 self.assertEqual(result, set([2, 3, 5, 6]))
849
850 def test_sym_difference_non_overlap(self):
851 result = self.set ^ set([8])
852 self.assertEqual(result, set([2, 4, 6, 8]))
853
854 def test_cmp(self):
855 a, b = set('a'), set('b')
856 self.assertRaises(TypeError, cmp, a, b)
857
858 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
859 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
860 # which Python thinks is good enough to synthesize a cmp() result
861 # without calling __cmp__.
862 self.assertEqual(cmp(a, a), 0)
863
864 self.assertRaises(TypeError, cmp, a, 12)
865 self.assertRaises(TypeError, cmp, "abc", a)
866
867#==============================================================================
868
869class TestUpdateOps(unittest.TestCase):
870 def setUp(self):
871 self.set = set((2, 4, 6))
872
873 def test_union_subset(self):
874 self.set |= set([2])
875 self.assertEqual(self.set, set((2, 4, 6)))
876
877 def test_union_superset(self):
878 self.set |= set([2, 4, 6, 8])
879 self.assertEqual(self.set, set([2, 4, 6, 8]))
880
881 def test_union_overlap(self):
882 self.set |= set([3, 4, 5])
883 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
884
885 def test_union_non_overlap(self):
886 self.set |= set([8])
887 self.assertEqual(self.set, set([2, 4, 6, 8]))
888
889 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000890 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +0000891 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
892
893 def test_intersection_subset(self):
894 self.set &= set((2, 4))
895 self.assertEqual(self.set, set((2, 4)))
896
897 def test_intersection_superset(self):
898 self.set &= set([2, 4, 6, 8])
899 self.assertEqual(self.set, set([2, 4, 6]))
900
901 def test_intersection_overlap(self):
902 self.set &= set([3, 4, 5])
903 self.assertEqual(self.set, set([4]))
904
905 def test_intersection_non_overlap(self):
906 self.set &= set([8])
907 self.assertEqual(self.set, empty_set)
908
909 def test_intersection_method_call(self):
910 self.set.intersection_update(set([3, 4, 5]))
911 self.assertEqual(self.set, set([4]))
912
913 def test_sym_difference_subset(self):
914 self.set ^= set((2, 4))
915 self.assertEqual(self.set, set([6]))
916
917 def test_sym_difference_superset(self):
918 self.set ^= set((2, 4, 6, 8))
919 self.assertEqual(self.set, set([8]))
920
921 def test_sym_difference_overlap(self):
922 self.set ^= set((3, 4, 5))
923 self.assertEqual(self.set, set([2, 3, 5, 6]))
924
925 def test_sym_difference_non_overlap(self):
926 self.set ^= set([8])
927 self.assertEqual(self.set, set([2, 4, 6, 8]))
928
929 def test_sym_difference_method_call(self):
930 self.set.symmetric_difference_update(set([3, 4, 5]))
931 self.assertEqual(self.set, set([2, 3, 5, 6]))
932
933 def test_difference_subset(self):
934 self.set -= set((2, 4))
935 self.assertEqual(self.set, set([6]))
936
937 def test_difference_superset(self):
938 self.set -= set((2, 4, 6, 8))
939 self.assertEqual(self.set, set([]))
940
941 def test_difference_overlap(self):
942 self.set -= set((3, 4, 5))
943 self.assertEqual(self.set, set([2, 6]))
944
945 def test_difference_non_overlap(self):
946 self.set -= set([8])
947 self.assertEqual(self.set, set([2, 4, 6]))
948
949 def test_difference_method_call(self):
950 self.set.difference_update(set([3, 4, 5]))
951 self.assertEqual(self.set, set([2, 6]))
952
953#==============================================================================
954
955class TestMutate(unittest.TestCase):
956 def setUp(self):
957 self.values = ["a", "b", "c"]
958 self.set = set(self.values)
959
960 def test_add_present(self):
961 self.set.add("c")
962 self.assertEqual(self.set, set("abc"))
963
964 def test_add_absent(self):
965 self.set.add("d")
966 self.assertEqual(self.set, set("abcd"))
967
968 def test_add_until_full(self):
969 tmp = set()
970 expected_len = 0
971 for v in self.values:
972 tmp.add(v)
973 expected_len += 1
974 self.assertEqual(len(tmp), expected_len)
975 self.assertEqual(tmp, self.set)
976
977 def test_remove_present(self):
978 self.set.remove("b")
979 self.assertEqual(self.set, set("ac"))
980
981 def test_remove_absent(self):
982 try:
983 self.set.remove("d")
984 self.fail("Removing missing element should have raised LookupError")
985 except LookupError:
986 pass
987
988 def test_remove_until_empty(self):
989 expected_len = len(self.set)
990 for v in self.values:
991 self.set.remove(v)
992 expected_len -= 1
993 self.assertEqual(len(self.set), expected_len)
994
995 def test_discard_present(self):
996 self.set.discard("c")
997 self.assertEqual(self.set, set("ab"))
998
999 def test_discard_absent(self):
1000 self.set.discard("d")
1001 self.assertEqual(self.set, set("abc"))
1002
1003 def test_clear(self):
1004 self.set.clear()
1005 self.assertEqual(len(self.set), 0)
1006
1007 def test_pop(self):
1008 popped = {}
1009 while self.set:
1010 popped[self.set.pop()] = None
1011 self.assertEqual(len(popped), len(self.values))
1012 for v in self.values:
1013 self.failUnless(v in popped)
1014
1015 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001016 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001017 self.assertEqual(self.set, set(self.values))
1018
1019 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001020 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001021 self.assertEqual(self.set, set(self.values))
1022
1023 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001024 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001025 self.assertEqual(self.set, set(self.values + ["z"]))
1026
1027#==============================================================================
1028
1029class TestSubsets(unittest.TestCase):
1030
1031 case2method = {"<=": "issubset",
1032 ">=": "issuperset",
1033 }
1034
1035 reverse = {"==": "==",
1036 "!=": "!=",
1037 "<": ">",
1038 ">": "<",
1039 "<=": ">=",
1040 ">=": "<=",
1041 }
1042
1043 def test_issubset(self):
1044 x = self.left
1045 y = self.right
1046 for case in "!=", "==", "<", "<=", ">", ">=":
1047 expected = case in self.cases
1048 # Test the binary infix spelling.
1049 result = eval("x" + case + "y", locals())
1050 self.assertEqual(result, expected)
1051 # Test the "friendly" method-name spelling, if one exists.
1052 if case in TestSubsets.case2method:
1053 method = getattr(x, TestSubsets.case2method[case])
1054 result = method(y)
1055 self.assertEqual(result, expected)
1056
1057 # Now do the same for the operands reversed.
1058 rcase = TestSubsets.reverse[case]
1059 result = eval("y" + rcase + "x", locals())
1060 self.assertEqual(result, expected)
1061 if rcase in TestSubsets.case2method:
1062 method = getattr(y, TestSubsets.case2method[rcase])
1063 result = method(x)
1064 self.assertEqual(result, expected)
1065#------------------------------------------------------------------------------
1066
1067class TestSubsetEqualEmpty(TestSubsets):
1068 left = set()
1069 right = set()
1070 name = "both empty"
1071 cases = "==", "<=", ">="
1072
1073#------------------------------------------------------------------------------
1074
1075class TestSubsetEqualNonEmpty(TestSubsets):
1076 left = set([1, 2])
1077 right = set([1, 2])
1078 name = "equal pair"
1079 cases = "==", "<=", ">="
1080
1081#------------------------------------------------------------------------------
1082
1083class TestSubsetEmptyNonEmpty(TestSubsets):
1084 left = set()
1085 right = set([1, 2])
1086 name = "one empty, one non-empty"
1087 cases = "!=", "<", "<="
1088
1089#------------------------------------------------------------------------------
1090
1091class TestSubsetPartial(TestSubsets):
1092 left = set([1])
1093 right = set([1, 2])
1094 name = "one a non-empty proper subset of other"
1095 cases = "!=", "<", "<="
1096
1097#------------------------------------------------------------------------------
1098
1099class TestSubsetNonOverlap(TestSubsets):
1100 left = set([1])
1101 right = set([2])
1102 name = "neither empty, neither contains"
1103 cases = "!="
1104
1105#==============================================================================
1106
1107class TestOnlySetsInBinaryOps(unittest.TestCase):
1108
1109 def test_eq_ne(self):
1110 # Unlike the others, this is testing that == and != *are* allowed.
1111 self.assertEqual(self.other == self.set, False)
1112 self.assertEqual(self.set == self.other, False)
1113 self.assertEqual(self.other != self.set, True)
1114 self.assertEqual(self.set != self.other, True)
1115
1116 def test_ge_gt_le_lt(self):
1117 self.assertRaises(TypeError, lambda: self.set < self.other)
1118 self.assertRaises(TypeError, lambda: self.set <= self.other)
1119 self.assertRaises(TypeError, lambda: self.set > self.other)
1120 self.assertRaises(TypeError, lambda: self.set >= self.other)
1121
1122 self.assertRaises(TypeError, lambda: self.other < self.set)
1123 self.assertRaises(TypeError, lambda: self.other <= self.set)
1124 self.assertRaises(TypeError, lambda: self.other > self.set)
1125 self.assertRaises(TypeError, lambda: self.other >= self.set)
1126
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001127 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001128 try:
1129 self.set |= self.other
1130 except TypeError:
1131 pass
1132 else:
1133 self.fail("expected TypeError")
1134
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001135 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001136 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001137 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001138 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001139 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001140
1141 def test_union(self):
1142 self.assertRaises(TypeError, lambda: self.set | self.other)
1143 self.assertRaises(TypeError, lambda: self.other | self.set)
1144 if self.otherIsIterable:
1145 self.set.union(self.other)
1146 else:
1147 self.assertRaises(TypeError, self.set.union, self.other)
1148
1149 def test_intersection_update_operator(self):
1150 try:
1151 self.set &= self.other
1152 except TypeError:
1153 pass
1154 else:
1155 self.fail("expected TypeError")
1156
1157 def test_intersection_update(self):
1158 if self.otherIsIterable:
1159 self.set.intersection_update(self.other)
1160 else:
1161 self.assertRaises(TypeError,
1162 self.set.intersection_update,
1163 self.other)
1164
1165 def test_intersection(self):
1166 self.assertRaises(TypeError, lambda: self.set & self.other)
1167 self.assertRaises(TypeError, lambda: self.other & self.set)
1168 if self.otherIsIterable:
1169 self.set.intersection(self.other)
1170 else:
1171 self.assertRaises(TypeError, self.set.intersection, self.other)
1172
1173 def test_sym_difference_update_operator(self):
1174 try:
1175 self.set ^= self.other
1176 except TypeError:
1177 pass
1178 else:
1179 self.fail("expected TypeError")
1180
1181 def test_sym_difference_update(self):
1182 if self.otherIsIterable:
1183 self.set.symmetric_difference_update(self.other)
1184 else:
1185 self.assertRaises(TypeError,
1186 self.set.symmetric_difference_update,
1187 self.other)
1188
1189 def test_sym_difference(self):
1190 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1191 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1192 if self.otherIsIterable:
1193 self.set.symmetric_difference(self.other)
1194 else:
1195 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1196
1197 def test_difference_update_operator(self):
1198 try:
1199 self.set -= self.other
1200 except TypeError:
1201 pass
1202 else:
1203 self.fail("expected TypeError")
1204
1205 def test_difference_update(self):
1206 if self.otherIsIterable:
1207 self.set.difference_update(self.other)
1208 else:
1209 self.assertRaises(TypeError,
1210 self.set.difference_update,
1211 self.other)
1212
1213 def test_difference(self):
1214 self.assertRaises(TypeError, lambda: self.set - self.other)
1215 self.assertRaises(TypeError, lambda: self.other - self.set)
1216 if self.otherIsIterable:
1217 self.set.difference(self.other)
1218 else:
1219 self.assertRaises(TypeError, self.set.difference, self.other)
1220
1221#------------------------------------------------------------------------------
1222
1223class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1224 def setUp(self):
1225 self.set = set((1, 2, 3))
1226 self.other = 19
1227 self.otherIsIterable = False
1228
1229#------------------------------------------------------------------------------
1230
1231class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1232 def setUp(self):
1233 self.set = set((1, 2, 3))
1234 self.other = {1:2, 3:4}
1235 self.otherIsIterable = True
1236
1237#------------------------------------------------------------------------------
1238
1239class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1240 def setUp(self):
1241 self.set = set((1, 2, 3))
1242 self.other = operator.add
1243 self.otherIsIterable = False
1244
1245#------------------------------------------------------------------------------
1246
1247class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1248 def setUp(self):
1249 self.set = set((1, 2, 3))
1250 self.other = (2, 4, 6)
1251 self.otherIsIterable = True
1252
1253#------------------------------------------------------------------------------
1254
1255class TestOnlySetsString(TestOnlySetsInBinaryOps):
1256 def setUp(self):
1257 self.set = set((1, 2, 3))
1258 self.other = 'abc'
1259 self.otherIsIterable = True
1260
1261#------------------------------------------------------------------------------
1262
1263class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1264 def setUp(self):
1265 def gen():
1266 for i in xrange(0, 10, 2):
1267 yield i
1268 self.set = set((1, 2, 3))
1269 self.other = gen()
1270 self.otherIsIterable = True
1271
1272#==============================================================================
1273
1274class TestCopying(unittest.TestCase):
1275
1276 def test_copy(self):
1277 dup = self.set.copy()
1278 dup_list = list(dup); dup_list.sort()
1279 set_list = list(self.set); set_list.sort()
1280 self.assertEqual(len(dup_list), len(set_list))
1281 for i in range(len(dup_list)):
1282 self.failUnless(dup_list[i] is set_list[i])
1283
1284 def test_deep_copy(self):
1285 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001286 ##print type(dup), repr(dup)
Raymond Hettingera690a992003-11-16 16:17:49 +00001287 dup_list = list(dup); dup_list.sort()
1288 set_list = list(self.set); set_list.sort()
1289 self.assertEqual(len(dup_list), len(set_list))
1290 for i in range(len(dup_list)):
1291 self.assertEqual(dup_list[i], set_list[i])
1292
1293#------------------------------------------------------------------------------
1294
1295class TestCopyingEmpty(TestCopying):
1296 def setUp(self):
1297 self.set = set()
1298
1299#------------------------------------------------------------------------------
1300
1301class TestCopyingSingleton(TestCopying):
1302 def setUp(self):
1303 self.set = set(["hello"])
1304
1305#------------------------------------------------------------------------------
1306
1307class TestCopyingTriple(TestCopying):
1308 def setUp(self):
1309 self.set = set(["zero", 0, None])
1310
1311#------------------------------------------------------------------------------
1312
1313class TestCopyingTuple(TestCopying):
1314 def setUp(self):
1315 self.set = set([(1, 2)])
1316
1317#------------------------------------------------------------------------------
1318
1319class TestCopyingNested(TestCopying):
1320 def setUp(self):
1321 self.set = set([((1, 2), (3, 4))])
1322
1323#==============================================================================
1324
1325class TestIdentities(unittest.TestCase):
1326 def setUp(self):
1327 self.a = set('abracadabra')
1328 self.b = set('alacazam')
1329
1330 def test_binopsVsSubsets(self):
1331 a, b = self.a, self.b
1332 self.assert_(a - b < a)
1333 self.assert_(b - a < b)
1334 self.assert_(a & b < a)
1335 self.assert_(a & b < b)
1336 self.assert_(a | b > a)
1337 self.assert_(a | b > b)
1338 self.assert_(a ^ b < a | b)
1339
1340 def test_commutativity(self):
1341 a, b = self.a, self.b
1342 self.assertEqual(a&b, b&a)
1343 self.assertEqual(a|b, b|a)
1344 self.assertEqual(a^b, b^a)
1345 if a != b:
1346 self.assertNotEqual(a-b, b-a)
1347
1348 def test_summations(self):
1349 # check that sums of parts equal the whole
1350 a, b = self.a, self.b
1351 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1352 self.assertEqual((a&b)|(a^b), a|b)
1353 self.assertEqual(a|(b-a), a|b)
1354 self.assertEqual((a-b)|b, a|b)
1355 self.assertEqual((a-b)|(a&b), a)
1356 self.assertEqual((b-a)|(a&b), b)
1357 self.assertEqual((a-b)|(b-a), a^b)
1358
1359 def test_exclusion(self):
1360 # check that inverse operations show non-overlap
1361 a, b, zero = self.a, self.b, set()
1362 self.assertEqual((a-b)&b, zero)
1363 self.assertEqual((b-a)&a, zero)
1364 self.assertEqual((a&b)&(a^b), zero)
1365
1366# Tests derived from test_itertools.py =======================================
1367
1368def R(seqn):
1369 'Regular generator'
1370 for i in seqn:
1371 yield i
1372
1373class G:
1374 'Sequence using __getitem__'
1375 def __init__(self, seqn):
1376 self.seqn = seqn
1377 def __getitem__(self, i):
1378 return self.seqn[i]
1379
1380class I:
1381 'Sequence using iterator protocol'
1382 def __init__(self, seqn):
1383 self.seqn = seqn
1384 self.i = 0
1385 def __iter__(self):
1386 return self
1387 def next(self):
1388 if self.i >= len(self.seqn): raise StopIteration
1389 v = self.seqn[self.i]
1390 self.i += 1
1391 return v
1392
1393class Ig:
1394 'Sequence using iterator protocol defined with a generator'
1395 def __init__(self, seqn):
1396 self.seqn = seqn
1397 self.i = 0
1398 def __iter__(self):
1399 for val in self.seqn:
1400 yield val
1401
1402class X:
1403 'Missing __getitem__ and __iter__'
1404 def __init__(self, seqn):
1405 self.seqn = seqn
1406 self.i = 0
1407 def next(self):
1408 if self.i >= len(self.seqn): raise StopIteration
1409 v = self.seqn[self.i]
1410 self.i += 1
1411 return v
1412
1413class N:
1414 'Iterator missing next()'
1415 def __init__(self, seqn):
1416 self.seqn = seqn
1417 self.i = 0
1418 def __iter__(self):
1419 return self
1420
1421class E:
1422 'Test propagation of exceptions'
1423 def __init__(self, seqn):
1424 self.seqn = seqn
1425 self.i = 0
1426 def __iter__(self):
1427 return self
1428 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001429 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001430
1431class S:
1432 'Test immediate stop'
1433 def __init__(self, seqn):
1434 pass
1435 def __iter__(self):
1436 return self
1437 def next(self):
1438 raise StopIteration
1439
1440from itertools import chain, imap
1441def L(seqn):
1442 'Test multiple tiers of iterators'
1443 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1444
1445class TestVariousIteratorArgs(unittest.TestCase):
1446
1447 def test_constructor(self):
1448 for cons in (set, frozenset):
1449 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1450 for g in (G, I, Ig, S, L, R):
Raymond Hettinger64958a12003-12-17 20:43:33 +00001451 self.assertEqual(sorted(cons(g(s))), sorted(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001452 self.assertRaises(TypeError, cons , X(s))
1453 self.assertRaises(TypeError, cons , N(s))
1454 self.assertRaises(ZeroDivisionError, cons , E(s))
1455
1456 def test_inline_methods(self):
1457 s = set('november')
1458 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
1459 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference):
1460 for g in (G, I, Ig, L, R):
1461 expected = meth(data)
1462 actual = meth(G(data))
Raymond Hettinger64958a12003-12-17 20:43:33 +00001463 self.assertEqual(sorted(actual), sorted(expected))
Raymond Hettingera690a992003-11-16 16:17:49 +00001464 self.assertRaises(TypeError, meth, X(s))
1465 self.assertRaises(TypeError, meth, N(s))
1466 self.assertRaises(ZeroDivisionError, meth, E(s))
1467
1468 def test_inplace_methods(self):
1469 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001470 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001471 'difference_update', 'symmetric_difference_update'):
1472 for g in (G, I, Ig, S, L, R):
1473 s = set('january')
1474 t = s.copy()
1475 getattr(s, methname)(list(g(data)))
1476 getattr(t, methname)(g(data))
Raymond Hettinger64958a12003-12-17 20:43:33 +00001477 self.assertEqual(sorted(s), sorted(t))
Raymond Hettingera690a992003-11-16 16:17:49 +00001478
1479 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1480 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1481 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1482
1483#==============================================================================
1484
1485def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001486 from test import test_sets
1487 test_classes = (
1488 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001489 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001490 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001491 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001492 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001493 TestSetOfSets,
1494 TestExceptionPropagation,
1495 TestBasicOpsEmpty,
1496 TestBasicOpsSingleton,
1497 TestBasicOpsTuple,
1498 TestBasicOpsTriple,
1499 TestBinaryOps,
1500 TestUpdateOps,
1501 TestMutate,
1502 TestSubsetEqualEmpty,
1503 TestSubsetEqualNonEmpty,
1504 TestSubsetEmptyNonEmpty,
1505 TestSubsetPartial,
1506 TestSubsetNonOverlap,
1507 TestOnlySetsNumeric,
1508 TestOnlySetsDict,
1509 TestOnlySetsOperator,
1510 TestOnlySetsTuple,
1511 TestOnlySetsString,
1512 TestOnlySetsGenerator,
1513 TestCopyingEmpty,
1514 TestCopyingSingleton,
1515 TestCopyingTriple,
1516 TestCopyingTuple,
1517 TestCopyingNested,
1518 TestIdentities,
1519 TestVariousIteratorArgs,
1520 )
1521
1522 test_support.run_unittest(*test_classes)
1523
1524 # verify reference counting
1525 if verbose and hasattr(sys, "gettotalrefcount"):
1526 import gc
1527 counts = [None] * 5
1528 for i in xrange(len(counts)):
1529 test_support.run_unittest(*test_classes)
1530 gc.collect()
1531 counts[i] = sys.gettotalrefcount()
1532 print counts
1533
1534if __name__ == "__main__":
1535 test_main(verbose=True)