blob: 62b36bd42c0faa135c997a8e0db64971ab622599 [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
Serhiy Storchaka14a7d632016-03-30 20:43:06 +0300343 def test_free_after_iterating(self):
344 test_support.check_free_after_iterating(self, iter, self.thetype)
345
Raymond Hettingera690a992003-11-16 16:17:49 +0000346class TestSet(TestJointOps):
347 thetype = set
348
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000349 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000350 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000351 s.__init__(self.word)
352 self.assertEqual(s, set(self.word))
353 s.__init__(self.otherword)
354 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000355 self.assertRaises(TypeError, s.__init__, s, 2);
356 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000357
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000358 def test_constructor_identity(self):
359 s = self.thetype(range(3))
360 t = self.thetype(s)
361 self.assertNotEqual(id(s), id(t))
362
Raymond Hettingera690a992003-11-16 16:17:49 +0000363 def test_hash(self):
364 self.assertRaises(TypeError, hash, self.s)
365
366 def test_clear(self):
367 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000368 self.assertEqual(self.s, set())
369 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000370
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000371 def test_copy(self):
372 dup = self.s.copy()
373 self.assertEqual(self.s, dup)
374 self.assertNotEqual(id(self.s), id(dup))
375
Raymond Hettingera690a992003-11-16 16:17:49 +0000376 def test_add(self):
377 self.s.add('Q')
Ezio Melottiaa980582010-01-23 23:04:36 +0000378 self.assertIn('Q', self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000379 dup = self.s.copy()
380 self.s.add('Q')
381 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000382 self.assertRaises(TypeError, self.s.add, [])
383
384 def test_remove(self):
385 self.s.remove('a')
Ezio Melottiaa980582010-01-23 23:04:36 +0000386 self.assertNotIn('a', self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000387 self.assertRaises(KeyError, self.s.remove, 'Q')
388 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000389 s = self.thetype([frozenset(self.word)])
Ezio Melottiaa980582010-01-23 23:04:36 +0000390 self.assertIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000391 s.remove(self.thetype(self.word))
Ezio Melottiaa980582010-01-23 23:04:36 +0000392 self.assertNotIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000393 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000394
Raymond Hettingerc789f342006-12-08 17:35:25 +0000395 def test_remove_keyerror_unpacking(self):
396 # bug: www.python.org/sf/1576657
397 for v1 in ['Q', (1,)]:
398 try:
399 self.s.remove(v1)
400 except KeyError, e:
401 v2 = e.args[0]
402 self.assertEqual(v1, v2)
403 else:
404 self.fail()
405
Amaury Forgeot d'Arcd78b9dc2008-10-07 20:32:10 +0000406 def test_remove_keyerror_set(self):
407 key = self.thetype([3, 4])
408 try:
409 self.s.remove(key)
410 except KeyError as e:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000411 self.assertTrue(e.args[0] is key,
Amaury Forgeot d'Arcd78b9dc2008-10-07 20:32:10 +0000412 "KeyError should be {0}, not {1}".format(key,
413 e.args[0]))
414 else:
415 self.fail()
416
Raymond Hettingera690a992003-11-16 16:17:49 +0000417 def test_discard(self):
418 self.s.discard('a')
Ezio Melottiaa980582010-01-23 23:04:36 +0000419 self.assertNotIn('a', self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000420 self.s.discard('Q')
421 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000422 s = self.thetype([frozenset(self.word)])
Ezio Melottiaa980582010-01-23 23:04:36 +0000423 self.assertIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000424 s.discard(self.thetype(self.word))
Ezio Melottiaa980582010-01-23 23:04:36 +0000425 self.assertNotIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000426 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000427
428 def test_pop(self):
429 for i in xrange(len(self.s)):
430 elem = self.s.pop()
Ezio Melottiaa980582010-01-23 23:04:36 +0000431 self.assertNotIn(elem, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000432 self.assertRaises(KeyError, self.s.pop)
433
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000434 def test_update(self):
435 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000436 self.assertEqual(retval, None)
437 for c in (self.word + self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000438 self.assertIn(c, self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000439 self.assertRaises(PassThru, self.s.update, check_pass_thru())
440 self.assertRaises(TypeError, self.s.update, [[]])
441 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
442 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
443 s = self.thetype('abcba')
444 self.assertEqual(s.update(C(p)), None)
445 self.assertEqual(s, set(q))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +0000446 for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
447 q = 'ahi'
448 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
449 s = self.thetype('abcba')
450 self.assertEqual(s.update(C(p), C(q)), None)
451 self.assertEqual(s, set(s) | set(p) | set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000452
453 def test_ior(self):
454 self.s |= set(self.otherword)
455 for c in (self.word + self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000456 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000457
458 def test_intersection_update(self):
459 retval = self.s.intersection_update(self.otherword)
460 self.assertEqual(retval, None)
461 for c in (self.word + self.otherword):
462 if c in self.otherword and c in self.word:
Ezio Melottiaa980582010-01-23 23:04:36 +0000463 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000464 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000465 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000466 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
467 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000468 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
469 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
470 s = self.thetype('abcba')
471 self.assertEqual(s.intersection_update(C(p)), None)
472 self.assertEqual(s, set(q))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000473 ss = 'abcba'
474 s = self.thetype(ss)
475 t = 'cbc'
476 self.assertEqual(s.intersection_update(C(p), C(t)), None)
477 self.assertEqual(s, set('abcba')&set(p)&set(t))
Raymond Hettingera690a992003-11-16 16:17:49 +0000478
479 def test_iand(self):
480 self.s &= set(self.otherword)
481 for c in (self.word + self.otherword):
482 if c in self.otherword and c in self.word:
Ezio Melottiaa980582010-01-23 23:04:36 +0000483 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000484 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000485 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000486
487 def test_difference_update(self):
488 retval = self.s.difference_update(self.otherword)
489 self.assertEqual(retval, None)
490 for c in (self.word + self.otherword):
491 if c in self.word and c not in self.otherword:
Ezio Melottiaa980582010-01-23 23:04:36 +0000492 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000493 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000494 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000495 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
496 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000497 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
498 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
499 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
500 s = self.thetype('abcba')
501 self.assertEqual(s.difference_update(C(p)), None)
502 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000503
Raymond Hettinger4267be62008-06-11 10:30:54 +0000504 s = self.thetype('abcdefghih')
505 s.difference_update()
506 self.assertEqual(s, self.thetype('abcdefghih'))
507
508 s = self.thetype('abcdefghih')
509 s.difference_update(C('aba'))
510 self.assertEqual(s, self.thetype('cdefghih'))
511
512 s = self.thetype('abcdefghih')
513 s.difference_update(C('cdc'), C('aba'))
514 self.assertEqual(s, self.thetype('efghih'))
515
Raymond Hettingera690a992003-11-16 16:17:49 +0000516 def test_isub(self):
517 self.s -= set(self.otherword)
518 for c in (self.word + self.otherword):
519 if c in self.word and c not in self.otherword:
Ezio Melottiaa980582010-01-23 23:04:36 +0000520 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000521 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000522 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000523
524 def test_symmetric_difference_update(self):
525 retval = self.s.symmetric_difference_update(self.otherword)
526 self.assertEqual(retval, None)
527 for c in (self.word + self.otherword):
528 if (c in self.word) ^ (c in self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000529 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000530 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000531 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000532 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
533 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000534 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
535 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
536 s = self.thetype('abcba')
537 self.assertEqual(s.symmetric_difference_update(C(p)), None)
538 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000539
540 def test_ixor(self):
541 self.s ^= set(self.otherword)
542 for c in (self.word + self.otherword):
543 if (c in self.word) ^ (c in self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000544 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000545 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000546 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000547
Raymond Hettingerc991db22005-08-11 07:58:45 +0000548 def test_inplace_on_self(self):
549 t = self.s.copy()
550 t |= t
551 self.assertEqual(t, self.s)
552 t &= t
553 self.assertEqual(t, self.s)
554 t -= t
555 self.assertEqual(t, self.thetype())
556 t = self.s.copy()
557 t ^= t
558 self.assertEqual(t, self.thetype())
559
Raymond Hettinger691d8052004-05-30 07:26:47 +0000560 def test_weakref(self):
561 s = self.thetype('gallahad')
Antoine Pitrouaa687902009-01-01 14:11:22 +0000562 p = weakref.proxy(s)
Raymond Hettinger691d8052004-05-30 07:26:47 +0000563 self.assertEqual(str(p), str(s))
564 s = None
565 self.assertRaises(ReferenceError, str, p)
566
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200567 @unittest.skipUnless(hasattr(set, "test_c_api"),
568 'C API test only available in a debug build')
569 def test_c_api(self):
570 self.assertEqual(set().test_c_api(), True)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000571
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000572class SetSubclass(set):
573 pass
574
575class TestSetSubclass(TestSet):
576 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000577
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000578class SetSubclassWithKeywordArgs(set):
579 def __init__(self, iterable=[], newarg=None):
580 set.__init__(self, iterable)
581
582class TestSetSubclassWithKeywordArgs(TestSet):
Tim Petersf733abb2007-01-30 03:03:46 +0000583
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000584 def test_keywords_in_subclass(self):
585 'SF bug #1486663 -- this used to erroneously raise a TypeError'
586 SetSubclassWithKeywordArgs(newarg=1)
587
Raymond Hettingera690a992003-11-16 16:17:49 +0000588class TestFrozenSet(TestJointOps):
589 thetype = frozenset
590
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000591 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000592 s = self.thetype(self.word)
593 s.__init__(self.otherword)
594 self.assertEqual(s, set(self.word))
595
Raymond Hettingerd7946662005-08-01 21:39:29 +0000596 def test_singleton_empty_frozenset(self):
597 f = frozenset()
598 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
599 frozenset(), frozenset([]), frozenset(()), frozenset(''),
600 frozenset(xrange(0)), frozenset(frozenset()),
601 frozenset(f), f]
602 # All of the empty frozensets should have just one id()
603 self.assertEqual(len(set(map(id, efs))), 1)
604
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000605 def test_constructor_identity(self):
606 s = self.thetype(range(3))
607 t = self.thetype(s)
608 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000609
Raymond Hettingera690a992003-11-16 16:17:49 +0000610 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000611 self.assertEqual(hash(self.thetype('abcdeb')),
612 hash(self.thetype('ebecda')))
613
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000614 # make sure that all permutations give the same hash value
615 n = 100
616 seq = [randrange(n) for i in xrange(n)]
617 results = set()
618 for i in xrange(200):
619 shuffle(seq)
620 results.add(hash(self.thetype(seq)))
621 self.assertEqual(len(results), 1)
622
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000623 def test_copy(self):
624 dup = self.s.copy()
625 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000626
627 def test_frozen_as_dictkey(self):
628 seq = range(10) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000629 key1 = self.thetype(seq)
630 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000631 self.assertEqual(key1, key2)
632 self.assertNotEqual(id(key1), id(key2))
633 d = {}
634 d[key1] = 42
635 self.assertEqual(d[key2], 42)
636
637 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000638 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000639 self.assertEqual(hash(f), hash(f))
640
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000641 def test_hash_effectiveness(self):
642 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000643 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000644 addhashvalue = hashvalues.add
645 elemmasks = [(i+1, 1<<i) for i in range(n)]
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000646 for i in xrange(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000647 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
648 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000649
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000650class FrozenSetSubclass(frozenset):
651 pass
652
653class TestFrozenSetSubclass(TestFrozenSet):
654 thetype = FrozenSetSubclass
655
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000656 def test_constructor_identity(self):
657 s = self.thetype(range(3))
658 t = self.thetype(s)
659 self.assertNotEqual(id(s), id(t))
660
661 def test_copy(self):
662 dup = self.s.copy()
663 self.assertNotEqual(id(self.s), id(dup))
664
665 def test_nested_empty_constructor(self):
666 s = self.thetype()
667 t = self.thetype(s)
668 self.assertEqual(s, t)
669
Raymond Hettingerd7946662005-08-01 21:39:29 +0000670 def test_singleton_empty_frozenset(self):
671 Frozenset = self.thetype
672 f = frozenset()
673 F = Frozenset()
674 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
675 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
676 Frozenset(xrange(0)), Frozenset(Frozenset()),
677 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
678 # All empty frozenset subclass instances should have different ids
679 self.assertEqual(len(set(map(id, efs))), len(efs))
680
Raymond Hettingera690a992003-11-16 16:17:49 +0000681# Tests taken from test_sets.py =============================================
682
683empty_set = set()
684
685#==============================================================================
686
687class TestBasicOps(unittest.TestCase):
688
689 def test_repr(self):
690 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000691 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000692
Barry Warsaw1e13eb02012-02-20 20:42:21 -0500693 def check_repr_against_values(self):
694 text = repr(self.set)
695 self.assertTrue(text.startswith('{'))
696 self.assertTrue(text.endswith('}'))
697
698 result = text[1:-1].split(', ')
699 result.sort()
700 sorted_repr_values = [repr(value) for value in self.values]
701 sorted_repr_values.sort()
702 self.assertEqual(result, sorted_repr_values)
703
Raymond Hettingereae05de2004-07-09 04:51:24 +0000704 def test_print(self):
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000705 fo = open(test_support.TESTFN, "wb")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000706 try:
Raymond Hettingereae05de2004-07-09 04:51:24 +0000707 print >> fo, self.set,
708 fo.close()
709 fo = open(test_support.TESTFN, "rb")
710 self.assertEqual(fo.read(), repr(self.set))
711 finally:
712 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000713 test_support.unlink(test_support.TESTFN)
Raymond Hettingereae05de2004-07-09 04:51:24 +0000714
Raymond Hettingera690a992003-11-16 16:17:49 +0000715 def test_length(self):
716 self.assertEqual(len(self.set), self.length)
717
718 def test_self_equality(self):
719 self.assertEqual(self.set, self.set)
720
721 def test_equivalent_equality(self):
722 self.assertEqual(self.set, self.dup)
723
724 def test_copy(self):
725 self.assertEqual(self.set.copy(), self.dup)
726
727 def test_self_union(self):
728 result = self.set | self.set
729 self.assertEqual(result, self.dup)
730
731 def test_empty_union(self):
732 result = self.set | empty_set
733 self.assertEqual(result, self.dup)
734
735 def test_union_empty(self):
736 result = empty_set | self.set
737 self.assertEqual(result, self.dup)
738
739 def test_self_intersection(self):
740 result = self.set & self.set
741 self.assertEqual(result, self.dup)
742
743 def test_empty_intersection(self):
744 result = self.set & empty_set
745 self.assertEqual(result, empty_set)
746
747 def test_intersection_empty(self):
748 result = empty_set & self.set
749 self.assertEqual(result, empty_set)
750
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000751 def test_self_isdisjoint(self):
752 result = self.set.isdisjoint(self.set)
753 self.assertEqual(result, not self.set)
754
755 def test_empty_isdisjoint(self):
756 result = self.set.isdisjoint(empty_set)
757 self.assertEqual(result, True)
758
759 def test_isdisjoint_empty(self):
760 result = empty_set.isdisjoint(self.set)
761 self.assertEqual(result, True)
762
Raymond Hettingera690a992003-11-16 16:17:49 +0000763 def test_self_symmetric_difference(self):
764 result = self.set ^ self.set
765 self.assertEqual(result, empty_set)
766
Georg Brandl0347c712010-08-01 19:02:09 +0000767 def test_empty_symmetric_difference(self):
Raymond Hettingera690a992003-11-16 16:17:49 +0000768 result = self.set ^ empty_set
769 self.assertEqual(result, self.set)
770
771 def test_self_difference(self):
772 result = self.set - self.set
773 self.assertEqual(result, empty_set)
774
775 def test_empty_difference(self):
776 result = self.set - empty_set
777 self.assertEqual(result, self.dup)
778
779 def test_empty_difference_rev(self):
780 result = empty_set - self.set
781 self.assertEqual(result, empty_set)
782
783 def test_iteration(self):
784 for v in self.set:
Ezio Melottiaa980582010-01-23 23:04:36 +0000785 self.assertIn(v, self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000786 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000787 # note: __length_hint__ is an internal undocumented API,
788 # don't rely on it in your own programs
789 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000790
791 def test_pickling(self):
Serhiy Storchaka655720e2014-12-15 14:02:43 +0200792 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
793 p = pickle.dumps(self.set, proto)
794 copy = pickle.loads(p)
795 self.assertEqual(self.set, copy,
796 "%s != %s" % (self.set, copy))
Raymond Hettingera690a992003-11-16 16:17:49 +0000797
798#------------------------------------------------------------------------------
799
800class TestBasicOpsEmpty(TestBasicOps):
801 def setUp(self):
802 self.case = "empty set"
803 self.values = []
804 self.set = set(self.values)
805 self.dup = set(self.values)
806 self.length = 0
807 self.repr = "set([])"
808
809#------------------------------------------------------------------------------
810
811class TestBasicOpsSingleton(TestBasicOps):
812 def setUp(self):
813 self.case = "unit set (number)"
814 self.values = [3]
815 self.set = set(self.values)
816 self.dup = set(self.values)
817 self.length = 1
818 self.repr = "set([3])"
819
820 def test_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000821 self.assertIn(3, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000822
823 def test_not_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000824 self.assertNotIn(2, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000825
826#------------------------------------------------------------------------------
827
828class TestBasicOpsTuple(TestBasicOps):
829 def setUp(self):
830 self.case = "unit set (tuple)"
831 self.values = [(0, "zero")]
832 self.set = set(self.values)
833 self.dup = set(self.values)
834 self.length = 1
835 self.repr = "set([(0, 'zero')])"
836
837 def test_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000838 self.assertIn((0, "zero"), self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000839
840 def test_not_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000841 self.assertNotIn(9, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000842
843#------------------------------------------------------------------------------
844
845class TestBasicOpsTriple(TestBasicOps):
846 def setUp(self):
847 self.case = "triple set"
848 self.values = [0, "zero", operator.add]
849 self.set = set(self.values)
850 self.dup = set(self.values)
851 self.length = 3
852 self.repr = None
853
Barry Warsaw1e13eb02012-02-20 20:42:21 -0500854#------------------------------------------------------------------------------
855
856class TestBasicOpsString(TestBasicOps):
857 def setUp(self):
858 self.case = "string set"
859 self.values = ["a", "b", "c"]
860 self.set = set(self.values)
861 self.dup = set(self.values)
862 self.length = 3
863
864 def test_repr(self):
865 self.check_repr_against_values()
866
867#------------------------------------------------------------------------------
868
869class TestBasicOpsUnicode(TestBasicOps):
870 def setUp(self):
871 self.case = "unicode set"
872 self.values = [u"a", u"b", u"c"]
873 self.set = set(self.values)
874 self.dup = set(self.values)
875 self.length = 3
876
877 def test_repr(self):
878 self.check_repr_against_values()
879
880#------------------------------------------------------------------------------
881
882class TestBasicOpsMixedStringUnicode(TestBasicOps):
883 def setUp(self):
884 self.case = "string and bytes set"
885 self.values = ["a", "b", u"a", u"b"]
886 self.set = set(self.values)
887 self.dup = set(self.values)
888 self.length = 4
889
890 def test_repr(self):
891 with test_support.check_warnings():
892 self.check_repr_against_values()
893
Raymond Hettingera690a992003-11-16 16:17:49 +0000894#==============================================================================
895
896def baditer():
897 raise TypeError
898 yield True
899
900def gooditer():
901 yield True
902
903class TestExceptionPropagation(unittest.TestCase):
904 """SF 628246: Set constructor should not trap iterator TypeErrors"""
905
906 def test_instanceWithException(self):
907 self.assertRaises(TypeError, set, baditer())
908
909 def test_instancesWithoutException(self):
910 # All of these iterables should load without exception.
911 set([1,2,3])
912 set((1,2,3))
913 set({'one':1, 'two':2, 'three':3})
914 set(xrange(3))
915 set('abc')
916 set(gooditer())
917
Neal Norwitzfcf44352005-11-27 20:37:43 +0000918 def test_changingSizeWhileIterating(self):
919 s = set([1,2,3])
920 try:
921 for i in s:
922 s.update([4])
923 except RuntimeError:
924 pass
925 else:
926 self.fail("no exception when changing size during iteration")
927
Raymond Hettingera690a992003-11-16 16:17:49 +0000928#==============================================================================
929
930class TestSetOfSets(unittest.TestCase):
931 def test_constructor(self):
932 inner = frozenset([1])
933 outer = set([inner])
934 element = outer.pop()
935 self.assertEqual(type(element), frozenset)
936 outer.add(inner) # Rebuild set of sets with .add method
937 outer.remove(inner)
938 self.assertEqual(outer, set()) # Verify that remove worked
939 outer.discard(inner) # Absence of KeyError indicates working fine
940
941#==============================================================================
942
943class TestBinaryOps(unittest.TestCase):
944 def setUp(self):
945 self.set = set((2, 4, 6))
946
947 def test_eq(self): # SF bug 643115
948 self.assertEqual(self.set, set({2:1,4:3,6:5}))
949
950 def test_union_subset(self):
951 result = self.set | set([2])
952 self.assertEqual(result, set((2, 4, 6)))
953
954 def test_union_superset(self):
955 result = self.set | set([2, 4, 6, 8])
956 self.assertEqual(result, set([2, 4, 6, 8]))
957
958 def test_union_overlap(self):
959 result = self.set | set([3, 4, 5])
960 self.assertEqual(result, set([2, 3, 4, 5, 6]))
961
962 def test_union_non_overlap(self):
963 result = self.set | set([8])
964 self.assertEqual(result, set([2, 4, 6, 8]))
965
966 def test_intersection_subset(self):
967 result = self.set & set((2, 4))
968 self.assertEqual(result, set((2, 4)))
969
970 def test_intersection_superset(self):
971 result = self.set & set([2, 4, 6, 8])
972 self.assertEqual(result, set([2, 4, 6]))
973
974 def test_intersection_overlap(self):
975 result = self.set & set([3, 4, 5])
976 self.assertEqual(result, set([4]))
977
978 def test_intersection_non_overlap(self):
979 result = self.set & set([8])
980 self.assertEqual(result, empty_set)
981
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000982 def test_isdisjoint_subset(self):
983 result = self.set.isdisjoint(set((2, 4)))
984 self.assertEqual(result, False)
985
986 def test_isdisjoint_superset(self):
987 result = self.set.isdisjoint(set([2, 4, 6, 8]))
988 self.assertEqual(result, False)
989
990 def test_isdisjoint_overlap(self):
991 result = self.set.isdisjoint(set([3, 4, 5]))
992 self.assertEqual(result, False)
993
994 def test_isdisjoint_non_overlap(self):
995 result = self.set.isdisjoint(set([8]))
996 self.assertEqual(result, True)
997
Raymond Hettingera690a992003-11-16 16:17:49 +0000998 def test_sym_difference_subset(self):
999 result = self.set ^ set((2, 4))
1000 self.assertEqual(result, set([6]))
1001
1002 def test_sym_difference_superset(self):
1003 result = self.set ^ set((2, 4, 6, 8))
1004 self.assertEqual(result, set([8]))
1005
1006 def test_sym_difference_overlap(self):
1007 result = self.set ^ set((3, 4, 5))
1008 self.assertEqual(result, set([2, 3, 5, 6]))
1009
1010 def test_sym_difference_non_overlap(self):
1011 result = self.set ^ set([8])
1012 self.assertEqual(result, set([2, 4, 6, 8]))
1013
1014 def test_cmp(self):
1015 a, b = set('a'), set('b')
1016 self.assertRaises(TypeError, cmp, a, b)
1017
1018 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
1019 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
1020 # which Python thinks is good enough to synthesize a cmp() result
1021 # without calling __cmp__.
1022 self.assertEqual(cmp(a, a), 0)
1023
Raymond Hettingera690a992003-11-16 16:17:49 +00001024
1025#==============================================================================
1026
1027class TestUpdateOps(unittest.TestCase):
1028 def setUp(self):
1029 self.set = set((2, 4, 6))
1030
1031 def test_union_subset(self):
1032 self.set |= set([2])
1033 self.assertEqual(self.set, set((2, 4, 6)))
1034
1035 def test_union_superset(self):
1036 self.set |= set([2, 4, 6, 8])
1037 self.assertEqual(self.set, set([2, 4, 6, 8]))
1038
1039 def test_union_overlap(self):
1040 self.set |= set([3, 4, 5])
1041 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1042
1043 def test_union_non_overlap(self):
1044 self.set |= set([8])
1045 self.assertEqual(self.set, set([2, 4, 6, 8]))
1046
1047 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001048 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +00001049 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1050
1051 def test_intersection_subset(self):
1052 self.set &= set((2, 4))
1053 self.assertEqual(self.set, set((2, 4)))
1054
1055 def test_intersection_superset(self):
1056 self.set &= set([2, 4, 6, 8])
1057 self.assertEqual(self.set, set([2, 4, 6]))
1058
1059 def test_intersection_overlap(self):
1060 self.set &= set([3, 4, 5])
1061 self.assertEqual(self.set, set([4]))
1062
1063 def test_intersection_non_overlap(self):
1064 self.set &= set([8])
1065 self.assertEqual(self.set, empty_set)
1066
1067 def test_intersection_method_call(self):
1068 self.set.intersection_update(set([3, 4, 5]))
1069 self.assertEqual(self.set, set([4]))
1070
1071 def test_sym_difference_subset(self):
1072 self.set ^= set((2, 4))
1073 self.assertEqual(self.set, set([6]))
1074
1075 def test_sym_difference_superset(self):
1076 self.set ^= set((2, 4, 6, 8))
1077 self.assertEqual(self.set, set([8]))
1078
1079 def test_sym_difference_overlap(self):
1080 self.set ^= set((3, 4, 5))
1081 self.assertEqual(self.set, set([2, 3, 5, 6]))
1082
1083 def test_sym_difference_non_overlap(self):
1084 self.set ^= set([8])
1085 self.assertEqual(self.set, set([2, 4, 6, 8]))
1086
1087 def test_sym_difference_method_call(self):
1088 self.set.symmetric_difference_update(set([3, 4, 5]))
1089 self.assertEqual(self.set, set([2, 3, 5, 6]))
1090
1091 def test_difference_subset(self):
1092 self.set -= set((2, 4))
1093 self.assertEqual(self.set, set([6]))
1094
1095 def test_difference_superset(self):
1096 self.set -= set((2, 4, 6, 8))
1097 self.assertEqual(self.set, set([]))
1098
1099 def test_difference_overlap(self):
1100 self.set -= set((3, 4, 5))
1101 self.assertEqual(self.set, set([2, 6]))
1102
1103 def test_difference_non_overlap(self):
1104 self.set -= set([8])
1105 self.assertEqual(self.set, set([2, 4, 6]))
1106
1107 def test_difference_method_call(self):
1108 self.set.difference_update(set([3, 4, 5]))
1109 self.assertEqual(self.set, set([2, 6]))
1110
1111#==============================================================================
1112
1113class TestMutate(unittest.TestCase):
1114 def setUp(self):
1115 self.values = ["a", "b", "c"]
1116 self.set = set(self.values)
1117
1118 def test_add_present(self):
1119 self.set.add("c")
1120 self.assertEqual(self.set, set("abc"))
1121
1122 def test_add_absent(self):
1123 self.set.add("d")
1124 self.assertEqual(self.set, set("abcd"))
1125
1126 def test_add_until_full(self):
1127 tmp = set()
1128 expected_len = 0
1129 for v in self.values:
1130 tmp.add(v)
1131 expected_len += 1
1132 self.assertEqual(len(tmp), expected_len)
1133 self.assertEqual(tmp, self.set)
1134
1135 def test_remove_present(self):
1136 self.set.remove("b")
1137 self.assertEqual(self.set, set("ac"))
1138
1139 def test_remove_absent(self):
1140 try:
1141 self.set.remove("d")
1142 self.fail("Removing missing element should have raised LookupError")
1143 except LookupError:
1144 pass
1145
1146 def test_remove_until_empty(self):
1147 expected_len = len(self.set)
1148 for v in self.values:
1149 self.set.remove(v)
1150 expected_len -= 1
1151 self.assertEqual(len(self.set), expected_len)
1152
1153 def test_discard_present(self):
1154 self.set.discard("c")
1155 self.assertEqual(self.set, set("ab"))
1156
1157 def test_discard_absent(self):
1158 self.set.discard("d")
1159 self.assertEqual(self.set, set("abc"))
1160
1161 def test_clear(self):
1162 self.set.clear()
1163 self.assertEqual(len(self.set), 0)
1164
1165 def test_pop(self):
1166 popped = {}
1167 while self.set:
1168 popped[self.set.pop()] = None
1169 self.assertEqual(len(popped), len(self.values))
1170 for v in self.values:
Ezio Melottiaa980582010-01-23 23:04:36 +00001171 self.assertIn(v, popped)
Raymond Hettingera690a992003-11-16 16:17:49 +00001172
1173 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001174 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001175 self.assertEqual(self.set, set(self.values))
1176
1177 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001178 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001179 self.assertEqual(self.set, set(self.values))
1180
1181 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001182 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001183 self.assertEqual(self.set, set(self.values + ["z"]))
1184
1185#==============================================================================
1186
1187class TestSubsets(unittest.TestCase):
1188
1189 case2method = {"<=": "issubset",
1190 ">=": "issuperset",
1191 }
1192
1193 reverse = {"==": "==",
1194 "!=": "!=",
1195 "<": ">",
1196 ">": "<",
1197 "<=": ">=",
1198 ">=": "<=",
1199 }
1200
1201 def test_issubset(self):
1202 x = self.left
1203 y = self.right
1204 for case in "!=", "==", "<", "<=", ">", ">=":
1205 expected = case in self.cases
1206 # Test the binary infix spelling.
1207 result = eval("x" + case + "y", locals())
1208 self.assertEqual(result, expected)
1209 # Test the "friendly" method-name spelling, if one exists.
1210 if case in TestSubsets.case2method:
1211 method = getattr(x, TestSubsets.case2method[case])
1212 result = method(y)
1213 self.assertEqual(result, expected)
1214
1215 # Now do the same for the operands reversed.
1216 rcase = TestSubsets.reverse[case]
1217 result = eval("y" + rcase + "x", locals())
1218 self.assertEqual(result, expected)
1219 if rcase in TestSubsets.case2method:
1220 method = getattr(y, TestSubsets.case2method[rcase])
1221 result = method(x)
1222 self.assertEqual(result, expected)
1223#------------------------------------------------------------------------------
1224
1225class TestSubsetEqualEmpty(TestSubsets):
1226 left = set()
1227 right = set()
1228 name = "both empty"
1229 cases = "==", "<=", ">="
1230
1231#------------------------------------------------------------------------------
1232
1233class TestSubsetEqualNonEmpty(TestSubsets):
1234 left = set([1, 2])
1235 right = set([1, 2])
1236 name = "equal pair"
1237 cases = "==", "<=", ">="
1238
1239#------------------------------------------------------------------------------
1240
1241class TestSubsetEmptyNonEmpty(TestSubsets):
1242 left = set()
1243 right = set([1, 2])
1244 name = "one empty, one non-empty"
1245 cases = "!=", "<", "<="
1246
1247#------------------------------------------------------------------------------
1248
1249class TestSubsetPartial(TestSubsets):
1250 left = set([1])
1251 right = set([1, 2])
1252 name = "one a non-empty proper subset of other"
1253 cases = "!=", "<", "<="
1254
1255#------------------------------------------------------------------------------
1256
1257class TestSubsetNonOverlap(TestSubsets):
1258 left = set([1])
1259 right = set([2])
1260 name = "neither empty, neither contains"
1261 cases = "!="
1262
1263#==============================================================================
1264
1265class TestOnlySetsInBinaryOps(unittest.TestCase):
1266
1267 def test_eq_ne(self):
1268 # Unlike the others, this is testing that == and != *are* allowed.
1269 self.assertEqual(self.other == self.set, False)
1270 self.assertEqual(self.set == self.other, False)
1271 self.assertEqual(self.other != self.set, True)
1272 self.assertEqual(self.set != self.other, True)
1273
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001274 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001275 try:
1276 self.set |= self.other
1277 except TypeError:
1278 pass
1279 else:
1280 self.fail("expected TypeError")
1281
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001282 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001283 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001284 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001285 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001286 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001287
1288 def test_union(self):
1289 self.assertRaises(TypeError, lambda: self.set | self.other)
1290 self.assertRaises(TypeError, lambda: self.other | self.set)
1291 if self.otherIsIterable:
1292 self.set.union(self.other)
1293 else:
1294 self.assertRaises(TypeError, self.set.union, self.other)
1295
1296 def test_intersection_update_operator(self):
1297 try:
1298 self.set &= self.other
1299 except TypeError:
1300 pass
1301 else:
1302 self.fail("expected TypeError")
1303
1304 def test_intersection_update(self):
1305 if self.otherIsIterable:
1306 self.set.intersection_update(self.other)
1307 else:
1308 self.assertRaises(TypeError,
1309 self.set.intersection_update,
1310 self.other)
1311
1312 def test_intersection(self):
1313 self.assertRaises(TypeError, lambda: self.set & self.other)
1314 self.assertRaises(TypeError, lambda: self.other & self.set)
1315 if self.otherIsIterable:
1316 self.set.intersection(self.other)
1317 else:
1318 self.assertRaises(TypeError, self.set.intersection, self.other)
1319
1320 def test_sym_difference_update_operator(self):
1321 try:
1322 self.set ^= self.other
1323 except TypeError:
1324 pass
1325 else:
1326 self.fail("expected TypeError")
1327
1328 def test_sym_difference_update(self):
1329 if self.otherIsIterable:
1330 self.set.symmetric_difference_update(self.other)
1331 else:
1332 self.assertRaises(TypeError,
1333 self.set.symmetric_difference_update,
1334 self.other)
1335
1336 def test_sym_difference(self):
1337 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1338 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1339 if self.otherIsIterable:
1340 self.set.symmetric_difference(self.other)
1341 else:
1342 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1343
1344 def test_difference_update_operator(self):
1345 try:
1346 self.set -= self.other
1347 except TypeError:
1348 pass
1349 else:
1350 self.fail("expected TypeError")
1351
1352 def test_difference_update(self):
1353 if self.otherIsIterable:
1354 self.set.difference_update(self.other)
1355 else:
1356 self.assertRaises(TypeError,
1357 self.set.difference_update,
1358 self.other)
1359
1360 def test_difference(self):
1361 self.assertRaises(TypeError, lambda: self.set - self.other)
1362 self.assertRaises(TypeError, lambda: self.other - self.set)
1363 if self.otherIsIterable:
1364 self.set.difference(self.other)
1365 else:
1366 self.assertRaises(TypeError, self.set.difference, self.other)
1367
1368#------------------------------------------------------------------------------
1369
1370class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1371 def setUp(self):
1372 self.set = set((1, 2, 3))
1373 self.other = 19
1374 self.otherIsIterable = False
1375
1376#------------------------------------------------------------------------------
1377
1378class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1379 def setUp(self):
1380 self.set = set((1, 2, 3))
1381 self.other = {1:2, 3:4}
1382 self.otherIsIterable = True
1383
1384#------------------------------------------------------------------------------
1385
Raymond Hettingera690a992003-11-16 16:17:49 +00001386class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1387 def setUp(self):
1388 self.set = set((1, 2, 3))
1389 self.other = (2, 4, 6)
1390 self.otherIsIterable = True
1391
1392#------------------------------------------------------------------------------
1393
1394class TestOnlySetsString(TestOnlySetsInBinaryOps):
1395 def setUp(self):
1396 self.set = set((1, 2, 3))
1397 self.other = 'abc'
1398 self.otherIsIterable = True
1399
1400#------------------------------------------------------------------------------
1401
1402class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1403 def setUp(self):
1404 def gen():
1405 for i in xrange(0, 10, 2):
1406 yield i
1407 self.set = set((1, 2, 3))
1408 self.other = gen()
1409 self.otherIsIterable = True
1410
1411#==============================================================================
1412
1413class TestCopying(unittest.TestCase):
1414
1415 def test_copy(self):
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001416 dup = list(self.set.copy())
1417 self.assertEqual(len(dup), len(self.set))
1418 for el in self.set:
1419 self.assertIn(el, dup)
1420 pos = dup.index(el)
1421 self.assertIs(el, dup.pop(pos))
1422 self.assertFalse(dup)
Raymond Hettingera690a992003-11-16 16:17:49 +00001423
1424 def test_deep_copy(self):
1425 dup = copy.deepcopy(self.set)
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001426 self.assertSetEqual(dup, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +00001427
1428#------------------------------------------------------------------------------
1429
1430class TestCopyingEmpty(TestCopying):
1431 def setUp(self):
1432 self.set = set()
1433
1434#------------------------------------------------------------------------------
1435
1436class TestCopyingSingleton(TestCopying):
1437 def setUp(self):
1438 self.set = set(["hello"])
1439
1440#------------------------------------------------------------------------------
1441
1442class TestCopyingTriple(TestCopying):
1443 def setUp(self):
1444 self.set = set(["zero", 0, None])
1445
1446#------------------------------------------------------------------------------
1447
1448class TestCopyingTuple(TestCopying):
1449 def setUp(self):
1450 self.set = set([(1, 2)])
1451
1452#------------------------------------------------------------------------------
1453
1454class TestCopyingNested(TestCopying):
1455 def setUp(self):
1456 self.set = set([((1, 2), (3, 4))])
1457
1458#==============================================================================
1459
1460class TestIdentities(unittest.TestCase):
1461 def setUp(self):
1462 self.a = set('abracadabra')
1463 self.b = set('alacazam')
1464
1465 def test_binopsVsSubsets(self):
1466 a, b = self.a, self.b
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001467 self.assertTrue(a - b < a)
1468 self.assertTrue(b - a < b)
1469 self.assertTrue(a & b < a)
1470 self.assertTrue(a & b < b)
1471 self.assertTrue(a | b > a)
1472 self.assertTrue(a | b > b)
1473 self.assertTrue(a ^ b < a | b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001474
1475 def test_commutativity(self):
1476 a, b = self.a, self.b
1477 self.assertEqual(a&b, b&a)
1478 self.assertEqual(a|b, b|a)
1479 self.assertEqual(a^b, b^a)
1480 if a != b:
1481 self.assertNotEqual(a-b, b-a)
1482
1483 def test_summations(self):
1484 # check that sums of parts equal the whole
1485 a, b = self.a, self.b
1486 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1487 self.assertEqual((a&b)|(a^b), a|b)
1488 self.assertEqual(a|(b-a), a|b)
1489 self.assertEqual((a-b)|b, a|b)
1490 self.assertEqual((a-b)|(a&b), a)
1491 self.assertEqual((b-a)|(a&b), b)
1492 self.assertEqual((a-b)|(b-a), a^b)
1493
1494 def test_exclusion(self):
1495 # check that inverse operations show non-overlap
1496 a, b, zero = self.a, self.b, set()
1497 self.assertEqual((a-b)&b, zero)
1498 self.assertEqual((b-a)&a, zero)
1499 self.assertEqual((a&b)&(a^b), zero)
1500
1501# Tests derived from test_itertools.py =======================================
1502
1503def R(seqn):
1504 'Regular generator'
1505 for i in seqn:
1506 yield i
1507
1508class G:
1509 'Sequence using __getitem__'
1510 def __init__(self, seqn):
1511 self.seqn = seqn
1512 def __getitem__(self, i):
1513 return self.seqn[i]
1514
1515class I:
1516 'Sequence using iterator protocol'
1517 def __init__(self, seqn):
1518 self.seqn = seqn
1519 self.i = 0
1520 def __iter__(self):
1521 return self
1522 def next(self):
1523 if self.i >= len(self.seqn): raise StopIteration
1524 v = self.seqn[self.i]
1525 self.i += 1
1526 return v
1527
1528class Ig:
1529 'Sequence using iterator protocol defined with a generator'
1530 def __init__(self, seqn):
1531 self.seqn = seqn
1532 self.i = 0
1533 def __iter__(self):
1534 for val in self.seqn:
1535 yield val
1536
1537class X:
1538 'Missing __getitem__ and __iter__'
1539 def __init__(self, seqn):
1540 self.seqn = seqn
1541 self.i = 0
1542 def next(self):
1543 if self.i >= len(self.seqn): raise StopIteration
1544 v = self.seqn[self.i]
1545 self.i += 1
1546 return v
1547
1548class N:
1549 'Iterator missing next()'
1550 def __init__(self, seqn):
1551 self.seqn = seqn
1552 self.i = 0
1553 def __iter__(self):
1554 return self
1555
1556class E:
1557 'Test propagation of exceptions'
1558 def __init__(self, seqn):
1559 self.seqn = seqn
1560 self.i = 0
1561 def __iter__(self):
1562 return self
1563 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001564 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001565
1566class S:
1567 'Test immediate stop'
1568 def __init__(self, seqn):
1569 pass
1570 def __iter__(self):
1571 return self
1572 def next(self):
1573 raise StopIteration
1574
1575from itertools import chain, imap
1576def L(seqn):
1577 'Test multiple tiers of iterators'
1578 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1579
1580class TestVariousIteratorArgs(unittest.TestCase):
1581
1582 def test_constructor(self):
1583 for cons in (set, frozenset):
1584 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1585 for g in (G, I, Ig, S, L, R):
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001586 self.assertSetEqual(cons(g(s)), set(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001587 self.assertRaises(TypeError, cons , X(s))
1588 self.assertRaises(TypeError, cons , N(s))
1589 self.assertRaises(ZeroDivisionError, cons , E(s))
1590
1591 def test_inline_methods(self):
1592 s = set('november')
1593 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001594 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001595 for g in (G, I, Ig, L, R):
1596 expected = meth(data)
Terry Jan Reedy807c9da2014-04-26 13:55:59 -04001597 actual = meth(g(data))
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001598 if isinstance(expected, bool):
1599 self.assertEqual(actual, expected)
1600 else:
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001601 self.assertSetEqual(actual, expected)
Raymond Hettingera690a992003-11-16 16:17:49 +00001602 self.assertRaises(TypeError, meth, X(s))
1603 self.assertRaises(TypeError, meth, N(s))
1604 self.assertRaises(ZeroDivisionError, meth, E(s))
1605
1606 def test_inplace_methods(self):
1607 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001608 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001609 'difference_update', 'symmetric_difference_update'):
1610 for g in (G, I, Ig, S, L, R):
1611 s = set('january')
1612 t = s.copy()
1613 getattr(s, methname)(list(g(data)))
1614 getattr(t, methname)(g(data))
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001615 self.assertSetEqual(s, t)
Raymond Hettingera690a992003-11-16 16:17:49 +00001616
1617 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1618 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1619 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1620
Éric Araujof079c9b2011-03-22 23:47:32 +01001621class bad_eq:
1622 def __eq__(self, other):
1623 if be_bad:
1624 set2.clear()
1625 raise ZeroDivisionError
1626 return self is other
1627 def __hash__(self):
1628 return 0
1629
1630class bad_dict_clear:
1631 def __eq__(self, other):
1632 if be_bad:
1633 dict2.clear()
1634 return self is other
1635 def __hash__(self):
1636 return 0
1637
1638class TestWeirdBugs(unittest.TestCase):
1639 def test_8420_set_merge(self):
1640 # This used to segfault
1641 global be_bad, set2, dict2
1642 be_bad = False
1643 set1 = {bad_eq()}
1644 set2 = {bad_eq() for i in range(75)}
1645 be_bad = True
1646 self.assertRaises(ZeroDivisionError, set1.update, set2)
1647
1648 be_bad = False
1649 set1 = {bad_dict_clear()}
1650 dict2 = {bad_dict_clear(): None}
1651 be_bad = True
1652 set1.symmetric_difference_update(dict2)
1653
Serhiy Storchakaa1b1e5f2015-07-08 22:58:55 +03001654 def test_iter_and_mutate(self):
1655 # Issue #24581
1656 s = set(range(100))
1657 s.clear()
1658 s.update(range(100))
1659 si = iter(s)
1660 s.clear()
1661 a = list(range(100))
1662 s.update(range(100))
1663 list(si)
1664
Raymond Hettinger61708742008-01-24 21:23:58 +00001665# Application tests (based on David Eppstein's graph recipes ====================================
1666
1667def powerset(U):
1668 """Generates all subsets of a set or sequence U."""
1669 U = iter(U)
1670 try:
1671 x = frozenset([U.next()])
1672 for S in powerset(U):
1673 yield S
1674 yield S | x
1675 except StopIteration:
1676 yield frozenset()
1677
1678def cube(n):
1679 """Graph of n-dimensional hypercube."""
1680 singletons = [frozenset([x]) for x in range(n)]
1681 return dict([(x, frozenset([x^s for s in singletons]))
1682 for x in powerset(range(n))])
1683
1684def linegraph(G):
1685 """Graph, the vertices of which are edges of G,
1686 with two vertices being adjacent iff the corresponding
1687 edges share a vertex."""
1688 L = {}
1689 for x in G:
1690 for y in G[x]:
1691 nx = [frozenset([x,z]) for z in G[x] if z != y]
1692 ny = [frozenset([y,z]) for z in G[y] if z != x]
1693 L[frozenset([x,y])] = frozenset(nx+ny)
1694 return L
1695
1696def faces(G):
1697 'Return a set of faces in G. Where a face is a set of vertices on that face'
1698 # currently limited to triangles,squares, and pentagons
1699 f = set()
1700 for v1, edges in G.items():
1701 for v2 in edges:
1702 for v3 in G[v2]:
1703 if v1 == v3:
1704 continue
1705 if v1 in G[v3]:
1706 f.add(frozenset([v1, v2, v3]))
1707 else:
1708 for v4 in G[v3]:
1709 if v4 == v2:
1710 continue
1711 if v1 in G[v4]:
1712 f.add(frozenset([v1, v2, v3, v4]))
1713 else:
1714 for v5 in G[v4]:
1715 if v5 == v3 or v5 == v2:
1716 continue
1717 if v1 in G[v5]:
1718 f.add(frozenset([v1, v2, v3, v4, v5]))
1719 return f
1720
1721
1722class TestGraphs(unittest.TestCase):
1723
1724 def test_cube(self):
1725
1726 g = cube(3) # vert --> {v1, v2, v3}
1727 vertices1 = set(g)
1728 self.assertEqual(len(vertices1), 8) # eight vertices
1729 for edge in g.values():
1730 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1731 vertices2 = set(v for edges in g.values() for v in edges)
1732 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1733
1734 cubefaces = faces(g)
1735 self.assertEqual(len(cubefaces), 6) # six faces
1736 for face in cubefaces:
1737 self.assertEqual(len(face), 4) # each face is a square
1738
1739 def test_cuboctahedron(self):
1740
1741 # http://en.wikipedia.org/wiki/Cuboctahedron
1742 # 8 triangular faces and 6 square faces
Martin Panterb1d867f2016-05-26 05:28:50 +00001743 # 12 identical vertices each connecting a triangle and square
Raymond Hettinger61708742008-01-24 21:23:58 +00001744
1745 g = cube(3)
1746 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1747 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1748
1749 vertices = set(cuboctahedron)
1750 for edges in cuboctahedron.values():
1751 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1752 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1753 self.assertEqual(vertices, othervertices) # edge vertices in original set
1754
1755 cubofaces = faces(cuboctahedron)
1756 facesizes = collections.defaultdict(int)
1757 for face in cubofaces:
1758 facesizes[len(face)] += 1
1759 self.assertEqual(facesizes[3], 8) # eight triangular faces
1760 self.assertEqual(facesizes[4], 6) # six square faces
1761
1762 for vertex in cuboctahedron:
1763 edge = vertex # Cuboctahedron vertices are edges in Cube
1764 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1765 for cubevert in edge:
Ezio Melottiaa980582010-01-23 23:04:36 +00001766 self.assertIn(cubevert, g)
Raymond Hettinger61708742008-01-24 21:23:58 +00001767
1768
Raymond Hettingera690a992003-11-16 16:17:49 +00001769#==============================================================================
1770
1771def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001772 test_classes = (
1773 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001774 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001775 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001776 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001777 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001778 TestSetOfSets,
1779 TestExceptionPropagation,
1780 TestBasicOpsEmpty,
1781 TestBasicOpsSingleton,
1782 TestBasicOpsTuple,
1783 TestBasicOpsTriple,
1784 TestBinaryOps,
1785 TestUpdateOps,
1786 TestMutate,
1787 TestSubsetEqualEmpty,
1788 TestSubsetEqualNonEmpty,
1789 TestSubsetEmptyNonEmpty,
1790 TestSubsetPartial,
1791 TestSubsetNonOverlap,
1792 TestOnlySetsNumeric,
1793 TestOnlySetsDict,
Raymond Hettingera690a992003-11-16 16:17:49 +00001794 TestOnlySetsTuple,
1795 TestOnlySetsString,
1796 TestOnlySetsGenerator,
1797 TestCopyingEmpty,
1798 TestCopyingSingleton,
1799 TestCopyingTriple,
1800 TestCopyingTuple,
1801 TestCopyingNested,
1802 TestIdentities,
1803 TestVariousIteratorArgs,
Raymond Hettinger61708742008-01-24 21:23:58 +00001804 TestGraphs,
Éric Araujof079c9b2011-03-22 23:47:32 +01001805 TestWeirdBugs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001806 )
1807
1808 test_support.run_unittest(*test_classes)
1809
1810 # verify reference counting
1811 if verbose and hasattr(sys, "gettotalrefcount"):
1812 import gc
1813 counts = [None] * 5
1814 for i in xrange(len(counts)):
1815 test_support.run_unittest(*test_classes)
1816 gc.collect()
1817 counts[i] = sys.gettotalrefcount()
1818 print counts
1819
1820if __name__ == "__main__":
1821 test_main(verbose=True)