blob: aba046a33b22798c1275cbba0d42f4585b9a2b54 [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
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000105 def test_isdisjoint(self):
106 def f(s1, s2):
107 'Pure python equivalent of isdisjoint()'
108 return not set(s1).intersection(s2)
109 for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
110 s1 = self.thetype(larg)
111 for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
112 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
113 s2 = C(rarg)
114 actual = s1.isdisjoint(s2)
115 expected = f(s1, s2)
116 self.assertEqual(actual, expected)
117 self.assert_(actual is True or actual is False)
118
Raymond Hettingera690a992003-11-16 16:17:49 +0000119 def test_and(self):
120 i = self.s.intersection(self.otherword)
121 self.assertEqual(self.s & set(self.otherword), i)
122 self.assertEqual(self.s & frozenset(self.otherword), i)
123 try:
124 self.s & self.otherword
125 except TypeError:
126 pass
127 else:
128 self.fail("s&t did not screen-out general iterables")
129
130 def test_difference(self):
131 i = self.s.difference(self.otherword)
132 for c in self.letters:
133 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000134 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000135 self.assertEqual(type(i), self.thetype)
136 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
137 self.assertRaises(TypeError, self.s.difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000138 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
139 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
140 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
141 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
142 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000143
144 def test_sub(self):
145 i = self.s.difference(self.otherword)
146 self.assertEqual(self.s - set(self.otherword), i)
147 self.assertEqual(self.s - frozenset(self.otherword), i)
148 try:
149 self.s - self.otherword
150 except TypeError:
151 pass
152 else:
153 self.fail("s-t did not screen-out general iterables")
154
155 def test_symmetric_difference(self):
156 i = self.s.symmetric_difference(self.otherword)
157 for c in self.letters:
158 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000159 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000160 self.assertEqual(type(i), self.thetype)
161 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
162 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000163 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
164 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
165 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
166 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
167 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000168
169 def test_xor(self):
170 i = self.s.symmetric_difference(self.otherword)
171 self.assertEqual(self.s ^ set(self.otherword), i)
172 self.assertEqual(self.s ^ frozenset(self.otherword), i)
173 try:
174 self.s ^ self.otherword
175 except TypeError:
176 pass
177 else:
178 self.fail("s^t did not screen-out general iterables")
179
180 def test_equality(self):
181 self.assertEqual(self.s, set(self.word))
182 self.assertEqual(self.s, frozenset(self.word))
183 self.assertEqual(self.s == self.word, False)
184 self.assertNotEqual(self.s, set(self.otherword))
185 self.assertNotEqual(self.s, frozenset(self.otherword))
186 self.assertEqual(self.s != self.word, True)
187
188 def test_setOfFrozensets(self):
189 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
190 s = self.thetype(t)
191 self.assertEqual(len(s), 3)
192
193 def test_compare(self):
194 self.assertRaises(TypeError, self.s.__cmp__, self.s)
195
196 def test_sub_and_super(self):
197 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
198 self.assert_(p < q)
199 self.assert_(p <= q)
200 self.assert_(q <= q)
201 self.assert_(q > p)
202 self.assert_(q >= p)
203 self.failIf(q < r)
204 self.failIf(q <= r)
205 self.failIf(q > r)
206 self.failIf(q >= r)
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000207 self.assert_(set('a').issubset('abc'))
208 self.assert_(set('abc').issuperset('a'))
209 self.failIf(set('a').issubset('cbs'))
210 self.failIf(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000211
212 def test_pickling(self):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000213 for i in (0, 1, 2):
214 p = pickle.dumps(self.s, i)
215 dup = pickle.loads(p)
216 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
217 if type(self.s) not in (set, frozenset):
218 self.s.x = 10
219 p = pickle.dumps(self.s)
220 dup = pickle.loads(p)
221 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000222
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000223 def test_deepcopy(self):
224 class Tracer:
225 def __init__(self, value):
226 self.value = value
227 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000228 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000229 def __deepcopy__(self, memo=None):
230 return Tracer(self.value + 1)
231 t = Tracer(10)
232 s = self.thetype([t])
233 dup = copy.deepcopy(s)
234 self.assertNotEqual(id(s), id(dup))
235 for elem in dup:
236 newt = elem
237 self.assertNotEqual(id(t), id(newt))
238 self.assertEqual(t.value + 1, newt.value)
239
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000240 def test_gc(self):
241 # Create a nest of cycles to exercise overall ref count check
242 class A:
243 pass
244 s = set(A() for i in xrange(1000))
245 for elem in s:
246 elem.cycle = s
247 elem.sub = elem
248 elem.set = set([elem])
249
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000250 def test_subclass_with_custom_hash(self):
251 # Bug #1257731
252 class H(self.thetype):
253 def __hash__(self):
Tim Peters6902b442006-04-11 00:43:27 +0000254 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000255 s=H()
256 f=set()
257 f.add(s)
258 self.assert_(s in f)
259 f.remove(s)
260 f.add(s)
261 f.discard(s)
262
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000263 def test_badcmp(self):
264 s = self.thetype([BadCmp()])
265 # Detect comparison errors during insertion and lookup
266 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
267 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
268 # Detect errors during mutating operations
269 if hasattr(s, 'add'):
270 self.assertRaises(RuntimeError, s.add, BadCmp())
271 self.assertRaises(RuntimeError, s.discard, BadCmp())
272 self.assertRaises(RuntimeError, s.remove, BadCmp())
273
Raymond Hettinger53999102006-12-30 04:01:17 +0000274 def test_cyclical_repr(self):
275 w = ReprWrapper()
276 s = self.thetype([w])
277 w.value = s
278 name = repr(s).partition('(')[0] # strip class name from repr string
279 self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
280
281 def test_cyclical_print(self):
282 w = ReprWrapper()
283 s = self.thetype([w])
284 w.value = s
285 try:
286 fo = open(test_support.TESTFN, "wb")
287 print >> fo, s,
288 fo.close()
289 fo = open(test_support.TESTFN, "rb")
290 self.assertEqual(fo.read(), repr(s))
291 finally:
292 fo.close()
293 os.remove(test_support.TESTFN)
294
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000295 def test_do_not_rehash_dict_keys(self):
296 n = 10
297 d = dict.fromkeys(map(HashCountingInt, xrange(n)))
298 self.assertEqual(sum(elem.hash_count for elem in d), n)
299 s = self.thetype(d)
300 self.assertEqual(sum(elem.hash_count for elem in d), n)
301 s.difference(d)
Tim Petersea5962f2007-03-12 18:07:52 +0000302 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000303 if hasattr(s, 'symmetric_difference_update'):
304 s.symmetric_difference_update(d)
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000305 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettinger0bbbfc42007-03-20 21:27:24 +0000306 d2 = dict.fromkeys(set(d))
307 self.assertEqual(sum(elem.hash_count for elem in d), n)
308 d3 = dict.fromkeys(frozenset(d))
Tim Petersea5962f2007-03-12 18:07:52 +0000309 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingere3146f52007-03-21 20:33:57 +0000310 d3 = dict.fromkeys(frozenset(d), 123)
311 self.assertEqual(sum(elem.hash_count for elem in d), n)
312 self.assertEqual(d3, dict.fromkeys(d, 123))
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000313
Raymond Hettingera690a992003-11-16 16:17:49 +0000314class TestSet(TestJointOps):
315 thetype = set
316
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000317 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000318 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000319 s.__init__(self.word)
320 self.assertEqual(s, set(self.word))
321 s.__init__(self.otherword)
322 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000323 self.assertRaises(TypeError, s.__init__, s, 2);
324 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000325
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000326 def test_constructor_identity(self):
327 s = self.thetype(range(3))
328 t = self.thetype(s)
329 self.assertNotEqual(id(s), id(t))
330
Raymond Hettingera690a992003-11-16 16:17:49 +0000331 def test_hash(self):
332 self.assertRaises(TypeError, hash, self.s)
333
334 def test_clear(self):
335 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000336 self.assertEqual(self.s, set())
337 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000338
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000339 def test_copy(self):
340 dup = self.s.copy()
341 self.assertEqual(self.s, dup)
342 self.assertNotEqual(id(self.s), id(dup))
343
Raymond Hettingera690a992003-11-16 16:17:49 +0000344 def test_add(self):
345 self.s.add('Q')
346 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000347 dup = self.s.copy()
348 self.s.add('Q')
349 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000350 self.assertRaises(TypeError, self.s.add, [])
351
352 def test_remove(self):
353 self.s.remove('a')
354 self.assert_('a' not in self.s)
355 self.assertRaises(KeyError, self.s.remove, 'Q')
356 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000357 s = self.thetype([frozenset(self.word)])
358 self.assert_(self.thetype(self.word) in s)
359 s.remove(self.thetype(self.word))
360 self.assert_(self.thetype(self.word) not in s)
361 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000362
Raymond Hettingerc789f342006-12-08 17:35:25 +0000363 def test_remove_keyerror_unpacking(self):
364 # bug: www.python.org/sf/1576657
365 for v1 in ['Q', (1,)]:
366 try:
367 self.s.remove(v1)
368 except KeyError, e:
369 v2 = e.args[0]
370 self.assertEqual(v1, v2)
371 else:
372 self.fail()
373
Raymond Hettingera690a992003-11-16 16:17:49 +0000374 def test_discard(self):
375 self.s.discard('a')
376 self.assert_('a' not in self.s)
377 self.s.discard('Q')
378 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000379 s = self.thetype([frozenset(self.word)])
380 self.assert_(self.thetype(self.word) in s)
381 s.discard(self.thetype(self.word))
382 self.assert_(self.thetype(self.word) not in s)
383 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000384
385 def test_pop(self):
386 for i in xrange(len(self.s)):
387 elem = self.s.pop()
388 self.assert_(elem not in self.s)
389 self.assertRaises(KeyError, self.s.pop)
390
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000391 def test_update(self):
392 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000393 self.assertEqual(retval, None)
394 for c in (self.word + self.otherword):
395 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000396 self.assertRaises(PassThru, self.s.update, check_pass_thru())
397 self.assertRaises(TypeError, self.s.update, [[]])
398 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
399 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
400 s = self.thetype('abcba')
401 self.assertEqual(s.update(C(p)), None)
402 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000403
404 def test_ior(self):
405 self.s |= set(self.otherword)
406 for c in (self.word + self.otherword):
407 self.assert_(c in self.s)
408
409 def test_intersection_update(self):
410 retval = self.s.intersection_update(self.otherword)
411 self.assertEqual(retval, None)
412 for c in (self.word + self.otherword):
413 if c in self.otherword and c in self.word:
414 self.assert_(c in self.s)
415 else:
416 self.assert_(c not in self.s)
417 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
418 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000419 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
420 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
421 s = self.thetype('abcba')
422 self.assertEqual(s.intersection_update(C(p)), None)
423 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000424
425 def test_iand(self):
426 self.s &= set(self.otherword)
427 for c in (self.word + self.otherword):
428 if c in self.otherword and c in self.word:
429 self.assert_(c in self.s)
430 else:
431 self.assert_(c not in self.s)
432
433 def test_difference_update(self):
434 retval = self.s.difference_update(self.otherword)
435 self.assertEqual(retval, None)
436 for c in (self.word + self.otherword):
437 if c in self.word and c not in self.otherword:
438 self.assert_(c in self.s)
439 else:
440 self.assert_(c not in self.s)
441 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
442 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000443 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
444 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
445 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
446 s = self.thetype('abcba')
447 self.assertEqual(s.difference_update(C(p)), None)
448 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000449
450 def test_isub(self):
451 self.s -= set(self.otherword)
452 for c in (self.word + self.otherword):
453 if c in self.word and c not in self.otherword:
454 self.assert_(c in self.s)
455 else:
456 self.assert_(c not in self.s)
457
458 def test_symmetric_difference_update(self):
459 retval = self.s.symmetric_difference_update(self.otherword)
460 self.assertEqual(retval, None)
461 for c in (self.word + self.otherword):
462 if (c in self.word) ^ (c in self.otherword):
463 self.assert_(c in self.s)
464 else:
465 self.assert_(c not in self.s)
466 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
467 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000468 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
469 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
470 s = self.thetype('abcba')
471 self.assertEqual(s.symmetric_difference_update(C(p)), None)
472 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000473
474 def test_ixor(self):
475 self.s ^= set(self.otherword)
476 for c in (self.word + self.otherword):
477 if (c in self.word) ^ (c in self.otherword):
478 self.assert_(c in self.s)
479 else:
480 self.assert_(c not in self.s)
481
Raymond Hettingerc991db22005-08-11 07:58:45 +0000482 def test_inplace_on_self(self):
483 t = self.s.copy()
484 t |= t
485 self.assertEqual(t, self.s)
486 t &= t
487 self.assertEqual(t, self.s)
488 t -= t
489 self.assertEqual(t, self.thetype())
490 t = self.s.copy()
491 t ^= t
492 self.assertEqual(t, self.thetype())
493
Raymond Hettinger691d8052004-05-30 07:26:47 +0000494 def test_weakref(self):
495 s = self.thetype('gallahad')
496 p = proxy(s)
497 self.assertEqual(str(p), str(s))
498 s = None
499 self.assertRaises(ReferenceError, str, p)
500
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000501 # C API test only available in a debug build
Barry Warsaw176014f2006-03-30 22:45:35 +0000502 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000503 def test_c_api(self):
504 self.assertEqual(set('abc').test_c_api(), True)
505
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000506class SetSubclass(set):
507 pass
508
509class TestSetSubclass(TestSet):
510 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000511
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000512class SetSubclassWithKeywordArgs(set):
513 def __init__(self, iterable=[], newarg=None):
514 set.__init__(self, iterable)
515
516class TestSetSubclassWithKeywordArgs(TestSet):
Tim Petersf733abb2007-01-30 03:03:46 +0000517
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000518 def test_keywords_in_subclass(self):
519 'SF bug #1486663 -- this used to erroneously raise a TypeError'
520 SetSubclassWithKeywordArgs(newarg=1)
521
Raymond Hettingera690a992003-11-16 16:17:49 +0000522class TestFrozenSet(TestJointOps):
523 thetype = frozenset
524
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000525 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000526 s = self.thetype(self.word)
527 s.__init__(self.otherword)
528 self.assertEqual(s, set(self.word))
529
Raymond Hettingerd7946662005-08-01 21:39:29 +0000530 def test_singleton_empty_frozenset(self):
531 f = frozenset()
532 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
533 frozenset(), frozenset([]), frozenset(()), frozenset(''),
534 frozenset(xrange(0)), frozenset(frozenset()),
535 frozenset(f), f]
536 # All of the empty frozensets should have just one id()
537 self.assertEqual(len(set(map(id, efs))), 1)
538
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000539 def test_constructor_identity(self):
540 s = self.thetype(range(3))
541 t = self.thetype(s)
542 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000543
Raymond Hettingera690a992003-11-16 16:17:49 +0000544 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000545 self.assertEqual(hash(self.thetype('abcdeb')),
546 hash(self.thetype('ebecda')))
547
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000548 # make sure that all permutations give the same hash value
549 n = 100
550 seq = [randrange(n) for i in xrange(n)]
551 results = set()
552 for i in xrange(200):
553 shuffle(seq)
554 results.add(hash(self.thetype(seq)))
555 self.assertEqual(len(results), 1)
556
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000557 def test_copy(self):
558 dup = self.s.copy()
559 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000560
561 def test_frozen_as_dictkey(self):
562 seq = range(10) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000563 key1 = self.thetype(seq)
564 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000565 self.assertEqual(key1, key2)
566 self.assertNotEqual(id(key1), id(key2))
567 d = {}
568 d[key1] = 42
569 self.assertEqual(d[key2], 42)
570
571 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000572 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000573 self.assertEqual(hash(f), hash(f))
574
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000575 def test_hash_effectiveness(self):
576 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000577 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000578 addhashvalue = hashvalues.add
579 elemmasks = [(i+1, 1<<i) for i in range(n)]
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000580 for i in xrange(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000581 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
582 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000583
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000584class FrozenSetSubclass(frozenset):
585 pass
586
587class TestFrozenSetSubclass(TestFrozenSet):
588 thetype = FrozenSetSubclass
589
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000590 def test_constructor_identity(self):
591 s = self.thetype(range(3))
592 t = self.thetype(s)
593 self.assertNotEqual(id(s), id(t))
594
595 def test_copy(self):
596 dup = self.s.copy()
597 self.assertNotEqual(id(self.s), id(dup))
598
599 def test_nested_empty_constructor(self):
600 s = self.thetype()
601 t = self.thetype(s)
602 self.assertEqual(s, t)
603
Raymond Hettingerd7946662005-08-01 21:39:29 +0000604 def test_singleton_empty_frozenset(self):
605 Frozenset = self.thetype
606 f = frozenset()
607 F = Frozenset()
608 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
609 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
610 Frozenset(xrange(0)), Frozenset(Frozenset()),
611 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
612 # All empty frozenset subclass instances should have different ids
613 self.assertEqual(len(set(map(id, efs))), len(efs))
614
Raymond Hettingera690a992003-11-16 16:17:49 +0000615# Tests taken from test_sets.py =============================================
616
617empty_set = set()
618
619#==============================================================================
620
621class TestBasicOps(unittest.TestCase):
622
623 def test_repr(self):
624 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000625 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000626
Raymond Hettingereae05de2004-07-09 04:51:24 +0000627 def test_print(self):
628 try:
629 fo = open(test_support.TESTFN, "wb")
630 print >> fo, self.set,
631 fo.close()
632 fo = open(test_support.TESTFN, "rb")
633 self.assertEqual(fo.read(), repr(self.set))
634 finally:
635 fo.close()
636 os.remove(test_support.TESTFN)
637
Raymond Hettingera690a992003-11-16 16:17:49 +0000638 def test_length(self):
639 self.assertEqual(len(self.set), self.length)
640
641 def test_self_equality(self):
642 self.assertEqual(self.set, self.set)
643
644 def test_equivalent_equality(self):
645 self.assertEqual(self.set, self.dup)
646
647 def test_copy(self):
648 self.assertEqual(self.set.copy(), self.dup)
649
650 def test_self_union(self):
651 result = self.set | self.set
652 self.assertEqual(result, self.dup)
653
654 def test_empty_union(self):
655 result = self.set | empty_set
656 self.assertEqual(result, self.dup)
657
658 def test_union_empty(self):
659 result = empty_set | self.set
660 self.assertEqual(result, self.dup)
661
662 def test_self_intersection(self):
663 result = self.set & self.set
664 self.assertEqual(result, self.dup)
665
666 def test_empty_intersection(self):
667 result = self.set & empty_set
668 self.assertEqual(result, empty_set)
669
670 def test_intersection_empty(self):
671 result = empty_set & self.set
672 self.assertEqual(result, empty_set)
673
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000674 def test_self_isdisjoint(self):
675 result = self.set.isdisjoint(self.set)
676 self.assertEqual(result, not self.set)
677
678 def test_empty_isdisjoint(self):
679 result = self.set.isdisjoint(empty_set)
680 self.assertEqual(result, True)
681
682 def test_isdisjoint_empty(self):
683 result = empty_set.isdisjoint(self.set)
684 self.assertEqual(result, True)
685
Raymond Hettingera690a992003-11-16 16:17:49 +0000686 def test_self_symmetric_difference(self):
687 result = self.set ^ self.set
688 self.assertEqual(result, empty_set)
689
690 def checkempty_symmetric_difference(self):
691 result = self.set ^ empty_set
692 self.assertEqual(result, self.set)
693
694 def test_self_difference(self):
695 result = self.set - self.set
696 self.assertEqual(result, empty_set)
697
698 def test_empty_difference(self):
699 result = self.set - empty_set
700 self.assertEqual(result, self.dup)
701
702 def test_empty_difference_rev(self):
703 result = empty_set - self.set
704 self.assertEqual(result, empty_set)
705
706 def test_iteration(self):
707 for v in self.set:
708 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000709 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000710 # note: __length_hint__ is an internal undocumented API,
711 # don't rely on it in your own programs
712 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000713
714 def test_pickling(self):
715 p = pickle.dumps(self.set)
716 copy = pickle.loads(p)
717 self.assertEqual(self.set, copy,
718 "%s != %s" % (self.set, copy))
719
720#------------------------------------------------------------------------------
721
722class TestBasicOpsEmpty(TestBasicOps):
723 def setUp(self):
724 self.case = "empty set"
725 self.values = []
726 self.set = set(self.values)
727 self.dup = set(self.values)
728 self.length = 0
729 self.repr = "set([])"
730
731#------------------------------------------------------------------------------
732
733class TestBasicOpsSingleton(TestBasicOps):
734 def setUp(self):
735 self.case = "unit set (number)"
736 self.values = [3]
737 self.set = set(self.values)
738 self.dup = set(self.values)
739 self.length = 1
740 self.repr = "set([3])"
741
742 def test_in(self):
743 self.failUnless(3 in self.set)
744
745 def test_not_in(self):
746 self.failUnless(2 not in self.set)
747
748#------------------------------------------------------------------------------
749
750class TestBasicOpsTuple(TestBasicOps):
751 def setUp(self):
752 self.case = "unit set (tuple)"
753 self.values = [(0, "zero")]
754 self.set = set(self.values)
755 self.dup = set(self.values)
756 self.length = 1
757 self.repr = "set([(0, 'zero')])"
758
759 def test_in(self):
760 self.failUnless((0, "zero") in self.set)
761
762 def test_not_in(self):
763 self.failUnless(9 not in self.set)
764
765#------------------------------------------------------------------------------
766
767class TestBasicOpsTriple(TestBasicOps):
768 def setUp(self):
769 self.case = "triple set"
770 self.values = [0, "zero", operator.add]
771 self.set = set(self.values)
772 self.dup = set(self.values)
773 self.length = 3
774 self.repr = None
775
776#==============================================================================
777
778def baditer():
779 raise TypeError
780 yield True
781
782def gooditer():
783 yield True
784
785class TestExceptionPropagation(unittest.TestCase):
786 """SF 628246: Set constructor should not trap iterator TypeErrors"""
787
788 def test_instanceWithException(self):
789 self.assertRaises(TypeError, set, baditer())
790
791 def test_instancesWithoutException(self):
792 # All of these iterables should load without exception.
793 set([1,2,3])
794 set((1,2,3))
795 set({'one':1, 'two':2, 'three':3})
796 set(xrange(3))
797 set('abc')
798 set(gooditer())
799
Neal Norwitzfcf44352005-11-27 20:37:43 +0000800 def test_changingSizeWhileIterating(self):
801 s = set([1,2,3])
802 try:
803 for i in s:
804 s.update([4])
805 except RuntimeError:
806 pass
807 else:
808 self.fail("no exception when changing size during iteration")
809
Raymond Hettingera690a992003-11-16 16:17:49 +0000810#==============================================================================
811
812class TestSetOfSets(unittest.TestCase):
813 def test_constructor(self):
814 inner = frozenset([1])
815 outer = set([inner])
816 element = outer.pop()
817 self.assertEqual(type(element), frozenset)
818 outer.add(inner) # Rebuild set of sets with .add method
819 outer.remove(inner)
820 self.assertEqual(outer, set()) # Verify that remove worked
821 outer.discard(inner) # Absence of KeyError indicates working fine
822
823#==============================================================================
824
825class TestBinaryOps(unittest.TestCase):
826 def setUp(self):
827 self.set = set((2, 4, 6))
828
829 def test_eq(self): # SF bug 643115
830 self.assertEqual(self.set, set({2:1,4:3,6:5}))
831
832 def test_union_subset(self):
833 result = self.set | set([2])
834 self.assertEqual(result, set((2, 4, 6)))
835
836 def test_union_superset(self):
837 result = self.set | set([2, 4, 6, 8])
838 self.assertEqual(result, set([2, 4, 6, 8]))
839
840 def test_union_overlap(self):
841 result = self.set | set([3, 4, 5])
842 self.assertEqual(result, set([2, 3, 4, 5, 6]))
843
844 def test_union_non_overlap(self):
845 result = self.set | set([8])
846 self.assertEqual(result, set([2, 4, 6, 8]))
847
848 def test_intersection_subset(self):
849 result = self.set & set((2, 4))
850 self.assertEqual(result, set((2, 4)))
851
852 def test_intersection_superset(self):
853 result = self.set & set([2, 4, 6, 8])
854 self.assertEqual(result, set([2, 4, 6]))
855
856 def test_intersection_overlap(self):
857 result = self.set & set([3, 4, 5])
858 self.assertEqual(result, set([4]))
859
860 def test_intersection_non_overlap(self):
861 result = self.set & set([8])
862 self.assertEqual(result, empty_set)
863
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000864 def test_isdisjoint_subset(self):
865 result = self.set.isdisjoint(set((2, 4)))
866 self.assertEqual(result, False)
867
868 def test_isdisjoint_superset(self):
869 result = self.set.isdisjoint(set([2, 4, 6, 8]))
870 self.assertEqual(result, False)
871
872 def test_isdisjoint_overlap(self):
873 result = self.set.isdisjoint(set([3, 4, 5]))
874 self.assertEqual(result, False)
875
876 def test_isdisjoint_non_overlap(self):
877 result = self.set.isdisjoint(set([8]))
878 self.assertEqual(result, True)
879
Raymond Hettingera690a992003-11-16 16:17:49 +0000880 def test_sym_difference_subset(self):
881 result = self.set ^ set((2, 4))
882 self.assertEqual(result, set([6]))
883
884 def test_sym_difference_superset(self):
885 result = self.set ^ set((2, 4, 6, 8))
886 self.assertEqual(result, set([8]))
887
888 def test_sym_difference_overlap(self):
889 result = self.set ^ set((3, 4, 5))
890 self.assertEqual(result, set([2, 3, 5, 6]))
891
892 def test_sym_difference_non_overlap(self):
893 result = self.set ^ set([8])
894 self.assertEqual(result, set([2, 4, 6, 8]))
895
896 def test_cmp(self):
897 a, b = set('a'), set('b')
898 self.assertRaises(TypeError, cmp, a, b)
899
900 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
901 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
902 # which Python thinks is good enough to synthesize a cmp() result
903 # without calling __cmp__.
904 self.assertEqual(cmp(a, a), 0)
905
906 self.assertRaises(TypeError, cmp, a, 12)
907 self.assertRaises(TypeError, cmp, "abc", a)
908
909#==============================================================================
910
911class TestUpdateOps(unittest.TestCase):
912 def setUp(self):
913 self.set = set((2, 4, 6))
914
915 def test_union_subset(self):
916 self.set |= set([2])
917 self.assertEqual(self.set, set((2, 4, 6)))
918
919 def test_union_superset(self):
920 self.set |= set([2, 4, 6, 8])
921 self.assertEqual(self.set, set([2, 4, 6, 8]))
922
923 def test_union_overlap(self):
924 self.set |= set([3, 4, 5])
925 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
926
927 def test_union_non_overlap(self):
928 self.set |= set([8])
929 self.assertEqual(self.set, set([2, 4, 6, 8]))
930
931 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000932 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +0000933 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
934
935 def test_intersection_subset(self):
936 self.set &= set((2, 4))
937 self.assertEqual(self.set, set((2, 4)))
938
939 def test_intersection_superset(self):
940 self.set &= set([2, 4, 6, 8])
941 self.assertEqual(self.set, set([2, 4, 6]))
942
943 def test_intersection_overlap(self):
944 self.set &= set([3, 4, 5])
945 self.assertEqual(self.set, set([4]))
946
947 def test_intersection_non_overlap(self):
948 self.set &= set([8])
949 self.assertEqual(self.set, empty_set)
950
951 def test_intersection_method_call(self):
952 self.set.intersection_update(set([3, 4, 5]))
953 self.assertEqual(self.set, set([4]))
954
955 def test_sym_difference_subset(self):
956 self.set ^= set((2, 4))
957 self.assertEqual(self.set, set([6]))
958
959 def test_sym_difference_superset(self):
960 self.set ^= set((2, 4, 6, 8))
961 self.assertEqual(self.set, set([8]))
962
963 def test_sym_difference_overlap(self):
964 self.set ^= set((3, 4, 5))
965 self.assertEqual(self.set, set([2, 3, 5, 6]))
966
967 def test_sym_difference_non_overlap(self):
968 self.set ^= set([8])
969 self.assertEqual(self.set, set([2, 4, 6, 8]))
970
971 def test_sym_difference_method_call(self):
972 self.set.symmetric_difference_update(set([3, 4, 5]))
973 self.assertEqual(self.set, set([2, 3, 5, 6]))
974
975 def test_difference_subset(self):
976 self.set -= set((2, 4))
977 self.assertEqual(self.set, set([6]))
978
979 def test_difference_superset(self):
980 self.set -= set((2, 4, 6, 8))
981 self.assertEqual(self.set, set([]))
982
983 def test_difference_overlap(self):
984 self.set -= set((3, 4, 5))
985 self.assertEqual(self.set, set([2, 6]))
986
987 def test_difference_non_overlap(self):
988 self.set -= set([8])
989 self.assertEqual(self.set, set([2, 4, 6]))
990
991 def test_difference_method_call(self):
992 self.set.difference_update(set([3, 4, 5]))
993 self.assertEqual(self.set, set([2, 6]))
994
995#==============================================================================
996
997class TestMutate(unittest.TestCase):
998 def setUp(self):
999 self.values = ["a", "b", "c"]
1000 self.set = set(self.values)
1001
1002 def test_add_present(self):
1003 self.set.add("c")
1004 self.assertEqual(self.set, set("abc"))
1005
1006 def test_add_absent(self):
1007 self.set.add("d")
1008 self.assertEqual(self.set, set("abcd"))
1009
1010 def test_add_until_full(self):
1011 tmp = set()
1012 expected_len = 0
1013 for v in self.values:
1014 tmp.add(v)
1015 expected_len += 1
1016 self.assertEqual(len(tmp), expected_len)
1017 self.assertEqual(tmp, self.set)
1018
1019 def test_remove_present(self):
1020 self.set.remove("b")
1021 self.assertEqual(self.set, set("ac"))
1022
1023 def test_remove_absent(self):
1024 try:
1025 self.set.remove("d")
1026 self.fail("Removing missing element should have raised LookupError")
1027 except LookupError:
1028 pass
1029
1030 def test_remove_until_empty(self):
1031 expected_len = len(self.set)
1032 for v in self.values:
1033 self.set.remove(v)
1034 expected_len -= 1
1035 self.assertEqual(len(self.set), expected_len)
1036
1037 def test_discard_present(self):
1038 self.set.discard("c")
1039 self.assertEqual(self.set, set("ab"))
1040
1041 def test_discard_absent(self):
1042 self.set.discard("d")
1043 self.assertEqual(self.set, set("abc"))
1044
1045 def test_clear(self):
1046 self.set.clear()
1047 self.assertEqual(len(self.set), 0)
1048
1049 def test_pop(self):
1050 popped = {}
1051 while self.set:
1052 popped[self.set.pop()] = None
1053 self.assertEqual(len(popped), len(self.values))
1054 for v in self.values:
1055 self.failUnless(v in popped)
1056
1057 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001058 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001059 self.assertEqual(self.set, set(self.values))
1060
1061 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001062 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001063 self.assertEqual(self.set, set(self.values))
1064
1065 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001066 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001067 self.assertEqual(self.set, set(self.values + ["z"]))
1068
1069#==============================================================================
1070
1071class TestSubsets(unittest.TestCase):
1072
1073 case2method = {"<=": "issubset",
1074 ">=": "issuperset",
1075 }
1076
1077 reverse = {"==": "==",
1078 "!=": "!=",
1079 "<": ">",
1080 ">": "<",
1081 "<=": ">=",
1082 ">=": "<=",
1083 }
1084
1085 def test_issubset(self):
1086 x = self.left
1087 y = self.right
1088 for case in "!=", "==", "<", "<=", ">", ">=":
1089 expected = case in self.cases
1090 # Test the binary infix spelling.
1091 result = eval("x" + case + "y", locals())
1092 self.assertEqual(result, expected)
1093 # Test the "friendly" method-name spelling, if one exists.
1094 if case in TestSubsets.case2method:
1095 method = getattr(x, TestSubsets.case2method[case])
1096 result = method(y)
1097 self.assertEqual(result, expected)
1098
1099 # Now do the same for the operands reversed.
1100 rcase = TestSubsets.reverse[case]
1101 result = eval("y" + rcase + "x", locals())
1102 self.assertEqual(result, expected)
1103 if rcase in TestSubsets.case2method:
1104 method = getattr(y, TestSubsets.case2method[rcase])
1105 result = method(x)
1106 self.assertEqual(result, expected)
1107#------------------------------------------------------------------------------
1108
1109class TestSubsetEqualEmpty(TestSubsets):
1110 left = set()
1111 right = set()
1112 name = "both empty"
1113 cases = "==", "<=", ">="
1114
1115#------------------------------------------------------------------------------
1116
1117class TestSubsetEqualNonEmpty(TestSubsets):
1118 left = set([1, 2])
1119 right = set([1, 2])
1120 name = "equal pair"
1121 cases = "==", "<=", ">="
1122
1123#------------------------------------------------------------------------------
1124
1125class TestSubsetEmptyNonEmpty(TestSubsets):
1126 left = set()
1127 right = set([1, 2])
1128 name = "one empty, one non-empty"
1129 cases = "!=", "<", "<="
1130
1131#------------------------------------------------------------------------------
1132
1133class TestSubsetPartial(TestSubsets):
1134 left = set([1])
1135 right = set([1, 2])
1136 name = "one a non-empty proper subset of other"
1137 cases = "!=", "<", "<="
1138
1139#------------------------------------------------------------------------------
1140
1141class TestSubsetNonOverlap(TestSubsets):
1142 left = set([1])
1143 right = set([2])
1144 name = "neither empty, neither contains"
1145 cases = "!="
1146
1147#==============================================================================
1148
1149class TestOnlySetsInBinaryOps(unittest.TestCase):
1150
1151 def test_eq_ne(self):
1152 # Unlike the others, this is testing that == and != *are* allowed.
1153 self.assertEqual(self.other == self.set, False)
1154 self.assertEqual(self.set == self.other, False)
1155 self.assertEqual(self.other != self.set, True)
1156 self.assertEqual(self.set != self.other, True)
1157
1158 def test_ge_gt_le_lt(self):
1159 self.assertRaises(TypeError, lambda: self.set < self.other)
1160 self.assertRaises(TypeError, lambda: self.set <= self.other)
1161 self.assertRaises(TypeError, lambda: self.set > self.other)
1162 self.assertRaises(TypeError, lambda: self.set >= self.other)
1163
1164 self.assertRaises(TypeError, lambda: self.other < self.set)
1165 self.assertRaises(TypeError, lambda: self.other <= self.set)
1166 self.assertRaises(TypeError, lambda: self.other > self.set)
1167 self.assertRaises(TypeError, lambda: self.other >= self.set)
1168
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001169 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001170 try:
1171 self.set |= self.other
1172 except TypeError:
1173 pass
1174 else:
1175 self.fail("expected TypeError")
1176
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001177 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001178 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001179 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001180 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001181 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001182
1183 def test_union(self):
1184 self.assertRaises(TypeError, lambda: self.set | self.other)
1185 self.assertRaises(TypeError, lambda: self.other | self.set)
1186 if self.otherIsIterable:
1187 self.set.union(self.other)
1188 else:
1189 self.assertRaises(TypeError, self.set.union, self.other)
1190
1191 def test_intersection_update_operator(self):
1192 try:
1193 self.set &= self.other
1194 except TypeError:
1195 pass
1196 else:
1197 self.fail("expected TypeError")
1198
1199 def test_intersection_update(self):
1200 if self.otherIsIterable:
1201 self.set.intersection_update(self.other)
1202 else:
1203 self.assertRaises(TypeError,
1204 self.set.intersection_update,
1205 self.other)
1206
1207 def test_intersection(self):
1208 self.assertRaises(TypeError, lambda: self.set & self.other)
1209 self.assertRaises(TypeError, lambda: self.other & self.set)
1210 if self.otherIsIterable:
1211 self.set.intersection(self.other)
1212 else:
1213 self.assertRaises(TypeError, self.set.intersection, self.other)
1214
1215 def test_sym_difference_update_operator(self):
1216 try:
1217 self.set ^= self.other
1218 except TypeError:
1219 pass
1220 else:
1221 self.fail("expected TypeError")
1222
1223 def test_sym_difference_update(self):
1224 if self.otherIsIterable:
1225 self.set.symmetric_difference_update(self.other)
1226 else:
1227 self.assertRaises(TypeError,
1228 self.set.symmetric_difference_update,
1229 self.other)
1230
1231 def test_sym_difference(self):
1232 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1233 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1234 if self.otherIsIterable:
1235 self.set.symmetric_difference(self.other)
1236 else:
1237 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1238
1239 def test_difference_update_operator(self):
1240 try:
1241 self.set -= self.other
1242 except TypeError:
1243 pass
1244 else:
1245 self.fail("expected TypeError")
1246
1247 def test_difference_update(self):
1248 if self.otherIsIterable:
1249 self.set.difference_update(self.other)
1250 else:
1251 self.assertRaises(TypeError,
1252 self.set.difference_update,
1253 self.other)
1254
1255 def test_difference(self):
1256 self.assertRaises(TypeError, lambda: self.set - self.other)
1257 self.assertRaises(TypeError, lambda: self.other - self.set)
1258 if self.otherIsIterable:
1259 self.set.difference(self.other)
1260 else:
1261 self.assertRaises(TypeError, self.set.difference, self.other)
1262
1263#------------------------------------------------------------------------------
1264
1265class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1266 def setUp(self):
1267 self.set = set((1, 2, 3))
1268 self.other = 19
1269 self.otherIsIterable = False
1270
1271#------------------------------------------------------------------------------
1272
1273class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1274 def setUp(self):
1275 self.set = set((1, 2, 3))
1276 self.other = {1:2, 3:4}
1277 self.otherIsIterable = True
1278
1279#------------------------------------------------------------------------------
1280
1281class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1282 def setUp(self):
1283 self.set = set((1, 2, 3))
1284 self.other = operator.add
1285 self.otherIsIterable = False
1286
1287#------------------------------------------------------------------------------
1288
1289class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1290 def setUp(self):
1291 self.set = set((1, 2, 3))
1292 self.other = (2, 4, 6)
1293 self.otherIsIterable = True
1294
1295#------------------------------------------------------------------------------
1296
1297class TestOnlySetsString(TestOnlySetsInBinaryOps):
1298 def setUp(self):
1299 self.set = set((1, 2, 3))
1300 self.other = 'abc'
1301 self.otherIsIterable = True
1302
1303#------------------------------------------------------------------------------
1304
1305class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1306 def setUp(self):
1307 def gen():
1308 for i in xrange(0, 10, 2):
1309 yield i
1310 self.set = set((1, 2, 3))
1311 self.other = gen()
1312 self.otherIsIterable = True
1313
1314#==============================================================================
1315
1316class TestCopying(unittest.TestCase):
1317
1318 def test_copy(self):
1319 dup = self.set.copy()
1320 dup_list = list(dup); dup_list.sort()
1321 set_list = list(self.set); set_list.sort()
1322 self.assertEqual(len(dup_list), len(set_list))
1323 for i in range(len(dup_list)):
1324 self.failUnless(dup_list[i] is set_list[i])
1325
1326 def test_deep_copy(self):
1327 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001328 ##print type(dup), repr(dup)
Raymond Hettingera690a992003-11-16 16:17:49 +00001329 dup_list = list(dup); dup_list.sort()
1330 set_list = list(self.set); set_list.sort()
1331 self.assertEqual(len(dup_list), len(set_list))
1332 for i in range(len(dup_list)):
1333 self.assertEqual(dup_list[i], set_list[i])
1334
1335#------------------------------------------------------------------------------
1336
1337class TestCopyingEmpty(TestCopying):
1338 def setUp(self):
1339 self.set = set()
1340
1341#------------------------------------------------------------------------------
1342
1343class TestCopyingSingleton(TestCopying):
1344 def setUp(self):
1345 self.set = set(["hello"])
1346
1347#------------------------------------------------------------------------------
1348
1349class TestCopyingTriple(TestCopying):
1350 def setUp(self):
1351 self.set = set(["zero", 0, None])
1352
1353#------------------------------------------------------------------------------
1354
1355class TestCopyingTuple(TestCopying):
1356 def setUp(self):
1357 self.set = set([(1, 2)])
1358
1359#------------------------------------------------------------------------------
1360
1361class TestCopyingNested(TestCopying):
1362 def setUp(self):
1363 self.set = set([((1, 2), (3, 4))])
1364
1365#==============================================================================
1366
1367class TestIdentities(unittest.TestCase):
1368 def setUp(self):
1369 self.a = set('abracadabra')
1370 self.b = set('alacazam')
1371
1372 def test_binopsVsSubsets(self):
1373 a, b = self.a, self.b
1374 self.assert_(a - b < a)
1375 self.assert_(b - a < b)
1376 self.assert_(a & b < a)
1377 self.assert_(a & b < b)
1378 self.assert_(a | b > a)
1379 self.assert_(a | b > b)
1380 self.assert_(a ^ b < a | b)
1381
1382 def test_commutativity(self):
1383 a, b = self.a, self.b
1384 self.assertEqual(a&b, b&a)
1385 self.assertEqual(a|b, b|a)
1386 self.assertEqual(a^b, b^a)
1387 if a != b:
1388 self.assertNotEqual(a-b, b-a)
1389
1390 def test_summations(self):
1391 # check that sums of parts equal the whole
1392 a, b = self.a, self.b
1393 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1394 self.assertEqual((a&b)|(a^b), a|b)
1395 self.assertEqual(a|(b-a), a|b)
1396 self.assertEqual((a-b)|b, a|b)
1397 self.assertEqual((a-b)|(a&b), a)
1398 self.assertEqual((b-a)|(a&b), b)
1399 self.assertEqual((a-b)|(b-a), a^b)
1400
1401 def test_exclusion(self):
1402 # check that inverse operations show non-overlap
1403 a, b, zero = self.a, self.b, set()
1404 self.assertEqual((a-b)&b, zero)
1405 self.assertEqual((b-a)&a, zero)
1406 self.assertEqual((a&b)&(a^b), zero)
1407
1408# Tests derived from test_itertools.py =======================================
1409
1410def R(seqn):
1411 'Regular generator'
1412 for i in seqn:
1413 yield i
1414
1415class G:
1416 'Sequence using __getitem__'
1417 def __init__(self, seqn):
1418 self.seqn = seqn
1419 def __getitem__(self, i):
1420 return self.seqn[i]
1421
1422class I:
1423 'Sequence using iterator protocol'
1424 def __init__(self, seqn):
1425 self.seqn = seqn
1426 self.i = 0
1427 def __iter__(self):
1428 return self
1429 def next(self):
1430 if self.i >= len(self.seqn): raise StopIteration
1431 v = self.seqn[self.i]
1432 self.i += 1
1433 return v
1434
1435class Ig:
1436 'Sequence using iterator protocol defined with a generator'
1437 def __init__(self, seqn):
1438 self.seqn = seqn
1439 self.i = 0
1440 def __iter__(self):
1441 for val in self.seqn:
1442 yield val
1443
1444class X:
1445 'Missing __getitem__ and __iter__'
1446 def __init__(self, seqn):
1447 self.seqn = seqn
1448 self.i = 0
1449 def next(self):
1450 if self.i >= len(self.seqn): raise StopIteration
1451 v = self.seqn[self.i]
1452 self.i += 1
1453 return v
1454
1455class N:
1456 'Iterator missing next()'
1457 def __init__(self, seqn):
1458 self.seqn = seqn
1459 self.i = 0
1460 def __iter__(self):
1461 return self
1462
1463class E:
1464 'Test propagation of exceptions'
1465 def __init__(self, seqn):
1466 self.seqn = seqn
1467 self.i = 0
1468 def __iter__(self):
1469 return self
1470 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001471 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001472
1473class S:
1474 'Test immediate stop'
1475 def __init__(self, seqn):
1476 pass
1477 def __iter__(self):
1478 return self
1479 def next(self):
1480 raise StopIteration
1481
1482from itertools import chain, imap
1483def L(seqn):
1484 'Test multiple tiers of iterators'
1485 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1486
1487class TestVariousIteratorArgs(unittest.TestCase):
1488
1489 def test_constructor(self):
1490 for cons in (set, frozenset):
1491 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1492 for g in (G, I, Ig, S, L, R):
Raymond Hettinger64958a12003-12-17 20:43:33 +00001493 self.assertEqual(sorted(cons(g(s))), sorted(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001494 self.assertRaises(TypeError, cons , X(s))
1495 self.assertRaises(TypeError, cons , N(s))
1496 self.assertRaises(ZeroDivisionError, cons , E(s))
1497
1498 def test_inline_methods(self):
1499 s = set('november')
1500 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001501 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001502 for g in (G, I, Ig, L, R):
1503 expected = meth(data)
1504 actual = meth(G(data))
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001505 if isinstance(expected, bool):
1506 self.assertEqual(actual, expected)
1507 else:
1508 self.assertEqual(sorted(actual), sorted(expected))
Raymond Hettingera690a992003-11-16 16:17:49 +00001509 self.assertRaises(TypeError, meth, X(s))
1510 self.assertRaises(TypeError, meth, N(s))
1511 self.assertRaises(ZeroDivisionError, meth, E(s))
1512
1513 def test_inplace_methods(self):
1514 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001515 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001516 'difference_update', 'symmetric_difference_update'):
1517 for g in (G, I, Ig, S, L, R):
1518 s = set('january')
1519 t = s.copy()
1520 getattr(s, methname)(list(g(data)))
1521 getattr(t, methname)(g(data))
Raymond Hettinger64958a12003-12-17 20:43:33 +00001522 self.assertEqual(sorted(s), sorted(t))
Raymond Hettingera690a992003-11-16 16:17:49 +00001523
1524 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1525 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1526 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1527
1528#==============================================================================
1529
1530def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001531 from test import test_sets
1532 test_classes = (
1533 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001534 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001535 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001536 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001537 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001538 TestSetOfSets,
1539 TestExceptionPropagation,
1540 TestBasicOpsEmpty,
1541 TestBasicOpsSingleton,
1542 TestBasicOpsTuple,
1543 TestBasicOpsTriple,
1544 TestBinaryOps,
1545 TestUpdateOps,
1546 TestMutate,
1547 TestSubsetEqualEmpty,
1548 TestSubsetEqualNonEmpty,
1549 TestSubsetEmptyNonEmpty,
1550 TestSubsetPartial,
1551 TestSubsetNonOverlap,
1552 TestOnlySetsNumeric,
1553 TestOnlySetsDict,
1554 TestOnlySetsOperator,
1555 TestOnlySetsTuple,
1556 TestOnlySetsString,
1557 TestOnlySetsGenerator,
1558 TestCopyingEmpty,
1559 TestCopyingSingleton,
1560 TestCopyingTriple,
1561 TestCopyingTuple,
1562 TestCopyingNested,
1563 TestIdentities,
1564 TestVariousIteratorArgs,
1565 )
1566
1567 test_support.run_unittest(*test_classes)
1568
1569 # verify reference counting
1570 if verbose and hasattr(sys, "gettotalrefcount"):
1571 import gc
1572 counts = [None] * 5
1573 for i in xrange(len(counts)):
1574 test_support.run_unittest(*test_classes)
1575 gc.collect()
1576 counts[i] = sys.gettotalrefcount()
1577 print counts
1578
1579if __name__ == "__main__":
1580 test_main(verbose=True)