blob: dd652023ee2adac2c96e5a23c308025f44296a3c [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
Serhiy Storchaka655720e2014-12-15 14:02:43 +0200236 p = pickle.dumps(self.s, i)
Raymond Hettinger15056a52004-11-09 07:25:31 +0000237 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):
Serhiy Storchaka655720e2014-12-15 14:02:43 +0200789 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
790 p = pickle.dumps(self.set, proto)
791 copy = pickle.loads(p)
792 self.assertEqual(self.set, copy,
793 "%s != %s" % (self.set, copy))
Raymond Hettingera690a992003-11-16 16:17:49 +0000794
795#------------------------------------------------------------------------------
796
797class TestBasicOpsEmpty(TestBasicOps):
798 def setUp(self):
799 self.case = "empty set"
800 self.values = []
801 self.set = set(self.values)
802 self.dup = set(self.values)
803 self.length = 0
804 self.repr = "set([])"
805
806#------------------------------------------------------------------------------
807
808class TestBasicOpsSingleton(TestBasicOps):
809 def setUp(self):
810 self.case = "unit set (number)"
811 self.values = [3]
812 self.set = set(self.values)
813 self.dup = set(self.values)
814 self.length = 1
815 self.repr = "set([3])"
816
817 def test_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000818 self.assertIn(3, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000819
820 def test_not_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000821 self.assertNotIn(2, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000822
823#------------------------------------------------------------------------------
824
825class TestBasicOpsTuple(TestBasicOps):
826 def setUp(self):
827 self.case = "unit set (tuple)"
828 self.values = [(0, "zero")]
829 self.set = set(self.values)
830 self.dup = set(self.values)
831 self.length = 1
832 self.repr = "set([(0, 'zero')])"
833
834 def test_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000835 self.assertIn((0, "zero"), self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000836
837 def test_not_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000838 self.assertNotIn(9, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000839
840#------------------------------------------------------------------------------
841
842class TestBasicOpsTriple(TestBasicOps):
843 def setUp(self):
844 self.case = "triple set"
845 self.values = [0, "zero", operator.add]
846 self.set = set(self.values)
847 self.dup = set(self.values)
848 self.length = 3
849 self.repr = None
850
Barry Warsaw1e13eb02012-02-20 20:42:21 -0500851#------------------------------------------------------------------------------
852
853class TestBasicOpsString(TestBasicOps):
854 def setUp(self):
855 self.case = "string set"
856 self.values = ["a", "b", "c"]
857 self.set = set(self.values)
858 self.dup = set(self.values)
859 self.length = 3
860
861 def test_repr(self):
862 self.check_repr_against_values()
863
864#------------------------------------------------------------------------------
865
866class TestBasicOpsUnicode(TestBasicOps):
867 def setUp(self):
868 self.case = "unicode set"
869 self.values = [u"a", u"b", u"c"]
870 self.set = set(self.values)
871 self.dup = set(self.values)
872 self.length = 3
873
874 def test_repr(self):
875 self.check_repr_against_values()
876
877#------------------------------------------------------------------------------
878
879class TestBasicOpsMixedStringUnicode(TestBasicOps):
880 def setUp(self):
881 self.case = "string and bytes set"
882 self.values = ["a", "b", u"a", u"b"]
883 self.set = set(self.values)
884 self.dup = set(self.values)
885 self.length = 4
886
887 def test_repr(self):
888 with test_support.check_warnings():
889 self.check_repr_against_values()
890
Raymond Hettingera690a992003-11-16 16:17:49 +0000891#==============================================================================
892
893def baditer():
894 raise TypeError
895 yield True
896
897def gooditer():
898 yield True
899
900class TestExceptionPropagation(unittest.TestCase):
901 """SF 628246: Set constructor should not trap iterator TypeErrors"""
902
903 def test_instanceWithException(self):
904 self.assertRaises(TypeError, set, baditer())
905
906 def test_instancesWithoutException(self):
907 # All of these iterables should load without exception.
908 set([1,2,3])
909 set((1,2,3))
910 set({'one':1, 'two':2, 'three':3})
911 set(xrange(3))
912 set('abc')
913 set(gooditer())
914
Neal Norwitzfcf44352005-11-27 20:37:43 +0000915 def test_changingSizeWhileIterating(self):
916 s = set([1,2,3])
917 try:
918 for i in s:
919 s.update([4])
920 except RuntimeError:
921 pass
922 else:
923 self.fail("no exception when changing size during iteration")
924
Raymond Hettingera690a992003-11-16 16:17:49 +0000925#==============================================================================
926
927class TestSetOfSets(unittest.TestCase):
928 def test_constructor(self):
929 inner = frozenset([1])
930 outer = set([inner])
931 element = outer.pop()
932 self.assertEqual(type(element), frozenset)
933 outer.add(inner) # Rebuild set of sets with .add method
934 outer.remove(inner)
935 self.assertEqual(outer, set()) # Verify that remove worked
936 outer.discard(inner) # Absence of KeyError indicates working fine
937
938#==============================================================================
939
940class TestBinaryOps(unittest.TestCase):
941 def setUp(self):
942 self.set = set((2, 4, 6))
943
944 def test_eq(self): # SF bug 643115
945 self.assertEqual(self.set, set({2:1,4:3,6:5}))
946
947 def test_union_subset(self):
948 result = self.set | set([2])
949 self.assertEqual(result, set((2, 4, 6)))
950
951 def test_union_superset(self):
952 result = self.set | set([2, 4, 6, 8])
953 self.assertEqual(result, set([2, 4, 6, 8]))
954
955 def test_union_overlap(self):
956 result = self.set | set([3, 4, 5])
957 self.assertEqual(result, set([2, 3, 4, 5, 6]))
958
959 def test_union_non_overlap(self):
960 result = self.set | set([8])
961 self.assertEqual(result, set([2, 4, 6, 8]))
962
963 def test_intersection_subset(self):
964 result = self.set & set((2, 4))
965 self.assertEqual(result, set((2, 4)))
966
967 def test_intersection_superset(self):
968 result = self.set & set([2, 4, 6, 8])
969 self.assertEqual(result, set([2, 4, 6]))
970
971 def test_intersection_overlap(self):
972 result = self.set & set([3, 4, 5])
973 self.assertEqual(result, set([4]))
974
975 def test_intersection_non_overlap(self):
976 result = self.set & set([8])
977 self.assertEqual(result, empty_set)
978
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000979 def test_isdisjoint_subset(self):
980 result = self.set.isdisjoint(set((2, 4)))
981 self.assertEqual(result, False)
982
983 def test_isdisjoint_superset(self):
984 result = self.set.isdisjoint(set([2, 4, 6, 8]))
985 self.assertEqual(result, False)
986
987 def test_isdisjoint_overlap(self):
988 result = self.set.isdisjoint(set([3, 4, 5]))
989 self.assertEqual(result, False)
990
991 def test_isdisjoint_non_overlap(self):
992 result = self.set.isdisjoint(set([8]))
993 self.assertEqual(result, True)
994
Raymond Hettingera690a992003-11-16 16:17:49 +0000995 def test_sym_difference_subset(self):
996 result = self.set ^ set((2, 4))
997 self.assertEqual(result, set([6]))
998
999 def test_sym_difference_superset(self):
1000 result = self.set ^ set((2, 4, 6, 8))
1001 self.assertEqual(result, set([8]))
1002
1003 def test_sym_difference_overlap(self):
1004 result = self.set ^ set((3, 4, 5))
1005 self.assertEqual(result, set([2, 3, 5, 6]))
1006
1007 def test_sym_difference_non_overlap(self):
1008 result = self.set ^ set([8])
1009 self.assertEqual(result, set([2, 4, 6, 8]))
1010
1011 def test_cmp(self):
1012 a, b = set('a'), set('b')
1013 self.assertRaises(TypeError, cmp, a, b)
1014
1015 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
1016 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
1017 # which Python thinks is good enough to synthesize a cmp() result
1018 # without calling __cmp__.
1019 self.assertEqual(cmp(a, a), 0)
1020
Raymond Hettingera690a992003-11-16 16:17:49 +00001021
1022#==============================================================================
1023
1024class TestUpdateOps(unittest.TestCase):
1025 def setUp(self):
1026 self.set = set((2, 4, 6))
1027
1028 def test_union_subset(self):
1029 self.set |= set([2])
1030 self.assertEqual(self.set, set((2, 4, 6)))
1031
1032 def test_union_superset(self):
1033 self.set |= set([2, 4, 6, 8])
1034 self.assertEqual(self.set, set([2, 4, 6, 8]))
1035
1036 def test_union_overlap(self):
1037 self.set |= set([3, 4, 5])
1038 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1039
1040 def test_union_non_overlap(self):
1041 self.set |= set([8])
1042 self.assertEqual(self.set, set([2, 4, 6, 8]))
1043
1044 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001045 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +00001046 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1047
1048 def test_intersection_subset(self):
1049 self.set &= set((2, 4))
1050 self.assertEqual(self.set, set((2, 4)))
1051
1052 def test_intersection_superset(self):
1053 self.set &= set([2, 4, 6, 8])
1054 self.assertEqual(self.set, set([2, 4, 6]))
1055
1056 def test_intersection_overlap(self):
1057 self.set &= set([3, 4, 5])
1058 self.assertEqual(self.set, set([4]))
1059
1060 def test_intersection_non_overlap(self):
1061 self.set &= set([8])
1062 self.assertEqual(self.set, empty_set)
1063
1064 def test_intersection_method_call(self):
1065 self.set.intersection_update(set([3, 4, 5]))
1066 self.assertEqual(self.set, set([4]))
1067
1068 def test_sym_difference_subset(self):
1069 self.set ^= set((2, 4))
1070 self.assertEqual(self.set, set([6]))
1071
1072 def test_sym_difference_superset(self):
1073 self.set ^= set((2, 4, 6, 8))
1074 self.assertEqual(self.set, set([8]))
1075
1076 def test_sym_difference_overlap(self):
1077 self.set ^= set((3, 4, 5))
1078 self.assertEqual(self.set, set([2, 3, 5, 6]))
1079
1080 def test_sym_difference_non_overlap(self):
1081 self.set ^= set([8])
1082 self.assertEqual(self.set, set([2, 4, 6, 8]))
1083
1084 def test_sym_difference_method_call(self):
1085 self.set.symmetric_difference_update(set([3, 4, 5]))
1086 self.assertEqual(self.set, set([2, 3, 5, 6]))
1087
1088 def test_difference_subset(self):
1089 self.set -= set((2, 4))
1090 self.assertEqual(self.set, set([6]))
1091
1092 def test_difference_superset(self):
1093 self.set -= set((2, 4, 6, 8))
1094 self.assertEqual(self.set, set([]))
1095
1096 def test_difference_overlap(self):
1097 self.set -= set((3, 4, 5))
1098 self.assertEqual(self.set, set([2, 6]))
1099
1100 def test_difference_non_overlap(self):
1101 self.set -= set([8])
1102 self.assertEqual(self.set, set([2, 4, 6]))
1103
1104 def test_difference_method_call(self):
1105 self.set.difference_update(set([3, 4, 5]))
1106 self.assertEqual(self.set, set([2, 6]))
1107
1108#==============================================================================
1109
1110class TestMutate(unittest.TestCase):
1111 def setUp(self):
1112 self.values = ["a", "b", "c"]
1113 self.set = set(self.values)
1114
1115 def test_add_present(self):
1116 self.set.add("c")
1117 self.assertEqual(self.set, set("abc"))
1118
1119 def test_add_absent(self):
1120 self.set.add("d")
1121 self.assertEqual(self.set, set("abcd"))
1122
1123 def test_add_until_full(self):
1124 tmp = set()
1125 expected_len = 0
1126 for v in self.values:
1127 tmp.add(v)
1128 expected_len += 1
1129 self.assertEqual(len(tmp), expected_len)
1130 self.assertEqual(tmp, self.set)
1131
1132 def test_remove_present(self):
1133 self.set.remove("b")
1134 self.assertEqual(self.set, set("ac"))
1135
1136 def test_remove_absent(self):
1137 try:
1138 self.set.remove("d")
1139 self.fail("Removing missing element should have raised LookupError")
1140 except LookupError:
1141 pass
1142
1143 def test_remove_until_empty(self):
1144 expected_len = len(self.set)
1145 for v in self.values:
1146 self.set.remove(v)
1147 expected_len -= 1
1148 self.assertEqual(len(self.set), expected_len)
1149
1150 def test_discard_present(self):
1151 self.set.discard("c")
1152 self.assertEqual(self.set, set("ab"))
1153
1154 def test_discard_absent(self):
1155 self.set.discard("d")
1156 self.assertEqual(self.set, set("abc"))
1157
1158 def test_clear(self):
1159 self.set.clear()
1160 self.assertEqual(len(self.set), 0)
1161
1162 def test_pop(self):
1163 popped = {}
1164 while self.set:
1165 popped[self.set.pop()] = None
1166 self.assertEqual(len(popped), len(self.values))
1167 for v in self.values:
Ezio Melottiaa980582010-01-23 23:04:36 +00001168 self.assertIn(v, popped)
Raymond Hettingera690a992003-11-16 16:17:49 +00001169
1170 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001171 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001172 self.assertEqual(self.set, set(self.values))
1173
1174 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001175 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001176 self.assertEqual(self.set, set(self.values))
1177
1178 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001179 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001180 self.assertEqual(self.set, set(self.values + ["z"]))
1181
1182#==============================================================================
1183
1184class TestSubsets(unittest.TestCase):
1185
1186 case2method = {"<=": "issubset",
1187 ">=": "issuperset",
1188 }
1189
1190 reverse = {"==": "==",
1191 "!=": "!=",
1192 "<": ">",
1193 ">": "<",
1194 "<=": ">=",
1195 ">=": "<=",
1196 }
1197
1198 def test_issubset(self):
1199 x = self.left
1200 y = self.right
1201 for case in "!=", "==", "<", "<=", ">", ">=":
1202 expected = case in self.cases
1203 # Test the binary infix spelling.
1204 result = eval("x" + case + "y", locals())
1205 self.assertEqual(result, expected)
1206 # Test the "friendly" method-name spelling, if one exists.
1207 if case in TestSubsets.case2method:
1208 method = getattr(x, TestSubsets.case2method[case])
1209 result = method(y)
1210 self.assertEqual(result, expected)
1211
1212 # Now do the same for the operands reversed.
1213 rcase = TestSubsets.reverse[case]
1214 result = eval("y" + rcase + "x", locals())
1215 self.assertEqual(result, expected)
1216 if rcase in TestSubsets.case2method:
1217 method = getattr(y, TestSubsets.case2method[rcase])
1218 result = method(x)
1219 self.assertEqual(result, expected)
1220#------------------------------------------------------------------------------
1221
1222class TestSubsetEqualEmpty(TestSubsets):
1223 left = set()
1224 right = set()
1225 name = "both empty"
1226 cases = "==", "<=", ">="
1227
1228#------------------------------------------------------------------------------
1229
1230class TestSubsetEqualNonEmpty(TestSubsets):
1231 left = set([1, 2])
1232 right = set([1, 2])
1233 name = "equal pair"
1234 cases = "==", "<=", ">="
1235
1236#------------------------------------------------------------------------------
1237
1238class TestSubsetEmptyNonEmpty(TestSubsets):
1239 left = set()
1240 right = set([1, 2])
1241 name = "one empty, one non-empty"
1242 cases = "!=", "<", "<="
1243
1244#------------------------------------------------------------------------------
1245
1246class TestSubsetPartial(TestSubsets):
1247 left = set([1])
1248 right = set([1, 2])
1249 name = "one a non-empty proper subset of other"
1250 cases = "!=", "<", "<="
1251
1252#------------------------------------------------------------------------------
1253
1254class TestSubsetNonOverlap(TestSubsets):
1255 left = set([1])
1256 right = set([2])
1257 name = "neither empty, neither contains"
1258 cases = "!="
1259
1260#==============================================================================
1261
1262class TestOnlySetsInBinaryOps(unittest.TestCase):
1263
1264 def test_eq_ne(self):
1265 # Unlike the others, this is testing that == and != *are* allowed.
1266 self.assertEqual(self.other == self.set, False)
1267 self.assertEqual(self.set == self.other, False)
1268 self.assertEqual(self.other != self.set, True)
1269 self.assertEqual(self.set != self.other, True)
1270
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001271 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001272 try:
1273 self.set |= self.other
1274 except TypeError:
1275 pass
1276 else:
1277 self.fail("expected TypeError")
1278
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001279 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001280 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001281 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001282 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001283 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001284
1285 def test_union(self):
1286 self.assertRaises(TypeError, lambda: self.set | self.other)
1287 self.assertRaises(TypeError, lambda: self.other | self.set)
1288 if self.otherIsIterable:
1289 self.set.union(self.other)
1290 else:
1291 self.assertRaises(TypeError, self.set.union, self.other)
1292
1293 def test_intersection_update_operator(self):
1294 try:
1295 self.set &= self.other
1296 except TypeError:
1297 pass
1298 else:
1299 self.fail("expected TypeError")
1300
1301 def test_intersection_update(self):
1302 if self.otherIsIterable:
1303 self.set.intersection_update(self.other)
1304 else:
1305 self.assertRaises(TypeError,
1306 self.set.intersection_update,
1307 self.other)
1308
1309 def test_intersection(self):
1310 self.assertRaises(TypeError, lambda: self.set & self.other)
1311 self.assertRaises(TypeError, lambda: self.other & self.set)
1312 if self.otherIsIterable:
1313 self.set.intersection(self.other)
1314 else:
1315 self.assertRaises(TypeError, self.set.intersection, self.other)
1316
1317 def test_sym_difference_update_operator(self):
1318 try:
1319 self.set ^= self.other
1320 except TypeError:
1321 pass
1322 else:
1323 self.fail("expected TypeError")
1324
1325 def test_sym_difference_update(self):
1326 if self.otherIsIterable:
1327 self.set.symmetric_difference_update(self.other)
1328 else:
1329 self.assertRaises(TypeError,
1330 self.set.symmetric_difference_update,
1331 self.other)
1332
1333 def test_sym_difference(self):
1334 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1335 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1336 if self.otherIsIterable:
1337 self.set.symmetric_difference(self.other)
1338 else:
1339 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1340
1341 def test_difference_update_operator(self):
1342 try:
1343 self.set -= self.other
1344 except TypeError:
1345 pass
1346 else:
1347 self.fail("expected TypeError")
1348
1349 def test_difference_update(self):
1350 if self.otherIsIterable:
1351 self.set.difference_update(self.other)
1352 else:
1353 self.assertRaises(TypeError,
1354 self.set.difference_update,
1355 self.other)
1356
1357 def test_difference(self):
1358 self.assertRaises(TypeError, lambda: self.set - self.other)
1359 self.assertRaises(TypeError, lambda: self.other - self.set)
1360 if self.otherIsIterable:
1361 self.set.difference(self.other)
1362 else:
1363 self.assertRaises(TypeError, self.set.difference, self.other)
1364
1365#------------------------------------------------------------------------------
1366
1367class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1368 def setUp(self):
1369 self.set = set((1, 2, 3))
1370 self.other = 19
1371 self.otherIsIterable = False
1372
1373#------------------------------------------------------------------------------
1374
1375class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1376 def setUp(self):
1377 self.set = set((1, 2, 3))
1378 self.other = {1:2, 3:4}
1379 self.otherIsIterable = True
1380
1381#------------------------------------------------------------------------------
1382
Raymond Hettingera690a992003-11-16 16:17:49 +00001383class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1384 def setUp(self):
1385 self.set = set((1, 2, 3))
1386 self.other = (2, 4, 6)
1387 self.otherIsIterable = True
1388
1389#------------------------------------------------------------------------------
1390
1391class TestOnlySetsString(TestOnlySetsInBinaryOps):
1392 def setUp(self):
1393 self.set = set((1, 2, 3))
1394 self.other = 'abc'
1395 self.otherIsIterable = True
1396
1397#------------------------------------------------------------------------------
1398
1399class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1400 def setUp(self):
1401 def gen():
1402 for i in xrange(0, 10, 2):
1403 yield i
1404 self.set = set((1, 2, 3))
1405 self.other = gen()
1406 self.otherIsIterable = True
1407
1408#==============================================================================
1409
1410class TestCopying(unittest.TestCase):
1411
1412 def test_copy(self):
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001413 dup = list(self.set.copy())
1414 self.assertEqual(len(dup), len(self.set))
1415 for el in self.set:
1416 self.assertIn(el, dup)
1417 pos = dup.index(el)
1418 self.assertIs(el, dup.pop(pos))
1419 self.assertFalse(dup)
Raymond Hettingera690a992003-11-16 16:17:49 +00001420
1421 def test_deep_copy(self):
1422 dup = copy.deepcopy(self.set)
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001423 self.assertSetEqual(dup, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +00001424
1425#------------------------------------------------------------------------------
1426
1427class TestCopyingEmpty(TestCopying):
1428 def setUp(self):
1429 self.set = set()
1430
1431#------------------------------------------------------------------------------
1432
1433class TestCopyingSingleton(TestCopying):
1434 def setUp(self):
1435 self.set = set(["hello"])
1436
1437#------------------------------------------------------------------------------
1438
1439class TestCopyingTriple(TestCopying):
1440 def setUp(self):
1441 self.set = set(["zero", 0, None])
1442
1443#------------------------------------------------------------------------------
1444
1445class TestCopyingTuple(TestCopying):
1446 def setUp(self):
1447 self.set = set([(1, 2)])
1448
1449#------------------------------------------------------------------------------
1450
1451class TestCopyingNested(TestCopying):
1452 def setUp(self):
1453 self.set = set([((1, 2), (3, 4))])
1454
1455#==============================================================================
1456
1457class TestIdentities(unittest.TestCase):
1458 def setUp(self):
1459 self.a = set('abracadabra')
1460 self.b = set('alacazam')
1461
1462 def test_binopsVsSubsets(self):
1463 a, b = self.a, self.b
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001464 self.assertTrue(a - b < a)
1465 self.assertTrue(b - a < b)
1466 self.assertTrue(a & b < a)
1467 self.assertTrue(a & b < b)
1468 self.assertTrue(a | b > a)
1469 self.assertTrue(a | b > b)
1470 self.assertTrue(a ^ b < a | b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001471
1472 def test_commutativity(self):
1473 a, b = self.a, self.b
1474 self.assertEqual(a&b, b&a)
1475 self.assertEqual(a|b, b|a)
1476 self.assertEqual(a^b, b^a)
1477 if a != b:
1478 self.assertNotEqual(a-b, b-a)
1479
1480 def test_summations(self):
1481 # check that sums of parts equal the whole
1482 a, b = self.a, self.b
1483 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1484 self.assertEqual((a&b)|(a^b), a|b)
1485 self.assertEqual(a|(b-a), a|b)
1486 self.assertEqual((a-b)|b, a|b)
1487 self.assertEqual((a-b)|(a&b), a)
1488 self.assertEqual((b-a)|(a&b), b)
1489 self.assertEqual((a-b)|(b-a), a^b)
1490
1491 def test_exclusion(self):
1492 # check that inverse operations show non-overlap
1493 a, b, zero = self.a, self.b, set()
1494 self.assertEqual((a-b)&b, zero)
1495 self.assertEqual((b-a)&a, zero)
1496 self.assertEqual((a&b)&(a^b), zero)
1497
1498# Tests derived from test_itertools.py =======================================
1499
1500def R(seqn):
1501 'Regular generator'
1502 for i in seqn:
1503 yield i
1504
1505class G:
1506 'Sequence using __getitem__'
1507 def __init__(self, seqn):
1508 self.seqn = seqn
1509 def __getitem__(self, i):
1510 return self.seqn[i]
1511
1512class I:
1513 'Sequence using iterator protocol'
1514 def __init__(self, seqn):
1515 self.seqn = seqn
1516 self.i = 0
1517 def __iter__(self):
1518 return self
1519 def next(self):
1520 if self.i >= len(self.seqn): raise StopIteration
1521 v = self.seqn[self.i]
1522 self.i += 1
1523 return v
1524
1525class Ig:
1526 'Sequence using iterator protocol defined with a generator'
1527 def __init__(self, seqn):
1528 self.seqn = seqn
1529 self.i = 0
1530 def __iter__(self):
1531 for val in self.seqn:
1532 yield val
1533
1534class X:
1535 'Missing __getitem__ and __iter__'
1536 def __init__(self, seqn):
1537 self.seqn = seqn
1538 self.i = 0
1539 def next(self):
1540 if self.i >= len(self.seqn): raise StopIteration
1541 v = self.seqn[self.i]
1542 self.i += 1
1543 return v
1544
1545class N:
1546 'Iterator missing next()'
1547 def __init__(self, seqn):
1548 self.seqn = seqn
1549 self.i = 0
1550 def __iter__(self):
1551 return self
1552
1553class E:
1554 'Test propagation of exceptions'
1555 def __init__(self, seqn):
1556 self.seqn = seqn
1557 self.i = 0
1558 def __iter__(self):
1559 return self
1560 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001561 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001562
1563class S:
1564 'Test immediate stop'
1565 def __init__(self, seqn):
1566 pass
1567 def __iter__(self):
1568 return self
1569 def next(self):
1570 raise StopIteration
1571
1572from itertools import chain, imap
1573def L(seqn):
1574 'Test multiple tiers of iterators'
1575 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1576
1577class TestVariousIteratorArgs(unittest.TestCase):
1578
1579 def test_constructor(self):
1580 for cons in (set, frozenset):
1581 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1582 for g in (G, I, Ig, S, L, R):
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001583 self.assertSetEqual(cons(g(s)), set(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001584 self.assertRaises(TypeError, cons , X(s))
1585 self.assertRaises(TypeError, cons , N(s))
1586 self.assertRaises(ZeroDivisionError, cons , E(s))
1587
1588 def test_inline_methods(self):
1589 s = set('november')
1590 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001591 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001592 for g in (G, I, Ig, L, R):
1593 expected = meth(data)
Terry Jan Reedy807c9da2014-04-26 13:55:59 -04001594 actual = meth(g(data))
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001595 if isinstance(expected, bool):
1596 self.assertEqual(actual, expected)
1597 else:
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001598 self.assertSetEqual(actual, expected)
Raymond Hettingera690a992003-11-16 16:17:49 +00001599 self.assertRaises(TypeError, meth, X(s))
1600 self.assertRaises(TypeError, meth, N(s))
1601 self.assertRaises(ZeroDivisionError, meth, E(s))
1602
1603 def test_inplace_methods(self):
1604 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001605 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001606 'difference_update', 'symmetric_difference_update'):
1607 for g in (G, I, Ig, S, L, R):
1608 s = set('january')
1609 t = s.copy()
1610 getattr(s, methname)(list(g(data)))
1611 getattr(t, methname)(g(data))
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001612 self.assertSetEqual(s, t)
Raymond Hettingera690a992003-11-16 16:17:49 +00001613
1614 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1615 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1616 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1617
Éric Araujof079c9b2011-03-22 23:47:32 +01001618class bad_eq:
1619 def __eq__(self, other):
1620 if be_bad:
1621 set2.clear()
1622 raise ZeroDivisionError
1623 return self is other
1624 def __hash__(self):
1625 return 0
1626
1627class bad_dict_clear:
1628 def __eq__(self, other):
1629 if be_bad:
1630 dict2.clear()
1631 return self is other
1632 def __hash__(self):
1633 return 0
1634
1635class TestWeirdBugs(unittest.TestCase):
1636 def test_8420_set_merge(self):
1637 # This used to segfault
1638 global be_bad, set2, dict2
1639 be_bad = False
1640 set1 = {bad_eq()}
1641 set2 = {bad_eq() for i in range(75)}
1642 be_bad = True
1643 self.assertRaises(ZeroDivisionError, set1.update, set2)
1644
1645 be_bad = False
1646 set1 = {bad_dict_clear()}
1647 dict2 = {bad_dict_clear(): None}
1648 be_bad = True
1649 set1.symmetric_difference_update(dict2)
1650
Raymond Hettinger61708742008-01-24 21:23:58 +00001651# Application tests (based on David Eppstein's graph recipes ====================================
1652
1653def powerset(U):
1654 """Generates all subsets of a set or sequence U."""
1655 U = iter(U)
1656 try:
1657 x = frozenset([U.next()])
1658 for S in powerset(U):
1659 yield S
1660 yield S | x
1661 except StopIteration:
1662 yield frozenset()
1663
1664def cube(n):
1665 """Graph of n-dimensional hypercube."""
1666 singletons = [frozenset([x]) for x in range(n)]
1667 return dict([(x, frozenset([x^s for s in singletons]))
1668 for x in powerset(range(n))])
1669
1670def linegraph(G):
1671 """Graph, the vertices of which are edges of G,
1672 with two vertices being adjacent iff the corresponding
1673 edges share a vertex."""
1674 L = {}
1675 for x in G:
1676 for y in G[x]:
1677 nx = [frozenset([x,z]) for z in G[x] if z != y]
1678 ny = [frozenset([y,z]) for z in G[y] if z != x]
1679 L[frozenset([x,y])] = frozenset(nx+ny)
1680 return L
1681
1682def faces(G):
1683 'Return a set of faces in G. Where a face is a set of vertices on that face'
1684 # currently limited to triangles,squares, and pentagons
1685 f = set()
1686 for v1, edges in G.items():
1687 for v2 in edges:
1688 for v3 in G[v2]:
1689 if v1 == v3:
1690 continue
1691 if v1 in G[v3]:
1692 f.add(frozenset([v1, v2, v3]))
1693 else:
1694 for v4 in G[v3]:
1695 if v4 == v2:
1696 continue
1697 if v1 in G[v4]:
1698 f.add(frozenset([v1, v2, v3, v4]))
1699 else:
1700 for v5 in G[v4]:
1701 if v5 == v3 or v5 == v2:
1702 continue
1703 if v1 in G[v5]:
1704 f.add(frozenset([v1, v2, v3, v4, v5]))
1705 return f
1706
1707
1708class TestGraphs(unittest.TestCase):
1709
1710 def test_cube(self):
1711
1712 g = cube(3) # vert --> {v1, v2, v3}
1713 vertices1 = set(g)
1714 self.assertEqual(len(vertices1), 8) # eight vertices
1715 for edge in g.values():
1716 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1717 vertices2 = set(v for edges in g.values() for v in edges)
1718 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1719
1720 cubefaces = faces(g)
1721 self.assertEqual(len(cubefaces), 6) # six faces
1722 for face in cubefaces:
1723 self.assertEqual(len(face), 4) # each face is a square
1724
1725 def test_cuboctahedron(self):
1726
1727 # http://en.wikipedia.org/wiki/Cuboctahedron
1728 # 8 triangular faces and 6 square faces
1729 # 12 indentical vertices each connecting a triangle and square
1730
1731 g = cube(3)
1732 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1733 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1734
1735 vertices = set(cuboctahedron)
1736 for edges in cuboctahedron.values():
1737 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1738 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1739 self.assertEqual(vertices, othervertices) # edge vertices in original set
1740
1741 cubofaces = faces(cuboctahedron)
1742 facesizes = collections.defaultdict(int)
1743 for face in cubofaces:
1744 facesizes[len(face)] += 1
1745 self.assertEqual(facesizes[3], 8) # eight triangular faces
1746 self.assertEqual(facesizes[4], 6) # six square faces
1747
1748 for vertex in cuboctahedron:
1749 edge = vertex # Cuboctahedron vertices are edges in Cube
1750 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1751 for cubevert in edge:
Ezio Melottiaa980582010-01-23 23:04:36 +00001752 self.assertIn(cubevert, g)
Raymond Hettinger61708742008-01-24 21:23:58 +00001753
1754
Raymond Hettingera690a992003-11-16 16:17:49 +00001755#==============================================================================
1756
1757def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001758 test_classes = (
1759 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001760 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001761 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001762 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001763 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001764 TestSetOfSets,
1765 TestExceptionPropagation,
1766 TestBasicOpsEmpty,
1767 TestBasicOpsSingleton,
1768 TestBasicOpsTuple,
1769 TestBasicOpsTriple,
1770 TestBinaryOps,
1771 TestUpdateOps,
1772 TestMutate,
1773 TestSubsetEqualEmpty,
1774 TestSubsetEqualNonEmpty,
1775 TestSubsetEmptyNonEmpty,
1776 TestSubsetPartial,
1777 TestSubsetNonOverlap,
1778 TestOnlySetsNumeric,
1779 TestOnlySetsDict,
Raymond Hettingera690a992003-11-16 16:17:49 +00001780 TestOnlySetsTuple,
1781 TestOnlySetsString,
1782 TestOnlySetsGenerator,
1783 TestCopyingEmpty,
1784 TestCopyingSingleton,
1785 TestCopyingTriple,
1786 TestCopyingTuple,
1787 TestCopyingNested,
1788 TestIdentities,
1789 TestVariousIteratorArgs,
Raymond Hettinger61708742008-01-24 21:23:58 +00001790 TestGraphs,
Éric Araujof079c9b2011-03-22 23:47:32 +01001791 TestWeirdBugs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001792 )
1793
1794 test_support.run_unittest(*test_classes)
1795
1796 # verify reference counting
1797 if verbose and hasattr(sys, "gettotalrefcount"):
1798 import gc
1799 counts = [None] * 5
1800 for i in xrange(len(counts)):
1801 test_support.run_unittest(*test_classes)
1802 gc.collect()
1803 counts[i] = sys.gettotalrefcount()
1804 print counts
1805
1806if __name__ == "__main__":
1807 test_main(verbose=True)