blob: 610be7c4369ed850a18d0614de83de3c96213dbb [file] [log] [blame]
Raymond Hettinger35b76022010-04-18 22:57:57 +00001
Raymond Hettingera690a992003-11-16 16:17:49 +00002import unittest
3from test import test_support
Antoine Pitrouaa687902009-01-01 14:11:22 +00004import gc
5import weakref
Raymond Hettingera690a992003-11-16 16:17:49 +00006import operator
7import copy
8import pickle
Raymond Hettinger82cb9a22005-07-05 05:34:43 +00009from random import randrange, shuffle
Raymond Hettingerc47e01d2005-08-16 10:44:15 +000010import sys
Raymond Hettinger61708742008-01-24 21:23:58 +000011import collections
Raymond Hettingera690a992003-11-16 16:17:49 +000012
13class PassThru(Exception):
14 pass
15
16def check_pass_thru():
17 raise PassThru
18 yield 1
19
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000020class BadCmp:
21 def __hash__(self):
22 return 1
23 def __cmp__(self, other):
24 raise RuntimeError
25
Raymond Hettinger53999102006-12-30 04:01:17 +000026class ReprWrapper:
27 'Used to test self-referential repr() calls'
28 def __repr__(self):
29 return repr(self.value)
30
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +000031class HashCountingInt(int):
32 'int-like object that counts the number of times __hash__ is called'
33 def __init__(self, *args):
34 self.hash_count = 0
35 def __hash__(self):
36 self.hash_count += 1
37 return int.__hash__(self)
38
Raymond Hettingera690a992003-11-16 16:17:49 +000039class TestJointOps(unittest.TestCase):
40 # Tests common to both set and frozenset
41
42 def setUp(self):
43 self.word = word = 'simsalabim'
44 self.otherword = 'madagascar'
45 self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
46 self.s = self.thetype(word)
47 self.d = dict.fromkeys(word)
48
Raymond Hettinger6429a472004-09-28 01:51:35 +000049 def test_new_or_init(self):
50 self.assertRaises(TypeError, self.thetype, [], 2)
Raymond Hettinger35b76022010-04-18 22:57:57 +000051 self.assertRaises(TypeError, set().__init__, a=1)
Raymond Hettinger6429a472004-09-28 01:51:35 +000052
Raymond Hettingera690a992003-11-16 16:17:49 +000053 def test_uniquification(self):
Raymond Hettinger64958a12003-12-17 20:43:33 +000054 actual = sorted(self.s)
55 expected = sorted(self.d)
Raymond Hettingera690a992003-11-16 16:17:49 +000056 self.assertEqual(actual, expected)
57 self.assertRaises(PassThru, self.thetype, check_pass_thru())
58 self.assertRaises(TypeError, self.thetype, [[]])
59
60 def test_len(self):
61 self.assertEqual(len(self.s), len(self.d))
62
63 def test_contains(self):
64 for c in self.letters:
65 self.assertEqual(c in self.s, c in self.d)
66 self.assertRaises(TypeError, self.s.__contains__, [[]])
Raymond Hettinger19c2d772003-11-21 18:36:54 +000067 s = self.thetype([frozenset(self.letters)])
Ezio Melottiaa980582010-01-23 23:04:36 +000068 self.assertIn(self.thetype(self.letters), s)
Raymond Hettingera690a992003-11-16 16:17:49 +000069
Raymond Hettingera690a992003-11-16 16:17:49 +000070 def test_union(self):
71 u = self.s.union(self.otherword)
72 for c in self.letters:
73 self.assertEqual(c in u, c in self.d or c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000074 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000075 self.assertEqual(type(u), self.thetype)
76 self.assertRaises(PassThru, self.s.union, check_pass_thru())
77 self.assertRaises(TypeError, self.s.union, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000078 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
79 self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
80 self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
81 self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
82 self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +000083 self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
Raymond Hettingera690a992003-11-16 16:17:49 +000084
Raymond Hettingerc2b9e1a2009-07-27 20:32:04 +000085 # Issue #6573
86 x = self.thetype()
87 self.assertEqual(x.union(set([1]), x, set([2])), self.thetype([1, 2]))
88
Raymond Hettingera690a992003-11-16 16:17:49 +000089 def test_or(self):
90 i = self.s.union(self.otherword)
91 self.assertEqual(self.s | set(self.otherword), i)
92 self.assertEqual(self.s | frozenset(self.otherword), i)
93 try:
94 self.s | self.otherword
95 except TypeError:
96 pass
97 else:
98 self.fail("s|t did not screen-out general iterables")
99
100 def test_intersection(self):
101 i = self.s.intersection(self.otherword)
102 for c in self.letters:
103 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000104 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000105 self.assertEqual(type(i), self.thetype)
106 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000107 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
108 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
109 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
110 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
111 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000112 self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
Raymond Hettinger610a93e2008-06-11 00:44:47 +0000113 s = self.thetype('abcba')
114 z = s.intersection()
115 if self.thetype == frozenset():
116 self.assertEqual(id(s), id(z))
117 else:
118 self.assertNotEqual(id(s), id(z))
Raymond Hettingera690a992003-11-16 16:17:49 +0000119
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000120 def test_isdisjoint(self):
121 def f(s1, s2):
122 'Pure python equivalent of isdisjoint()'
123 return not set(s1).intersection(s2)
124 for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
125 s1 = self.thetype(larg)
126 for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
127 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
128 s2 = C(rarg)
129 actual = s1.isdisjoint(s2)
130 expected = f(s1, s2)
131 self.assertEqual(actual, expected)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000132 self.assertTrue(actual is True or actual is False)
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000133
Raymond Hettingera690a992003-11-16 16:17:49 +0000134 def test_and(self):
135 i = self.s.intersection(self.otherword)
136 self.assertEqual(self.s & set(self.otherword), i)
137 self.assertEqual(self.s & frozenset(self.otherword), i)
138 try:
139 self.s & self.otherword
140 except TypeError:
141 pass
142 else:
143 self.fail("s&t did not screen-out general iterables")
144
145 def test_difference(self):
146 i = self.s.difference(self.otherword)
147 for c in self.letters:
148 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000149 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000150 self.assertEqual(type(i), self.thetype)
151 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
152 self.assertRaises(TypeError, self.s.difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000153 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
154 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
155 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
156 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
157 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettinger4267be62008-06-11 10:30:54 +0000158 self.assertEqual(self.thetype('abcba').difference(), set('abc'))
159 self.assertEqual(self.thetype('abcba').difference(C('a'), C('b')), set('c'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000160
161 def test_sub(self):
162 i = self.s.difference(self.otherword)
163 self.assertEqual(self.s - set(self.otherword), i)
164 self.assertEqual(self.s - frozenset(self.otherword), i)
165 try:
166 self.s - self.otherword
167 except TypeError:
168 pass
169 else:
170 self.fail("s-t did not screen-out general iterables")
171
172 def test_symmetric_difference(self):
173 i = self.s.symmetric_difference(self.otherword)
174 for c in self.letters:
175 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000176 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000177 self.assertEqual(type(i), self.thetype)
178 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
179 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000180 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
181 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
182 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
183 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
184 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000185
186 def test_xor(self):
187 i = self.s.symmetric_difference(self.otherword)
188 self.assertEqual(self.s ^ set(self.otherword), i)
189 self.assertEqual(self.s ^ frozenset(self.otherword), i)
190 try:
191 self.s ^ self.otherword
192 except TypeError:
193 pass
194 else:
195 self.fail("s^t did not screen-out general iterables")
196
197 def test_equality(self):
198 self.assertEqual(self.s, set(self.word))
199 self.assertEqual(self.s, frozenset(self.word))
200 self.assertEqual(self.s == self.word, False)
201 self.assertNotEqual(self.s, set(self.otherword))
202 self.assertNotEqual(self.s, frozenset(self.otherword))
203 self.assertEqual(self.s != self.word, True)
204
205 def test_setOfFrozensets(self):
206 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
207 s = self.thetype(t)
208 self.assertEqual(len(s), 3)
209
210 def test_compare(self):
211 self.assertRaises(TypeError, self.s.__cmp__, self.s)
212
213 def test_sub_and_super(self):
214 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000215 self.assertTrue(p < q)
216 self.assertTrue(p <= q)
217 self.assertTrue(q <= q)
218 self.assertTrue(q > p)
219 self.assertTrue(q >= p)
220 self.assertFalse(q < r)
221 self.assertFalse(q <= r)
222 self.assertFalse(q > r)
223 self.assertFalse(q >= r)
224 self.assertTrue(set('a').issubset('abc'))
225 self.assertTrue(set('abc').issuperset('a'))
226 self.assertFalse(set('a').issubset('cbs'))
227 self.assertFalse(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000228
229 def test_pickling(self):
Hirokazu Yamamoto0fc07472008-12-27 04:19:48 +0000230 for i in range(pickle.HIGHEST_PROTOCOL + 1):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000231 p = pickle.dumps(self.s, i)
232 dup = pickle.loads(p)
233 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
234 if type(self.s) not in (set, frozenset):
235 self.s.x = 10
236 p = pickle.dumps(self.s)
237 dup = pickle.loads(p)
238 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000239
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000240 def test_deepcopy(self):
241 class Tracer:
242 def __init__(self, value):
243 self.value = value
244 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000245 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000246 def __deepcopy__(self, memo=None):
247 return Tracer(self.value + 1)
248 t = Tracer(10)
249 s = self.thetype([t])
250 dup = copy.deepcopy(s)
251 self.assertNotEqual(id(s), id(dup))
252 for elem in dup:
253 newt = elem
254 self.assertNotEqual(id(t), id(newt))
255 self.assertEqual(t.value + 1, newt.value)
256
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000257 def test_gc(self):
258 # Create a nest of cycles to exercise overall ref count check
259 class A:
260 pass
261 s = set(A() for i in xrange(1000))
262 for elem in s:
263 elem.cycle = s
264 elem.sub = elem
265 elem.set = set([elem])
266
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000267 def test_subclass_with_custom_hash(self):
268 # Bug #1257731
269 class H(self.thetype):
270 def __hash__(self):
Tim Peters6902b442006-04-11 00:43:27 +0000271 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000272 s=H()
273 f=set()
274 f.add(s)
Ezio Melottiaa980582010-01-23 23:04:36 +0000275 self.assertIn(s, f)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000276 f.remove(s)
277 f.add(s)
278 f.discard(s)
279
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000280 def test_badcmp(self):
281 s = self.thetype([BadCmp()])
282 # Detect comparison errors during insertion and lookup
283 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
284 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
285 # Detect errors during mutating operations
286 if hasattr(s, 'add'):
287 self.assertRaises(RuntimeError, s.add, BadCmp())
288 self.assertRaises(RuntimeError, s.discard, BadCmp())
289 self.assertRaises(RuntimeError, s.remove, BadCmp())
290
Raymond Hettinger53999102006-12-30 04:01:17 +0000291 def test_cyclical_repr(self):
292 w = ReprWrapper()
293 s = self.thetype([w])
294 w.value = s
295 name = repr(s).partition('(')[0] # strip class name from repr string
296 self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
297
298 def test_cyclical_print(self):
299 w = ReprWrapper()
300 s = self.thetype([w])
301 w.value = s
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000302 fo = open(test_support.TESTFN, "wb")
Raymond Hettinger53999102006-12-30 04:01:17 +0000303 try:
Raymond Hettinger53999102006-12-30 04:01:17 +0000304 print >> fo, s,
305 fo.close()
306 fo = open(test_support.TESTFN, "rb")
307 self.assertEqual(fo.read(), repr(s))
308 finally:
309 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000310 test_support.unlink(test_support.TESTFN)
Raymond Hettinger53999102006-12-30 04:01:17 +0000311
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000312 def test_do_not_rehash_dict_keys(self):
313 n = 10
314 d = dict.fromkeys(map(HashCountingInt, xrange(n)))
315 self.assertEqual(sum(elem.hash_count for elem in d), n)
316 s = self.thetype(d)
317 self.assertEqual(sum(elem.hash_count for elem in d), n)
318 s.difference(d)
Tim Petersea5962f2007-03-12 18:07:52 +0000319 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000320 if hasattr(s, 'symmetric_difference_update'):
321 s.symmetric_difference_update(d)
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000322 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettinger0bbbfc42007-03-20 21:27:24 +0000323 d2 = dict.fromkeys(set(d))
324 self.assertEqual(sum(elem.hash_count for elem in d), n)
325 d3 = dict.fromkeys(frozenset(d))
Tim Petersea5962f2007-03-12 18:07:52 +0000326 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingere3146f52007-03-21 20:33:57 +0000327 d3 = dict.fromkeys(frozenset(d), 123)
328 self.assertEqual(sum(elem.hash_count for elem in d), n)
329 self.assertEqual(d3, dict.fromkeys(d, 123))
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000330
Antoine Pitrouaa687902009-01-01 14:11:22 +0000331 def test_container_iterator(self):
Antoine Pitrou733dc742009-01-01 15:38:03 +0000332 # Bug #3680: tp_traverse was not implemented for set iterator object
Antoine Pitrouaa687902009-01-01 14:11:22 +0000333 class C(object):
334 pass
335 obj = C()
336 ref = weakref.ref(obj)
337 container = set([obj, 1])
338 obj.x = iter(container)
339 del obj, container
340 gc.collect()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000341 self.assertTrue(ref() is None, "Cycle was not collected")
Antoine Pitrouaa687902009-01-01 14:11:22 +0000342
Raymond Hettingera690a992003-11-16 16:17:49 +0000343class TestSet(TestJointOps):
344 thetype = set
345
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000346 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000347 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000348 s.__init__(self.word)
349 self.assertEqual(s, set(self.word))
350 s.__init__(self.otherword)
351 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000352 self.assertRaises(TypeError, s.__init__, s, 2);
353 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000354
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000355 def test_constructor_identity(self):
356 s = self.thetype(range(3))
357 t = self.thetype(s)
358 self.assertNotEqual(id(s), id(t))
359
Raymond Hettingera690a992003-11-16 16:17:49 +0000360 def test_hash(self):
361 self.assertRaises(TypeError, hash, self.s)
362
363 def test_clear(self):
364 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000365 self.assertEqual(self.s, set())
366 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000367
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000368 def test_copy(self):
369 dup = self.s.copy()
370 self.assertEqual(self.s, dup)
371 self.assertNotEqual(id(self.s), id(dup))
372
Raymond Hettingera690a992003-11-16 16:17:49 +0000373 def test_add(self):
374 self.s.add('Q')
Ezio Melottiaa980582010-01-23 23:04:36 +0000375 self.assertIn('Q', self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000376 dup = self.s.copy()
377 self.s.add('Q')
378 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000379 self.assertRaises(TypeError, self.s.add, [])
380
381 def test_remove(self):
382 self.s.remove('a')
Ezio Melottiaa980582010-01-23 23:04:36 +0000383 self.assertNotIn('a', self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000384 self.assertRaises(KeyError, self.s.remove, 'Q')
385 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000386 s = self.thetype([frozenset(self.word)])
Ezio Melottiaa980582010-01-23 23:04:36 +0000387 self.assertIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000388 s.remove(self.thetype(self.word))
Ezio Melottiaa980582010-01-23 23:04:36 +0000389 self.assertNotIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000390 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000391
Raymond Hettingerc789f342006-12-08 17:35:25 +0000392 def test_remove_keyerror_unpacking(self):
393 # bug: www.python.org/sf/1576657
394 for v1 in ['Q', (1,)]:
395 try:
396 self.s.remove(v1)
397 except KeyError, e:
398 v2 = e.args[0]
399 self.assertEqual(v1, v2)
400 else:
401 self.fail()
402
Amaury Forgeot d'Arcd78b9dc2008-10-07 20:32:10 +0000403 def test_remove_keyerror_set(self):
404 key = self.thetype([3, 4])
405 try:
406 self.s.remove(key)
407 except KeyError as e:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000408 self.assertTrue(e.args[0] is key,
Amaury Forgeot d'Arcd78b9dc2008-10-07 20:32:10 +0000409 "KeyError should be {0}, not {1}".format(key,
410 e.args[0]))
411 else:
412 self.fail()
413
Raymond Hettingera690a992003-11-16 16:17:49 +0000414 def test_discard(self):
415 self.s.discard('a')
Ezio Melottiaa980582010-01-23 23:04:36 +0000416 self.assertNotIn('a', self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000417 self.s.discard('Q')
418 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000419 s = self.thetype([frozenset(self.word)])
Ezio Melottiaa980582010-01-23 23:04:36 +0000420 self.assertIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000421 s.discard(self.thetype(self.word))
Ezio Melottiaa980582010-01-23 23:04:36 +0000422 self.assertNotIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000423 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000424
425 def test_pop(self):
426 for i in xrange(len(self.s)):
427 elem = self.s.pop()
Ezio Melottiaa980582010-01-23 23:04:36 +0000428 self.assertNotIn(elem, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000429 self.assertRaises(KeyError, self.s.pop)
430
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000431 def test_update(self):
432 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000433 self.assertEqual(retval, None)
434 for c in (self.word + self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000435 self.assertIn(c, self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000436 self.assertRaises(PassThru, self.s.update, check_pass_thru())
437 self.assertRaises(TypeError, self.s.update, [[]])
438 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
439 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
440 s = self.thetype('abcba')
441 self.assertEqual(s.update(C(p)), None)
442 self.assertEqual(s, set(q))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +0000443 for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
444 q = 'ahi'
445 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
446 s = self.thetype('abcba')
447 self.assertEqual(s.update(C(p), C(q)), None)
448 self.assertEqual(s, set(s) | set(p) | set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000449
450 def test_ior(self):
451 self.s |= set(self.otherword)
452 for c in (self.word + self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000453 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000454
455 def test_intersection_update(self):
456 retval = self.s.intersection_update(self.otherword)
457 self.assertEqual(retval, None)
458 for c in (self.word + self.otherword):
459 if c in self.otherword and c in self.word:
Ezio Melottiaa980582010-01-23 23:04:36 +0000460 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000461 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000462 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000463 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
464 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000465 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
466 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
467 s = self.thetype('abcba')
468 self.assertEqual(s.intersection_update(C(p)), None)
469 self.assertEqual(s, set(q))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000470 ss = 'abcba'
471 s = self.thetype(ss)
472 t = 'cbc'
473 self.assertEqual(s.intersection_update(C(p), C(t)), None)
474 self.assertEqual(s, set('abcba')&set(p)&set(t))
Raymond Hettingera690a992003-11-16 16:17:49 +0000475
476 def test_iand(self):
477 self.s &= set(self.otherword)
478 for c in (self.word + self.otherword):
479 if c in self.otherword and c in self.word:
Ezio Melottiaa980582010-01-23 23:04:36 +0000480 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000481 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000482 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000483
484 def test_difference_update(self):
485 retval = self.s.difference_update(self.otherword)
486 self.assertEqual(retval, None)
487 for c in (self.word + self.otherword):
488 if c in self.word and c not in self.otherword:
Ezio Melottiaa980582010-01-23 23:04:36 +0000489 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000490 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000491 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000492 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
493 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000494 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
495 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
496 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
497 s = self.thetype('abcba')
498 self.assertEqual(s.difference_update(C(p)), None)
499 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000500
Raymond Hettinger4267be62008-06-11 10:30:54 +0000501 s = self.thetype('abcdefghih')
502 s.difference_update()
503 self.assertEqual(s, self.thetype('abcdefghih'))
504
505 s = self.thetype('abcdefghih')
506 s.difference_update(C('aba'))
507 self.assertEqual(s, self.thetype('cdefghih'))
508
509 s = self.thetype('abcdefghih')
510 s.difference_update(C('cdc'), C('aba'))
511 self.assertEqual(s, self.thetype('efghih'))
512
Raymond Hettingera690a992003-11-16 16:17:49 +0000513 def test_isub(self):
514 self.s -= set(self.otherword)
515 for c in (self.word + self.otherword):
516 if c in self.word and c not in self.otherword:
Ezio Melottiaa980582010-01-23 23:04:36 +0000517 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000518 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000519 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000520
521 def test_symmetric_difference_update(self):
522 retval = self.s.symmetric_difference_update(self.otherword)
523 self.assertEqual(retval, None)
524 for c in (self.word + self.otherword):
525 if (c in self.word) ^ (c in self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000526 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000527 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000528 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000529 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
530 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000531 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
532 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
533 s = self.thetype('abcba')
534 self.assertEqual(s.symmetric_difference_update(C(p)), None)
535 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000536
537 def test_ixor(self):
538 self.s ^= set(self.otherword)
539 for c in (self.word + self.otherword):
540 if (c in self.word) ^ (c in self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000541 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000542 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000543 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000544
Raymond Hettingerc991db22005-08-11 07:58:45 +0000545 def test_inplace_on_self(self):
546 t = self.s.copy()
547 t |= t
548 self.assertEqual(t, self.s)
549 t &= t
550 self.assertEqual(t, self.s)
551 t -= t
552 self.assertEqual(t, self.thetype())
553 t = self.s.copy()
554 t ^= t
555 self.assertEqual(t, self.thetype())
556
Raymond Hettinger691d8052004-05-30 07:26:47 +0000557 def test_weakref(self):
558 s = self.thetype('gallahad')
Antoine Pitrouaa687902009-01-01 14:11:22 +0000559 p = weakref.proxy(s)
Raymond Hettinger691d8052004-05-30 07:26:47 +0000560 self.assertEqual(str(p), str(s))
561 s = None
562 self.assertRaises(ReferenceError, str, p)
563
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200564 @unittest.skipUnless(hasattr(set, "test_c_api"),
565 'C API test only available in a debug build')
566 def test_c_api(self):
567 self.assertEqual(set().test_c_api(), True)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000568
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000569class SetSubclass(set):
570 pass
571
572class TestSetSubclass(TestSet):
573 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000574
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000575class SetSubclassWithKeywordArgs(set):
576 def __init__(self, iterable=[], newarg=None):
577 set.__init__(self, iterable)
578
579class TestSetSubclassWithKeywordArgs(TestSet):
Tim Petersf733abb2007-01-30 03:03:46 +0000580
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000581 def test_keywords_in_subclass(self):
582 'SF bug #1486663 -- this used to erroneously raise a TypeError'
583 SetSubclassWithKeywordArgs(newarg=1)
584
Raymond Hettingera690a992003-11-16 16:17:49 +0000585class TestFrozenSet(TestJointOps):
586 thetype = frozenset
587
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000588 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000589 s = self.thetype(self.word)
590 s.__init__(self.otherword)
591 self.assertEqual(s, set(self.word))
592
Raymond Hettingerd7946662005-08-01 21:39:29 +0000593 def test_singleton_empty_frozenset(self):
594 f = frozenset()
595 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
596 frozenset(), frozenset([]), frozenset(()), frozenset(''),
597 frozenset(xrange(0)), frozenset(frozenset()),
598 frozenset(f), f]
599 # All of the empty frozensets should have just one id()
600 self.assertEqual(len(set(map(id, efs))), 1)
601
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000602 def test_constructor_identity(self):
603 s = self.thetype(range(3))
604 t = self.thetype(s)
605 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000606
Raymond Hettingera690a992003-11-16 16:17:49 +0000607 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000608 self.assertEqual(hash(self.thetype('abcdeb')),
609 hash(self.thetype('ebecda')))
610
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000611 # make sure that all permutations give the same hash value
612 n = 100
613 seq = [randrange(n) for i in xrange(n)]
614 results = set()
615 for i in xrange(200):
616 shuffle(seq)
617 results.add(hash(self.thetype(seq)))
618 self.assertEqual(len(results), 1)
619
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000620 def test_copy(self):
621 dup = self.s.copy()
622 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000623
624 def test_frozen_as_dictkey(self):
625 seq = range(10) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000626 key1 = self.thetype(seq)
627 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000628 self.assertEqual(key1, key2)
629 self.assertNotEqual(id(key1), id(key2))
630 d = {}
631 d[key1] = 42
632 self.assertEqual(d[key2], 42)
633
634 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000635 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000636 self.assertEqual(hash(f), hash(f))
637
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000638 def test_hash_effectiveness(self):
639 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000640 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000641 addhashvalue = hashvalues.add
642 elemmasks = [(i+1, 1<<i) for i in range(n)]
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000643 for i in xrange(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000644 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
645 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000646
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000647class FrozenSetSubclass(frozenset):
648 pass
649
650class TestFrozenSetSubclass(TestFrozenSet):
651 thetype = FrozenSetSubclass
652
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000653 def test_constructor_identity(self):
654 s = self.thetype(range(3))
655 t = self.thetype(s)
656 self.assertNotEqual(id(s), id(t))
657
658 def test_copy(self):
659 dup = self.s.copy()
660 self.assertNotEqual(id(self.s), id(dup))
661
662 def test_nested_empty_constructor(self):
663 s = self.thetype()
664 t = self.thetype(s)
665 self.assertEqual(s, t)
666
Raymond Hettingerd7946662005-08-01 21:39:29 +0000667 def test_singleton_empty_frozenset(self):
668 Frozenset = self.thetype
669 f = frozenset()
670 F = Frozenset()
671 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
672 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
673 Frozenset(xrange(0)), Frozenset(Frozenset()),
674 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
675 # All empty frozenset subclass instances should have different ids
676 self.assertEqual(len(set(map(id, efs))), len(efs))
677
Raymond Hettingera690a992003-11-16 16:17:49 +0000678# Tests taken from test_sets.py =============================================
679
680empty_set = set()
681
682#==============================================================================
683
684class TestBasicOps(unittest.TestCase):
685
686 def test_repr(self):
687 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000688 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000689
Barry Warsaw1e13eb02012-02-20 20:42:21 -0500690 def check_repr_against_values(self):
691 text = repr(self.set)
692 self.assertTrue(text.startswith('{'))
693 self.assertTrue(text.endswith('}'))
694
695 result = text[1:-1].split(', ')
696 result.sort()
697 sorted_repr_values = [repr(value) for value in self.values]
698 sorted_repr_values.sort()
699 self.assertEqual(result, sorted_repr_values)
700
Raymond Hettingereae05de2004-07-09 04:51:24 +0000701 def test_print(self):
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000702 fo = open(test_support.TESTFN, "wb")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000703 try:
Raymond Hettingereae05de2004-07-09 04:51:24 +0000704 print >> fo, self.set,
705 fo.close()
706 fo = open(test_support.TESTFN, "rb")
707 self.assertEqual(fo.read(), repr(self.set))
708 finally:
709 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000710 test_support.unlink(test_support.TESTFN)
Raymond Hettingereae05de2004-07-09 04:51:24 +0000711
Raymond Hettingera690a992003-11-16 16:17:49 +0000712 def test_length(self):
713 self.assertEqual(len(self.set), self.length)
714
715 def test_self_equality(self):
716 self.assertEqual(self.set, self.set)
717
718 def test_equivalent_equality(self):
719 self.assertEqual(self.set, self.dup)
720
721 def test_copy(self):
722 self.assertEqual(self.set.copy(), self.dup)
723
724 def test_self_union(self):
725 result = self.set | self.set
726 self.assertEqual(result, self.dup)
727
728 def test_empty_union(self):
729 result = self.set | empty_set
730 self.assertEqual(result, self.dup)
731
732 def test_union_empty(self):
733 result = empty_set | self.set
734 self.assertEqual(result, self.dup)
735
736 def test_self_intersection(self):
737 result = self.set & self.set
738 self.assertEqual(result, self.dup)
739
740 def test_empty_intersection(self):
741 result = self.set & empty_set
742 self.assertEqual(result, empty_set)
743
744 def test_intersection_empty(self):
745 result = empty_set & self.set
746 self.assertEqual(result, empty_set)
747
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000748 def test_self_isdisjoint(self):
749 result = self.set.isdisjoint(self.set)
750 self.assertEqual(result, not self.set)
751
752 def test_empty_isdisjoint(self):
753 result = self.set.isdisjoint(empty_set)
754 self.assertEqual(result, True)
755
756 def test_isdisjoint_empty(self):
757 result = empty_set.isdisjoint(self.set)
758 self.assertEqual(result, True)
759
Raymond Hettingera690a992003-11-16 16:17:49 +0000760 def test_self_symmetric_difference(self):
761 result = self.set ^ self.set
762 self.assertEqual(result, empty_set)
763
Georg Brandl0347c712010-08-01 19:02:09 +0000764 def test_empty_symmetric_difference(self):
Raymond Hettingera690a992003-11-16 16:17:49 +0000765 result = self.set ^ empty_set
766 self.assertEqual(result, self.set)
767
768 def test_self_difference(self):
769 result = self.set - self.set
770 self.assertEqual(result, empty_set)
771
772 def test_empty_difference(self):
773 result = self.set - empty_set
774 self.assertEqual(result, self.dup)
775
776 def test_empty_difference_rev(self):
777 result = empty_set - self.set
778 self.assertEqual(result, empty_set)
779
780 def test_iteration(self):
781 for v in self.set:
Ezio Melottiaa980582010-01-23 23:04:36 +0000782 self.assertIn(v, self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000783 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000784 # note: __length_hint__ is an internal undocumented API,
785 # don't rely on it in your own programs
786 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000787
788 def test_pickling(self):
789 p = pickle.dumps(self.set)
790 copy = pickle.loads(p)
791 self.assertEqual(self.set, copy,
792 "%s != %s" % (self.set, copy))
793
794#------------------------------------------------------------------------------
795
796class TestBasicOpsEmpty(TestBasicOps):
797 def setUp(self):
798 self.case = "empty set"
799 self.values = []
800 self.set = set(self.values)
801 self.dup = set(self.values)
802 self.length = 0
803 self.repr = "set([])"
804
805#------------------------------------------------------------------------------
806
807class TestBasicOpsSingleton(TestBasicOps):
808 def setUp(self):
809 self.case = "unit set (number)"
810 self.values = [3]
811 self.set = set(self.values)
812 self.dup = set(self.values)
813 self.length = 1
814 self.repr = "set([3])"
815
816 def test_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000817 self.assertIn(3, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000818
819 def test_not_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000820 self.assertNotIn(2, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000821
822#------------------------------------------------------------------------------
823
824class TestBasicOpsTuple(TestBasicOps):
825 def setUp(self):
826 self.case = "unit set (tuple)"
827 self.values = [(0, "zero")]
828 self.set = set(self.values)
829 self.dup = set(self.values)
830 self.length = 1
831 self.repr = "set([(0, 'zero')])"
832
833 def test_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000834 self.assertIn((0, "zero"), self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000835
836 def test_not_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000837 self.assertNotIn(9, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000838
839#------------------------------------------------------------------------------
840
841class TestBasicOpsTriple(TestBasicOps):
842 def setUp(self):
843 self.case = "triple set"
844 self.values = [0, "zero", operator.add]
845 self.set = set(self.values)
846 self.dup = set(self.values)
847 self.length = 3
848 self.repr = None
849
Barry Warsaw1e13eb02012-02-20 20:42:21 -0500850#------------------------------------------------------------------------------
851
852class TestBasicOpsString(TestBasicOps):
853 def setUp(self):
854 self.case = "string set"
855 self.values = ["a", "b", "c"]
856 self.set = set(self.values)
857 self.dup = set(self.values)
858 self.length = 3
859
860 def test_repr(self):
861 self.check_repr_against_values()
862
863#------------------------------------------------------------------------------
864
865class TestBasicOpsUnicode(TestBasicOps):
866 def setUp(self):
867 self.case = "unicode set"
868 self.values = [u"a", u"b", u"c"]
869 self.set = set(self.values)
870 self.dup = set(self.values)
871 self.length = 3
872
873 def test_repr(self):
874 self.check_repr_against_values()
875
876#------------------------------------------------------------------------------
877
878class TestBasicOpsMixedStringUnicode(TestBasicOps):
879 def setUp(self):
880 self.case = "string and bytes set"
881 self.values = ["a", "b", u"a", u"b"]
882 self.set = set(self.values)
883 self.dup = set(self.values)
884 self.length = 4
885
886 def test_repr(self):
887 with test_support.check_warnings():
888 self.check_repr_against_values()
889
Raymond Hettingera690a992003-11-16 16:17:49 +0000890#==============================================================================
891
892def baditer():
893 raise TypeError
894 yield True
895
896def gooditer():
897 yield True
898
899class TestExceptionPropagation(unittest.TestCase):
900 """SF 628246: Set constructor should not trap iterator TypeErrors"""
901
902 def test_instanceWithException(self):
903 self.assertRaises(TypeError, set, baditer())
904
905 def test_instancesWithoutException(self):
906 # All of these iterables should load without exception.
907 set([1,2,3])
908 set((1,2,3))
909 set({'one':1, 'two':2, 'three':3})
910 set(xrange(3))
911 set('abc')
912 set(gooditer())
913
Neal Norwitzfcf44352005-11-27 20:37:43 +0000914 def test_changingSizeWhileIterating(self):
915 s = set([1,2,3])
916 try:
917 for i in s:
918 s.update([4])
919 except RuntimeError:
920 pass
921 else:
922 self.fail("no exception when changing size during iteration")
923
Raymond Hettingera690a992003-11-16 16:17:49 +0000924#==============================================================================
925
926class TestSetOfSets(unittest.TestCase):
927 def test_constructor(self):
928 inner = frozenset([1])
929 outer = set([inner])
930 element = outer.pop()
931 self.assertEqual(type(element), frozenset)
932 outer.add(inner) # Rebuild set of sets with .add method
933 outer.remove(inner)
934 self.assertEqual(outer, set()) # Verify that remove worked
935 outer.discard(inner) # Absence of KeyError indicates working fine
936
937#==============================================================================
938
939class TestBinaryOps(unittest.TestCase):
940 def setUp(self):
941 self.set = set((2, 4, 6))
942
943 def test_eq(self): # SF bug 643115
944 self.assertEqual(self.set, set({2:1,4:3,6:5}))
945
946 def test_union_subset(self):
947 result = self.set | set([2])
948 self.assertEqual(result, set((2, 4, 6)))
949
950 def test_union_superset(self):
951 result = self.set | set([2, 4, 6, 8])
952 self.assertEqual(result, set([2, 4, 6, 8]))
953
954 def test_union_overlap(self):
955 result = self.set | set([3, 4, 5])
956 self.assertEqual(result, set([2, 3, 4, 5, 6]))
957
958 def test_union_non_overlap(self):
959 result = self.set | set([8])
960 self.assertEqual(result, set([2, 4, 6, 8]))
961
962 def test_intersection_subset(self):
963 result = self.set & set((2, 4))
964 self.assertEqual(result, set((2, 4)))
965
966 def test_intersection_superset(self):
967 result = self.set & set([2, 4, 6, 8])
968 self.assertEqual(result, set([2, 4, 6]))
969
970 def test_intersection_overlap(self):
971 result = self.set & set([3, 4, 5])
972 self.assertEqual(result, set([4]))
973
974 def test_intersection_non_overlap(self):
975 result = self.set & set([8])
976 self.assertEqual(result, empty_set)
977
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000978 def test_isdisjoint_subset(self):
979 result = self.set.isdisjoint(set((2, 4)))
980 self.assertEqual(result, False)
981
982 def test_isdisjoint_superset(self):
983 result = self.set.isdisjoint(set([2, 4, 6, 8]))
984 self.assertEqual(result, False)
985
986 def test_isdisjoint_overlap(self):
987 result = self.set.isdisjoint(set([3, 4, 5]))
988 self.assertEqual(result, False)
989
990 def test_isdisjoint_non_overlap(self):
991 result = self.set.isdisjoint(set([8]))
992 self.assertEqual(result, True)
993
Raymond Hettingera690a992003-11-16 16:17:49 +0000994 def test_sym_difference_subset(self):
995 result = self.set ^ set((2, 4))
996 self.assertEqual(result, set([6]))
997
998 def test_sym_difference_superset(self):
999 result = self.set ^ set((2, 4, 6, 8))
1000 self.assertEqual(result, set([8]))
1001
1002 def test_sym_difference_overlap(self):
1003 result = self.set ^ set((3, 4, 5))
1004 self.assertEqual(result, set([2, 3, 5, 6]))
1005
1006 def test_sym_difference_non_overlap(self):
1007 result = self.set ^ set([8])
1008 self.assertEqual(result, set([2, 4, 6, 8]))
1009
1010 def test_cmp(self):
1011 a, b = set('a'), set('b')
1012 self.assertRaises(TypeError, cmp, a, b)
1013
1014 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
1015 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
1016 # which Python thinks is good enough to synthesize a cmp() result
1017 # without calling __cmp__.
1018 self.assertEqual(cmp(a, a), 0)
1019
Raymond Hettingera690a992003-11-16 16:17:49 +00001020
1021#==============================================================================
1022
1023class TestUpdateOps(unittest.TestCase):
1024 def setUp(self):
1025 self.set = set((2, 4, 6))
1026
1027 def test_union_subset(self):
1028 self.set |= set([2])
1029 self.assertEqual(self.set, set((2, 4, 6)))
1030
1031 def test_union_superset(self):
1032 self.set |= set([2, 4, 6, 8])
1033 self.assertEqual(self.set, set([2, 4, 6, 8]))
1034
1035 def test_union_overlap(self):
1036 self.set |= set([3, 4, 5])
1037 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1038
1039 def test_union_non_overlap(self):
1040 self.set |= set([8])
1041 self.assertEqual(self.set, set([2, 4, 6, 8]))
1042
1043 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001044 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +00001045 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1046
1047 def test_intersection_subset(self):
1048 self.set &= set((2, 4))
1049 self.assertEqual(self.set, set((2, 4)))
1050
1051 def test_intersection_superset(self):
1052 self.set &= set([2, 4, 6, 8])
1053 self.assertEqual(self.set, set([2, 4, 6]))
1054
1055 def test_intersection_overlap(self):
1056 self.set &= set([3, 4, 5])
1057 self.assertEqual(self.set, set([4]))
1058
1059 def test_intersection_non_overlap(self):
1060 self.set &= set([8])
1061 self.assertEqual(self.set, empty_set)
1062
1063 def test_intersection_method_call(self):
1064 self.set.intersection_update(set([3, 4, 5]))
1065 self.assertEqual(self.set, set([4]))
1066
1067 def test_sym_difference_subset(self):
1068 self.set ^= set((2, 4))
1069 self.assertEqual(self.set, set([6]))
1070
1071 def test_sym_difference_superset(self):
1072 self.set ^= set((2, 4, 6, 8))
1073 self.assertEqual(self.set, set([8]))
1074
1075 def test_sym_difference_overlap(self):
1076 self.set ^= set((3, 4, 5))
1077 self.assertEqual(self.set, set([2, 3, 5, 6]))
1078
1079 def test_sym_difference_non_overlap(self):
1080 self.set ^= set([8])
1081 self.assertEqual(self.set, set([2, 4, 6, 8]))
1082
1083 def test_sym_difference_method_call(self):
1084 self.set.symmetric_difference_update(set([3, 4, 5]))
1085 self.assertEqual(self.set, set([2, 3, 5, 6]))
1086
1087 def test_difference_subset(self):
1088 self.set -= set((2, 4))
1089 self.assertEqual(self.set, set([6]))
1090
1091 def test_difference_superset(self):
1092 self.set -= set((2, 4, 6, 8))
1093 self.assertEqual(self.set, set([]))
1094
1095 def test_difference_overlap(self):
1096 self.set -= set((3, 4, 5))
1097 self.assertEqual(self.set, set([2, 6]))
1098
1099 def test_difference_non_overlap(self):
1100 self.set -= set([8])
1101 self.assertEqual(self.set, set([2, 4, 6]))
1102
1103 def test_difference_method_call(self):
1104 self.set.difference_update(set([3, 4, 5]))
1105 self.assertEqual(self.set, set([2, 6]))
1106
1107#==============================================================================
1108
1109class TestMutate(unittest.TestCase):
1110 def setUp(self):
1111 self.values = ["a", "b", "c"]
1112 self.set = set(self.values)
1113
1114 def test_add_present(self):
1115 self.set.add("c")
1116 self.assertEqual(self.set, set("abc"))
1117
1118 def test_add_absent(self):
1119 self.set.add("d")
1120 self.assertEqual(self.set, set("abcd"))
1121
1122 def test_add_until_full(self):
1123 tmp = set()
1124 expected_len = 0
1125 for v in self.values:
1126 tmp.add(v)
1127 expected_len += 1
1128 self.assertEqual(len(tmp), expected_len)
1129 self.assertEqual(tmp, self.set)
1130
1131 def test_remove_present(self):
1132 self.set.remove("b")
1133 self.assertEqual(self.set, set("ac"))
1134
1135 def test_remove_absent(self):
1136 try:
1137 self.set.remove("d")
1138 self.fail("Removing missing element should have raised LookupError")
1139 except LookupError:
1140 pass
1141
1142 def test_remove_until_empty(self):
1143 expected_len = len(self.set)
1144 for v in self.values:
1145 self.set.remove(v)
1146 expected_len -= 1
1147 self.assertEqual(len(self.set), expected_len)
1148
1149 def test_discard_present(self):
1150 self.set.discard("c")
1151 self.assertEqual(self.set, set("ab"))
1152
1153 def test_discard_absent(self):
1154 self.set.discard("d")
1155 self.assertEqual(self.set, set("abc"))
1156
1157 def test_clear(self):
1158 self.set.clear()
1159 self.assertEqual(len(self.set), 0)
1160
1161 def test_pop(self):
1162 popped = {}
1163 while self.set:
1164 popped[self.set.pop()] = None
1165 self.assertEqual(len(popped), len(self.values))
1166 for v in self.values:
Ezio Melottiaa980582010-01-23 23:04:36 +00001167 self.assertIn(v, popped)
Raymond Hettingera690a992003-11-16 16:17:49 +00001168
1169 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001170 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001171 self.assertEqual(self.set, set(self.values))
1172
1173 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001174 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001175 self.assertEqual(self.set, set(self.values))
1176
1177 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001178 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001179 self.assertEqual(self.set, set(self.values + ["z"]))
1180
1181#==============================================================================
1182
1183class TestSubsets(unittest.TestCase):
1184
1185 case2method = {"<=": "issubset",
1186 ">=": "issuperset",
1187 }
1188
1189 reverse = {"==": "==",
1190 "!=": "!=",
1191 "<": ">",
1192 ">": "<",
1193 "<=": ">=",
1194 ">=": "<=",
1195 }
1196
1197 def test_issubset(self):
1198 x = self.left
1199 y = self.right
1200 for case in "!=", "==", "<", "<=", ">", ">=":
1201 expected = case in self.cases
1202 # Test the binary infix spelling.
1203 result = eval("x" + case + "y", locals())
1204 self.assertEqual(result, expected)
1205 # Test the "friendly" method-name spelling, if one exists.
1206 if case in TestSubsets.case2method:
1207 method = getattr(x, TestSubsets.case2method[case])
1208 result = method(y)
1209 self.assertEqual(result, expected)
1210
1211 # Now do the same for the operands reversed.
1212 rcase = TestSubsets.reverse[case]
1213 result = eval("y" + rcase + "x", locals())
1214 self.assertEqual(result, expected)
1215 if rcase in TestSubsets.case2method:
1216 method = getattr(y, TestSubsets.case2method[rcase])
1217 result = method(x)
1218 self.assertEqual(result, expected)
1219#------------------------------------------------------------------------------
1220
1221class TestSubsetEqualEmpty(TestSubsets):
1222 left = set()
1223 right = set()
1224 name = "both empty"
1225 cases = "==", "<=", ">="
1226
1227#------------------------------------------------------------------------------
1228
1229class TestSubsetEqualNonEmpty(TestSubsets):
1230 left = set([1, 2])
1231 right = set([1, 2])
1232 name = "equal pair"
1233 cases = "==", "<=", ">="
1234
1235#------------------------------------------------------------------------------
1236
1237class TestSubsetEmptyNonEmpty(TestSubsets):
1238 left = set()
1239 right = set([1, 2])
1240 name = "one empty, one non-empty"
1241 cases = "!=", "<", "<="
1242
1243#------------------------------------------------------------------------------
1244
1245class TestSubsetPartial(TestSubsets):
1246 left = set([1])
1247 right = set([1, 2])
1248 name = "one a non-empty proper subset of other"
1249 cases = "!=", "<", "<="
1250
1251#------------------------------------------------------------------------------
1252
1253class TestSubsetNonOverlap(TestSubsets):
1254 left = set([1])
1255 right = set([2])
1256 name = "neither empty, neither contains"
1257 cases = "!="
1258
1259#==============================================================================
1260
1261class TestOnlySetsInBinaryOps(unittest.TestCase):
1262
1263 def test_eq_ne(self):
1264 # Unlike the others, this is testing that == and != *are* allowed.
1265 self.assertEqual(self.other == self.set, False)
1266 self.assertEqual(self.set == self.other, False)
1267 self.assertEqual(self.other != self.set, True)
1268 self.assertEqual(self.set != self.other, True)
1269
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001270 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001271 try:
1272 self.set |= self.other
1273 except TypeError:
1274 pass
1275 else:
1276 self.fail("expected TypeError")
1277
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001278 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001279 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001280 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001281 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001282 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001283
1284 def test_union(self):
1285 self.assertRaises(TypeError, lambda: self.set | self.other)
1286 self.assertRaises(TypeError, lambda: self.other | self.set)
1287 if self.otherIsIterable:
1288 self.set.union(self.other)
1289 else:
1290 self.assertRaises(TypeError, self.set.union, self.other)
1291
1292 def test_intersection_update_operator(self):
1293 try:
1294 self.set &= self.other
1295 except TypeError:
1296 pass
1297 else:
1298 self.fail("expected TypeError")
1299
1300 def test_intersection_update(self):
1301 if self.otherIsIterable:
1302 self.set.intersection_update(self.other)
1303 else:
1304 self.assertRaises(TypeError,
1305 self.set.intersection_update,
1306 self.other)
1307
1308 def test_intersection(self):
1309 self.assertRaises(TypeError, lambda: self.set & self.other)
1310 self.assertRaises(TypeError, lambda: self.other & self.set)
1311 if self.otherIsIterable:
1312 self.set.intersection(self.other)
1313 else:
1314 self.assertRaises(TypeError, self.set.intersection, self.other)
1315
1316 def test_sym_difference_update_operator(self):
1317 try:
1318 self.set ^= self.other
1319 except TypeError:
1320 pass
1321 else:
1322 self.fail("expected TypeError")
1323
1324 def test_sym_difference_update(self):
1325 if self.otherIsIterable:
1326 self.set.symmetric_difference_update(self.other)
1327 else:
1328 self.assertRaises(TypeError,
1329 self.set.symmetric_difference_update,
1330 self.other)
1331
1332 def test_sym_difference(self):
1333 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1334 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1335 if self.otherIsIterable:
1336 self.set.symmetric_difference(self.other)
1337 else:
1338 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1339
1340 def test_difference_update_operator(self):
1341 try:
1342 self.set -= self.other
1343 except TypeError:
1344 pass
1345 else:
1346 self.fail("expected TypeError")
1347
1348 def test_difference_update(self):
1349 if self.otherIsIterable:
1350 self.set.difference_update(self.other)
1351 else:
1352 self.assertRaises(TypeError,
1353 self.set.difference_update,
1354 self.other)
1355
1356 def test_difference(self):
1357 self.assertRaises(TypeError, lambda: self.set - self.other)
1358 self.assertRaises(TypeError, lambda: self.other - self.set)
1359 if self.otherIsIterable:
1360 self.set.difference(self.other)
1361 else:
1362 self.assertRaises(TypeError, self.set.difference, self.other)
1363
1364#------------------------------------------------------------------------------
1365
1366class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1367 def setUp(self):
1368 self.set = set((1, 2, 3))
1369 self.other = 19
1370 self.otherIsIterable = False
1371
1372#------------------------------------------------------------------------------
1373
1374class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1375 def setUp(self):
1376 self.set = set((1, 2, 3))
1377 self.other = {1:2, 3:4}
1378 self.otherIsIterable = True
1379
1380#------------------------------------------------------------------------------
1381
Raymond Hettingera690a992003-11-16 16:17:49 +00001382class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1383 def setUp(self):
1384 self.set = set((1, 2, 3))
1385 self.other = (2, 4, 6)
1386 self.otherIsIterable = True
1387
1388#------------------------------------------------------------------------------
1389
1390class TestOnlySetsString(TestOnlySetsInBinaryOps):
1391 def setUp(self):
1392 self.set = set((1, 2, 3))
1393 self.other = 'abc'
1394 self.otherIsIterable = True
1395
1396#------------------------------------------------------------------------------
1397
1398class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1399 def setUp(self):
1400 def gen():
1401 for i in xrange(0, 10, 2):
1402 yield i
1403 self.set = set((1, 2, 3))
1404 self.other = gen()
1405 self.otherIsIterable = True
1406
1407#==============================================================================
1408
1409class TestCopying(unittest.TestCase):
1410
1411 def test_copy(self):
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001412 dup = list(self.set.copy())
1413 self.assertEqual(len(dup), len(self.set))
1414 for el in self.set:
1415 self.assertIn(el, dup)
1416 pos = dup.index(el)
1417 self.assertIs(el, dup.pop(pos))
1418 self.assertFalse(dup)
Raymond Hettingera690a992003-11-16 16:17:49 +00001419
1420 def test_deep_copy(self):
1421 dup = copy.deepcopy(self.set)
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001422 self.assertSetEqual(dup, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +00001423
1424#------------------------------------------------------------------------------
1425
1426class TestCopyingEmpty(TestCopying):
1427 def setUp(self):
1428 self.set = set()
1429
1430#------------------------------------------------------------------------------
1431
1432class TestCopyingSingleton(TestCopying):
1433 def setUp(self):
1434 self.set = set(["hello"])
1435
1436#------------------------------------------------------------------------------
1437
1438class TestCopyingTriple(TestCopying):
1439 def setUp(self):
1440 self.set = set(["zero", 0, None])
1441
1442#------------------------------------------------------------------------------
1443
1444class TestCopyingTuple(TestCopying):
1445 def setUp(self):
1446 self.set = set([(1, 2)])
1447
1448#------------------------------------------------------------------------------
1449
1450class TestCopyingNested(TestCopying):
1451 def setUp(self):
1452 self.set = set([((1, 2), (3, 4))])
1453
1454#==============================================================================
1455
1456class TestIdentities(unittest.TestCase):
1457 def setUp(self):
1458 self.a = set('abracadabra')
1459 self.b = set('alacazam')
1460
1461 def test_binopsVsSubsets(self):
1462 a, b = self.a, self.b
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001463 self.assertTrue(a - b < a)
1464 self.assertTrue(b - a < b)
1465 self.assertTrue(a & b < a)
1466 self.assertTrue(a & b < b)
1467 self.assertTrue(a | b > a)
1468 self.assertTrue(a | b > b)
1469 self.assertTrue(a ^ b < a | b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001470
1471 def test_commutativity(self):
1472 a, b = self.a, self.b
1473 self.assertEqual(a&b, b&a)
1474 self.assertEqual(a|b, b|a)
1475 self.assertEqual(a^b, b^a)
1476 if a != b:
1477 self.assertNotEqual(a-b, b-a)
1478
1479 def test_summations(self):
1480 # check that sums of parts equal the whole
1481 a, b = self.a, self.b
1482 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1483 self.assertEqual((a&b)|(a^b), a|b)
1484 self.assertEqual(a|(b-a), a|b)
1485 self.assertEqual((a-b)|b, a|b)
1486 self.assertEqual((a-b)|(a&b), a)
1487 self.assertEqual((b-a)|(a&b), b)
1488 self.assertEqual((a-b)|(b-a), a^b)
1489
1490 def test_exclusion(self):
1491 # check that inverse operations show non-overlap
1492 a, b, zero = self.a, self.b, set()
1493 self.assertEqual((a-b)&b, zero)
1494 self.assertEqual((b-a)&a, zero)
1495 self.assertEqual((a&b)&(a^b), zero)
1496
1497# Tests derived from test_itertools.py =======================================
1498
1499def R(seqn):
1500 'Regular generator'
1501 for i in seqn:
1502 yield i
1503
1504class G:
1505 'Sequence using __getitem__'
1506 def __init__(self, seqn):
1507 self.seqn = seqn
1508 def __getitem__(self, i):
1509 return self.seqn[i]
1510
1511class I:
1512 'Sequence using iterator protocol'
1513 def __init__(self, seqn):
1514 self.seqn = seqn
1515 self.i = 0
1516 def __iter__(self):
1517 return self
1518 def next(self):
1519 if self.i >= len(self.seqn): raise StopIteration
1520 v = self.seqn[self.i]
1521 self.i += 1
1522 return v
1523
1524class Ig:
1525 'Sequence using iterator protocol defined with a generator'
1526 def __init__(self, seqn):
1527 self.seqn = seqn
1528 self.i = 0
1529 def __iter__(self):
1530 for val in self.seqn:
1531 yield val
1532
1533class X:
1534 'Missing __getitem__ and __iter__'
1535 def __init__(self, seqn):
1536 self.seqn = seqn
1537 self.i = 0
1538 def next(self):
1539 if self.i >= len(self.seqn): raise StopIteration
1540 v = self.seqn[self.i]
1541 self.i += 1
1542 return v
1543
1544class N:
1545 'Iterator missing next()'
1546 def __init__(self, seqn):
1547 self.seqn = seqn
1548 self.i = 0
1549 def __iter__(self):
1550 return self
1551
1552class E:
1553 'Test propagation of exceptions'
1554 def __init__(self, seqn):
1555 self.seqn = seqn
1556 self.i = 0
1557 def __iter__(self):
1558 return self
1559 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001560 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001561
1562class S:
1563 'Test immediate stop'
1564 def __init__(self, seqn):
1565 pass
1566 def __iter__(self):
1567 return self
1568 def next(self):
1569 raise StopIteration
1570
1571from itertools import chain, imap
1572def L(seqn):
1573 'Test multiple tiers of iterators'
1574 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1575
1576class TestVariousIteratorArgs(unittest.TestCase):
1577
1578 def test_constructor(self):
1579 for cons in (set, frozenset):
1580 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1581 for g in (G, I, Ig, S, L, R):
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001582 self.assertSetEqual(cons(g(s)), set(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001583 self.assertRaises(TypeError, cons , X(s))
1584 self.assertRaises(TypeError, cons , N(s))
1585 self.assertRaises(ZeroDivisionError, cons , E(s))
1586
1587 def test_inline_methods(self):
1588 s = set('november')
1589 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001590 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001591 for g in (G, I, Ig, L, R):
1592 expected = meth(data)
Terry Jan Reedy807c9da2014-04-26 13:55:59 -04001593 actual = meth(g(data))
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001594 if isinstance(expected, bool):
1595 self.assertEqual(actual, expected)
1596 else:
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001597 self.assertSetEqual(actual, expected)
Raymond Hettingera690a992003-11-16 16:17:49 +00001598 self.assertRaises(TypeError, meth, X(s))
1599 self.assertRaises(TypeError, meth, N(s))
1600 self.assertRaises(ZeroDivisionError, meth, E(s))
1601
1602 def test_inplace_methods(self):
1603 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001604 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001605 'difference_update', 'symmetric_difference_update'):
1606 for g in (G, I, Ig, S, L, R):
1607 s = set('january')
1608 t = s.copy()
1609 getattr(s, methname)(list(g(data)))
1610 getattr(t, methname)(g(data))
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001611 self.assertSetEqual(s, t)
Raymond Hettingera690a992003-11-16 16:17:49 +00001612
1613 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1614 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1615 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1616
Éric Araujof079c9b2011-03-22 23:47:32 +01001617class bad_eq:
1618 def __eq__(self, other):
1619 if be_bad:
1620 set2.clear()
1621 raise ZeroDivisionError
1622 return self is other
1623 def __hash__(self):
1624 return 0
1625
1626class bad_dict_clear:
1627 def __eq__(self, other):
1628 if be_bad:
1629 dict2.clear()
1630 return self is other
1631 def __hash__(self):
1632 return 0
1633
1634class TestWeirdBugs(unittest.TestCase):
1635 def test_8420_set_merge(self):
1636 # This used to segfault
1637 global be_bad, set2, dict2
1638 be_bad = False
1639 set1 = {bad_eq()}
1640 set2 = {bad_eq() for i in range(75)}
1641 be_bad = True
1642 self.assertRaises(ZeroDivisionError, set1.update, set2)
1643
1644 be_bad = False
1645 set1 = {bad_dict_clear()}
1646 dict2 = {bad_dict_clear(): None}
1647 be_bad = True
1648 set1.symmetric_difference_update(dict2)
1649
Raymond Hettinger61708742008-01-24 21:23:58 +00001650# Application tests (based on David Eppstein's graph recipes ====================================
1651
1652def powerset(U):
1653 """Generates all subsets of a set or sequence U."""
1654 U = iter(U)
1655 try:
1656 x = frozenset([U.next()])
1657 for S in powerset(U):
1658 yield S
1659 yield S | x
1660 except StopIteration:
1661 yield frozenset()
1662
1663def cube(n):
1664 """Graph of n-dimensional hypercube."""
1665 singletons = [frozenset([x]) for x in range(n)]
1666 return dict([(x, frozenset([x^s for s in singletons]))
1667 for x in powerset(range(n))])
1668
1669def linegraph(G):
1670 """Graph, the vertices of which are edges of G,
1671 with two vertices being adjacent iff the corresponding
1672 edges share a vertex."""
1673 L = {}
1674 for x in G:
1675 for y in G[x]:
1676 nx = [frozenset([x,z]) for z in G[x] if z != y]
1677 ny = [frozenset([y,z]) for z in G[y] if z != x]
1678 L[frozenset([x,y])] = frozenset(nx+ny)
1679 return L
1680
1681def faces(G):
1682 'Return a set of faces in G. Where a face is a set of vertices on that face'
1683 # currently limited to triangles,squares, and pentagons
1684 f = set()
1685 for v1, edges in G.items():
1686 for v2 in edges:
1687 for v3 in G[v2]:
1688 if v1 == v3:
1689 continue
1690 if v1 in G[v3]:
1691 f.add(frozenset([v1, v2, v3]))
1692 else:
1693 for v4 in G[v3]:
1694 if v4 == v2:
1695 continue
1696 if v1 in G[v4]:
1697 f.add(frozenset([v1, v2, v3, v4]))
1698 else:
1699 for v5 in G[v4]:
1700 if v5 == v3 or v5 == v2:
1701 continue
1702 if v1 in G[v5]:
1703 f.add(frozenset([v1, v2, v3, v4, v5]))
1704 return f
1705
1706
1707class TestGraphs(unittest.TestCase):
1708
1709 def test_cube(self):
1710
1711 g = cube(3) # vert --> {v1, v2, v3}
1712 vertices1 = set(g)
1713 self.assertEqual(len(vertices1), 8) # eight vertices
1714 for edge in g.values():
1715 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1716 vertices2 = set(v for edges in g.values() for v in edges)
1717 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1718
1719 cubefaces = faces(g)
1720 self.assertEqual(len(cubefaces), 6) # six faces
1721 for face in cubefaces:
1722 self.assertEqual(len(face), 4) # each face is a square
1723
1724 def test_cuboctahedron(self):
1725
1726 # http://en.wikipedia.org/wiki/Cuboctahedron
1727 # 8 triangular faces and 6 square faces
1728 # 12 indentical vertices each connecting a triangle and square
1729
1730 g = cube(3)
1731 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1732 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1733
1734 vertices = set(cuboctahedron)
1735 for edges in cuboctahedron.values():
1736 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1737 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1738 self.assertEqual(vertices, othervertices) # edge vertices in original set
1739
1740 cubofaces = faces(cuboctahedron)
1741 facesizes = collections.defaultdict(int)
1742 for face in cubofaces:
1743 facesizes[len(face)] += 1
1744 self.assertEqual(facesizes[3], 8) # eight triangular faces
1745 self.assertEqual(facesizes[4], 6) # six square faces
1746
1747 for vertex in cuboctahedron:
1748 edge = vertex # Cuboctahedron vertices are edges in Cube
1749 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1750 for cubevert in edge:
Ezio Melottiaa980582010-01-23 23:04:36 +00001751 self.assertIn(cubevert, g)
Raymond Hettinger61708742008-01-24 21:23:58 +00001752
1753
Raymond Hettingera690a992003-11-16 16:17:49 +00001754#==============================================================================
1755
1756def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001757 test_classes = (
1758 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001759 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001760 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001761 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001762 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001763 TestSetOfSets,
1764 TestExceptionPropagation,
1765 TestBasicOpsEmpty,
1766 TestBasicOpsSingleton,
1767 TestBasicOpsTuple,
1768 TestBasicOpsTriple,
1769 TestBinaryOps,
1770 TestUpdateOps,
1771 TestMutate,
1772 TestSubsetEqualEmpty,
1773 TestSubsetEqualNonEmpty,
1774 TestSubsetEmptyNonEmpty,
1775 TestSubsetPartial,
1776 TestSubsetNonOverlap,
1777 TestOnlySetsNumeric,
1778 TestOnlySetsDict,
Raymond Hettingera690a992003-11-16 16:17:49 +00001779 TestOnlySetsTuple,
1780 TestOnlySetsString,
1781 TestOnlySetsGenerator,
1782 TestCopyingEmpty,
1783 TestCopyingSingleton,
1784 TestCopyingTriple,
1785 TestCopyingTuple,
1786 TestCopyingNested,
1787 TestIdentities,
1788 TestVariousIteratorArgs,
Raymond Hettinger61708742008-01-24 21:23:58 +00001789 TestGraphs,
Éric Araujof079c9b2011-03-22 23:47:32 +01001790 TestWeirdBugs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001791 )
1792
1793 test_support.run_unittest(*test_classes)
1794
1795 # verify reference counting
1796 if verbose and hasattr(sys, "gettotalrefcount"):
1797 import gc
1798 counts = [None] * 5
1799 for i in xrange(len(counts)):
1800 test_support.run_unittest(*test_classes)
1801 gc.collect()
1802 counts[i] = sys.gettotalrefcount()
1803 print counts
1804
1805if __name__ == "__main__":
1806 test_main(verbose=True)