blob: 1548a65b72a76d5261b6ef682035d564645e32ef [file] [log] [blame]
Raymond Hettingera690a992003-11-16 16:17:49 +00001import unittest
2from test import test_support
Antoine Pitrouaa687902009-01-01 14:11:22 +00003import gc
4import weakref
Raymond Hettingera690a992003-11-16 16:17:49 +00005import operator
6import copy
7import pickle
Raymond Hettinger82cb9a22005-07-05 05:34:43 +00008from random import randrange, shuffle
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00009import sys
Raymond Hettinger61708742008-01-24 21:23:58 +000010import collections
Raymond Hettingera690a992003-11-16 16:17:49 +000011
12class PassThru(Exception):
13 pass
14
15def check_pass_thru():
16 raise PassThru
17 yield 1
18
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000019class BadCmp:
20 def __hash__(self):
21 return 1
22 def __cmp__(self, other):
23 raise RuntimeError
24
Raymond Hettinger53999102006-12-30 04:01:17 +000025class ReprWrapper:
26 'Used to test self-referential repr() calls'
27 def __repr__(self):
28 return repr(self.value)
29
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +000030class HashCountingInt(int):
31 'int-like object that counts the number of times __hash__ is called'
32 def __init__(self, *args):
33 self.hash_count = 0
34 def __hash__(self):
35 self.hash_count += 1
36 return int.__hash__(self)
37
Raymond Hettingera690a992003-11-16 16:17:49 +000038class TestJointOps(unittest.TestCase):
39 # Tests common to both set and frozenset
40
41 def setUp(self):
42 self.word = word = 'simsalabim'
43 self.otherword = 'madagascar'
44 self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
45 self.s = self.thetype(word)
46 self.d = dict.fromkeys(word)
47
Raymond Hettinger6429a472004-09-28 01:51:35 +000048 def test_new_or_init(self):
49 self.assertRaises(TypeError, self.thetype, [], 2)
50
Raymond Hettingera690a992003-11-16 16:17:49 +000051 def test_uniquification(self):
Raymond Hettinger64958a12003-12-17 20:43:33 +000052 actual = sorted(self.s)
53 expected = sorted(self.d)
Raymond Hettingera690a992003-11-16 16:17:49 +000054 self.assertEqual(actual, expected)
55 self.assertRaises(PassThru, self.thetype, check_pass_thru())
56 self.assertRaises(TypeError, self.thetype, [[]])
57
58 def test_len(self):
59 self.assertEqual(len(self.s), len(self.d))
60
61 def test_contains(self):
62 for c in self.letters:
63 self.assertEqual(c in self.s, c in self.d)
64 self.assertRaises(TypeError, self.s.__contains__, [[]])
Raymond Hettinger19c2d772003-11-21 18:36:54 +000065 s = self.thetype([frozenset(self.letters)])
Ezio Melottiaa980582010-01-23 23:04:36 +000066 self.assertIn(self.thetype(self.letters), s)
Raymond Hettingera690a992003-11-16 16:17:49 +000067
Raymond Hettingera690a992003-11-16 16:17:49 +000068 def test_union(self):
69 u = self.s.union(self.otherword)
70 for c in self.letters:
71 self.assertEqual(c in u, c in self.d or c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000072 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000073 self.assertEqual(type(u), self.thetype)
74 self.assertRaises(PassThru, self.s.union, check_pass_thru())
75 self.assertRaises(TypeError, self.s.union, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000076 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
77 self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
78 self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
79 self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
80 self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +000081 self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
Raymond Hettingera690a992003-11-16 16:17:49 +000082
Raymond Hettingerc2b9e1a2009-07-27 20:32:04 +000083 # Issue #6573
84 x = self.thetype()
85 self.assertEqual(x.union(set([1]), x, set([2])), self.thetype([1, 2]))
86
Raymond Hettingera690a992003-11-16 16:17:49 +000087 def test_or(self):
88 i = self.s.union(self.otherword)
89 self.assertEqual(self.s | set(self.otherword), i)
90 self.assertEqual(self.s | frozenset(self.otherword), i)
91 try:
92 self.s | self.otherword
93 except TypeError:
94 pass
95 else:
96 self.fail("s|t did not screen-out general iterables")
97
98 def test_intersection(self):
99 i = self.s.intersection(self.otherword)
100 for c in self.letters:
101 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000102 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000103 self.assertEqual(type(i), self.thetype)
104 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000105 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
106 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
107 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
108 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
109 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000110 self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
Raymond Hettinger610a93e2008-06-11 00:44:47 +0000111 s = self.thetype('abcba')
112 z = s.intersection()
113 if self.thetype == frozenset():
114 self.assertEqual(id(s), id(z))
115 else:
116 self.assertNotEqual(id(s), id(z))
Raymond Hettingera690a992003-11-16 16:17:49 +0000117
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000118 def test_isdisjoint(self):
119 def f(s1, s2):
120 'Pure python equivalent of isdisjoint()'
121 return not set(s1).intersection(s2)
122 for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
123 s1 = self.thetype(larg)
124 for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
125 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
126 s2 = C(rarg)
127 actual = s1.isdisjoint(s2)
128 expected = f(s1, s2)
129 self.assertEqual(actual, expected)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000130 self.assertTrue(actual is True or actual is False)
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000131
Raymond Hettingera690a992003-11-16 16:17:49 +0000132 def test_and(self):
133 i = self.s.intersection(self.otherword)
134 self.assertEqual(self.s & set(self.otherword), i)
135 self.assertEqual(self.s & frozenset(self.otherword), i)
136 try:
137 self.s & self.otherword
138 except TypeError:
139 pass
140 else:
141 self.fail("s&t did not screen-out general iterables")
142
143 def test_difference(self):
144 i = self.s.difference(self.otherword)
145 for c in self.letters:
146 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000147 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000148 self.assertEqual(type(i), self.thetype)
149 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
150 self.assertRaises(TypeError, self.s.difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000151 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
152 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
153 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
154 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
155 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettinger4267be62008-06-11 10:30:54 +0000156 self.assertEqual(self.thetype('abcba').difference(), set('abc'))
157 self.assertEqual(self.thetype('abcba').difference(C('a'), C('b')), set('c'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000158
159 def test_sub(self):
160 i = self.s.difference(self.otherword)
161 self.assertEqual(self.s - set(self.otherword), i)
162 self.assertEqual(self.s - frozenset(self.otherword), i)
163 try:
164 self.s - self.otherword
165 except TypeError:
166 pass
167 else:
168 self.fail("s-t did not screen-out general iterables")
169
170 def test_symmetric_difference(self):
171 i = self.s.symmetric_difference(self.otherword)
172 for c in self.letters:
173 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000174 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000175 self.assertEqual(type(i), self.thetype)
176 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
177 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000178 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
179 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
180 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
181 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
182 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000183
184 def test_xor(self):
185 i = self.s.symmetric_difference(self.otherword)
186 self.assertEqual(self.s ^ set(self.otherword), i)
187 self.assertEqual(self.s ^ frozenset(self.otherword), i)
188 try:
189 self.s ^ self.otherword
190 except TypeError:
191 pass
192 else:
193 self.fail("s^t did not screen-out general iterables")
194
195 def test_equality(self):
196 self.assertEqual(self.s, set(self.word))
197 self.assertEqual(self.s, frozenset(self.word))
198 self.assertEqual(self.s == self.word, False)
199 self.assertNotEqual(self.s, set(self.otherword))
200 self.assertNotEqual(self.s, frozenset(self.otherword))
201 self.assertEqual(self.s != self.word, True)
202
203 def test_setOfFrozensets(self):
204 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
205 s = self.thetype(t)
206 self.assertEqual(len(s), 3)
207
208 def test_compare(self):
209 self.assertRaises(TypeError, self.s.__cmp__, self.s)
210
211 def test_sub_and_super(self):
212 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000213 self.assertTrue(p < q)
214 self.assertTrue(p <= q)
215 self.assertTrue(q <= q)
216 self.assertTrue(q > p)
217 self.assertTrue(q >= p)
218 self.assertFalse(q < r)
219 self.assertFalse(q <= r)
220 self.assertFalse(q > r)
221 self.assertFalse(q >= r)
222 self.assertTrue(set('a').issubset('abc'))
223 self.assertTrue(set('abc').issuperset('a'))
224 self.assertFalse(set('a').issubset('cbs'))
225 self.assertFalse(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000226
227 def test_pickling(self):
Hirokazu Yamamoto0fc07472008-12-27 04:19:48 +0000228 for i in range(pickle.HIGHEST_PROTOCOL + 1):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000229 p = pickle.dumps(self.s, i)
230 dup = pickle.loads(p)
231 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
232 if type(self.s) not in (set, frozenset):
233 self.s.x = 10
234 p = pickle.dumps(self.s)
235 dup = pickle.loads(p)
236 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000237
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000238 def test_deepcopy(self):
239 class Tracer:
240 def __init__(self, value):
241 self.value = value
242 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000243 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000244 def __deepcopy__(self, memo=None):
245 return Tracer(self.value + 1)
246 t = Tracer(10)
247 s = self.thetype([t])
248 dup = copy.deepcopy(s)
249 self.assertNotEqual(id(s), id(dup))
250 for elem in dup:
251 newt = elem
252 self.assertNotEqual(id(t), id(newt))
253 self.assertEqual(t.value + 1, newt.value)
254
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000255 def test_gc(self):
256 # Create a nest of cycles to exercise overall ref count check
257 class A:
258 pass
259 s = set(A() for i in xrange(1000))
260 for elem in s:
261 elem.cycle = s
262 elem.sub = elem
263 elem.set = set([elem])
264
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000265 def test_subclass_with_custom_hash(self):
266 # Bug #1257731
267 class H(self.thetype):
268 def __hash__(self):
Tim Peters6902b442006-04-11 00:43:27 +0000269 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000270 s=H()
271 f=set()
272 f.add(s)
Ezio Melottiaa980582010-01-23 23:04:36 +0000273 self.assertIn(s, f)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000274 f.remove(s)
275 f.add(s)
276 f.discard(s)
277
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000278 def test_badcmp(self):
279 s = self.thetype([BadCmp()])
280 # Detect comparison errors during insertion and lookup
281 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
282 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
283 # Detect errors during mutating operations
284 if hasattr(s, 'add'):
285 self.assertRaises(RuntimeError, s.add, BadCmp())
286 self.assertRaises(RuntimeError, s.discard, BadCmp())
287 self.assertRaises(RuntimeError, s.remove, BadCmp())
288
Raymond Hettinger53999102006-12-30 04:01:17 +0000289 def test_cyclical_repr(self):
290 w = ReprWrapper()
291 s = self.thetype([w])
292 w.value = s
293 name = repr(s).partition('(')[0] # strip class name from repr string
294 self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
295
296 def test_cyclical_print(self):
297 w = ReprWrapper()
298 s = self.thetype([w])
299 w.value = s
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000300 fo = open(test_support.TESTFN, "wb")
Raymond Hettinger53999102006-12-30 04:01:17 +0000301 try:
Raymond Hettinger53999102006-12-30 04:01:17 +0000302 print >> fo, s,
303 fo.close()
304 fo = open(test_support.TESTFN, "rb")
305 self.assertEqual(fo.read(), repr(s))
306 finally:
307 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000308 test_support.unlink(test_support.TESTFN)
Raymond Hettinger53999102006-12-30 04:01:17 +0000309
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000310 def test_do_not_rehash_dict_keys(self):
311 n = 10
312 d = dict.fromkeys(map(HashCountingInt, xrange(n)))
313 self.assertEqual(sum(elem.hash_count for elem in d), n)
314 s = self.thetype(d)
315 self.assertEqual(sum(elem.hash_count for elem in d), n)
316 s.difference(d)
Tim Petersea5962f2007-03-12 18:07:52 +0000317 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000318 if hasattr(s, 'symmetric_difference_update'):
319 s.symmetric_difference_update(d)
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000320 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettinger0bbbfc42007-03-20 21:27:24 +0000321 d2 = dict.fromkeys(set(d))
322 self.assertEqual(sum(elem.hash_count for elem in d), n)
323 d3 = dict.fromkeys(frozenset(d))
Tim Petersea5962f2007-03-12 18:07:52 +0000324 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingere3146f52007-03-21 20:33:57 +0000325 d3 = dict.fromkeys(frozenset(d), 123)
326 self.assertEqual(sum(elem.hash_count for elem in d), n)
327 self.assertEqual(d3, dict.fromkeys(d, 123))
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000328
Antoine Pitrouaa687902009-01-01 14:11:22 +0000329 def test_container_iterator(self):
Antoine Pitrou733dc742009-01-01 15:38:03 +0000330 # Bug #3680: tp_traverse was not implemented for set iterator object
Antoine Pitrouaa687902009-01-01 14:11:22 +0000331 class C(object):
332 pass
333 obj = C()
334 ref = weakref.ref(obj)
335 container = set([obj, 1])
336 obj.x = iter(container)
337 del obj, container
338 gc.collect()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000339 self.assertTrue(ref() is None, "Cycle was not collected")
Antoine Pitrouaa687902009-01-01 14:11:22 +0000340
Raymond Hettingera690a992003-11-16 16:17:49 +0000341class TestSet(TestJointOps):
342 thetype = set
343
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000344 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000345 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000346 s.__init__(self.word)
347 self.assertEqual(s, set(self.word))
348 s.__init__(self.otherword)
349 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000350 self.assertRaises(TypeError, s.__init__, s, 2);
351 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000352
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000353 def test_constructor_identity(self):
354 s = self.thetype(range(3))
355 t = self.thetype(s)
356 self.assertNotEqual(id(s), id(t))
357
Raymond Hettingera690a992003-11-16 16:17:49 +0000358 def test_hash(self):
359 self.assertRaises(TypeError, hash, self.s)
360
361 def test_clear(self):
362 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000363 self.assertEqual(self.s, set())
364 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000365
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000366 def test_copy(self):
367 dup = self.s.copy()
368 self.assertEqual(self.s, dup)
369 self.assertNotEqual(id(self.s), id(dup))
370
Raymond Hettingera690a992003-11-16 16:17:49 +0000371 def test_add(self):
372 self.s.add('Q')
Ezio Melottiaa980582010-01-23 23:04:36 +0000373 self.assertIn('Q', self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000374 dup = self.s.copy()
375 self.s.add('Q')
376 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000377 self.assertRaises(TypeError, self.s.add, [])
378
379 def test_remove(self):
380 self.s.remove('a')
Ezio Melottiaa980582010-01-23 23:04:36 +0000381 self.assertNotIn('a', self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000382 self.assertRaises(KeyError, self.s.remove, 'Q')
383 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000384 s = self.thetype([frozenset(self.word)])
Ezio Melottiaa980582010-01-23 23:04:36 +0000385 self.assertIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000386 s.remove(self.thetype(self.word))
Ezio Melottiaa980582010-01-23 23:04:36 +0000387 self.assertNotIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000388 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000389
Raymond Hettingerc789f342006-12-08 17:35:25 +0000390 def test_remove_keyerror_unpacking(self):
391 # bug: www.python.org/sf/1576657
392 for v1 in ['Q', (1,)]:
393 try:
394 self.s.remove(v1)
395 except KeyError, e:
396 v2 = e.args[0]
397 self.assertEqual(v1, v2)
398 else:
399 self.fail()
400
Amaury Forgeot d'Arcd78b9dc2008-10-07 20:32:10 +0000401 def test_remove_keyerror_set(self):
402 key = self.thetype([3, 4])
403 try:
404 self.s.remove(key)
405 except KeyError as e:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000406 self.assertTrue(e.args[0] is key,
Amaury Forgeot d'Arcd78b9dc2008-10-07 20:32:10 +0000407 "KeyError should be {0}, not {1}".format(key,
408 e.args[0]))
409 else:
410 self.fail()
411
Raymond Hettingera690a992003-11-16 16:17:49 +0000412 def test_discard(self):
413 self.s.discard('a')
Ezio Melottiaa980582010-01-23 23:04:36 +0000414 self.assertNotIn('a', self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000415 self.s.discard('Q')
416 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000417 s = self.thetype([frozenset(self.word)])
Ezio Melottiaa980582010-01-23 23:04:36 +0000418 self.assertIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000419 s.discard(self.thetype(self.word))
Ezio Melottiaa980582010-01-23 23:04:36 +0000420 self.assertNotIn(self.thetype(self.word), s)
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000421 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000422
423 def test_pop(self):
424 for i in xrange(len(self.s)):
425 elem = self.s.pop()
Ezio Melottiaa980582010-01-23 23:04:36 +0000426 self.assertNotIn(elem, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000427 self.assertRaises(KeyError, self.s.pop)
428
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000429 def test_update(self):
430 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000431 self.assertEqual(retval, None)
432 for c in (self.word + self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000433 self.assertIn(c, self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000434 self.assertRaises(PassThru, self.s.update, check_pass_thru())
435 self.assertRaises(TypeError, self.s.update, [[]])
436 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
437 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
438 s = self.thetype('abcba')
439 self.assertEqual(s.update(C(p)), None)
440 self.assertEqual(s, set(q))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +0000441 for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
442 q = 'ahi'
443 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
444 s = self.thetype('abcba')
445 self.assertEqual(s.update(C(p), C(q)), None)
446 self.assertEqual(s, set(s) | set(p) | set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000447
448 def test_ior(self):
449 self.s |= set(self.otherword)
450 for c in (self.word + self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000451 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000452
453 def test_intersection_update(self):
454 retval = self.s.intersection_update(self.otherword)
455 self.assertEqual(retval, None)
456 for c in (self.word + self.otherword):
457 if c in self.otherword and c in self.word:
Ezio Melottiaa980582010-01-23 23:04:36 +0000458 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000459 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000460 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000461 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
462 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000463 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
464 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
465 s = self.thetype('abcba')
466 self.assertEqual(s.intersection_update(C(p)), None)
467 self.assertEqual(s, set(q))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000468 ss = 'abcba'
469 s = self.thetype(ss)
470 t = 'cbc'
471 self.assertEqual(s.intersection_update(C(p), C(t)), None)
472 self.assertEqual(s, set('abcba')&set(p)&set(t))
Raymond Hettingera690a992003-11-16 16:17:49 +0000473
474 def test_iand(self):
475 self.s &= set(self.otherword)
476 for c in (self.word + self.otherword):
477 if c in self.otherword and c in self.word:
Ezio Melottiaa980582010-01-23 23:04:36 +0000478 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000479 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000480 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000481
482 def test_difference_update(self):
483 retval = self.s.difference_update(self.otherword)
484 self.assertEqual(retval, None)
485 for c in (self.word + self.otherword):
486 if c in self.word and c not in self.otherword:
Ezio Melottiaa980582010-01-23 23:04:36 +0000487 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000488 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000489 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000490 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
491 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000492 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
493 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
494 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
495 s = self.thetype('abcba')
496 self.assertEqual(s.difference_update(C(p)), None)
497 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000498
Raymond Hettinger4267be62008-06-11 10:30:54 +0000499 s = self.thetype('abcdefghih')
500 s.difference_update()
501 self.assertEqual(s, self.thetype('abcdefghih'))
502
503 s = self.thetype('abcdefghih')
504 s.difference_update(C('aba'))
505 self.assertEqual(s, self.thetype('cdefghih'))
506
507 s = self.thetype('abcdefghih')
508 s.difference_update(C('cdc'), C('aba'))
509 self.assertEqual(s, self.thetype('efghih'))
510
Raymond Hettingera690a992003-11-16 16:17:49 +0000511 def test_isub(self):
512 self.s -= set(self.otherword)
513 for c in (self.word + self.otherword):
514 if c in self.word and c not in self.otherword:
Ezio Melottiaa980582010-01-23 23:04:36 +0000515 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000516 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000517 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000518
519 def test_symmetric_difference_update(self):
520 retval = self.s.symmetric_difference_update(self.otherword)
521 self.assertEqual(retval, None)
522 for c in (self.word + self.otherword):
523 if (c in self.word) ^ (c in self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000524 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000525 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000526 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000527 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
528 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000529 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
530 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
531 s = self.thetype('abcba')
532 self.assertEqual(s.symmetric_difference_update(C(p)), None)
533 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000534
535 def test_ixor(self):
536 self.s ^= set(self.otherword)
537 for c in (self.word + self.otherword):
538 if (c in self.word) ^ (c in self.otherword):
Ezio Melottiaa980582010-01-23 23:04:36 +0000539 self.assertIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000540 else:
Ezio Melottiaa980582010-01-23 23:04:36 +0000541 self.assertNotIn(c, self.s)
Raymond Hettingera690a992003-11-16 16:17:49 +0000542
Raymond Hettingerc991db22005-08-11 07:58:45 +0000543 def test_inplace_on_self(self):
544 t = self.s.copy()
545 t |= t
546 self.assertEqual(t, self.s)
547 t &= t
548 self.assertEqual(t, self.s)
549 t -= t
550 self.assertEqual(t, self.thetype())
551 t = self.s.copy()
552 t ^= t
553 self.assertEqual(t, self.thetype())
554
Raymond Hettinger691d8052004-05-30 07:26:47 +0000555 def test_weakref(self):
556 s = self.thetype('gallahad')
Antoine Pitrouaa687902009-01-01 14:11:22 +0000557 p = weakref.proxy(s)
Raymond Hettinger691d8052004-05-30 07:26:47 +0000558 self.assertEqual(str(p), str(s))
559 s = None
560 self.assertRaises(ReferenceError, str, p)
561
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000562 # C API test only available in a debug build
Barry Warsaw176014f2006-03-30 22:45:35 +0000563 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000564 def test_c_api(self):
Victor Stinner17d90542010-03-13 00:13:22 +0000565 self.assertEqual(set().test_c_api(), True)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000566
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000567class SetSubclass(set):
568 pass
569
570class TestSetSubclass(TestSet):
571 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000572
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000573class SetSubclassWithKeywordArgs(set):
574 def __init__(self, iterable=[], newarg=None):
575 set.__init__(self, iterable)
576
577class TestSetSubclassWithKeywordArgs(TestSet):
Tim Petersf733abb2007-01-30 03:03:46 +0000578
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000579 def test_keywords_in_subclass(self):
580 'SF bug #1486663 -- this used to erroneously raise a TypeError'
581 SetSubclassWithKeywordArgs(newarg=1)
582
Raymond Hettingera690a992003-11-16 16:17:49 +0000583class TestFrozenSet(TestJointOps):
584 thetype = frozenset
585
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000586 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000587 s = self.thetype(self.word)
588 s.__init__(self.otherword)
589 self.assertEqual(s, set(self.word))
590
Raymond Hettingerd7946662005-08-01 21:39:29 +0000591 def test_singleton_empty_frozenset(self):
592 f = frozenset()
593 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
594 frozenset(), frozenset([]), frozenset(()), frozenset(''),
595 frozenset(xrange(0)), frozenset(frozenset()),
596 frozenset(f), f]
597 # All of the empty frozensets should have just one id()
598 self.assertEqual(len(set(map(id, efs))), 1)
599
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000600 def test_constructor_identity(self):
601 s = self.thetype(range(3))
602 t = self.thetype(s)
603 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000604
Raymond Hettingera690a992003-11-16 16:17:49 +0000605 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000606 self.assertEqual(hash(self.thetype('abcdeb')),
607 hash(self.thetype('ebecda')))
608
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000609 # make sure that all permutations give the same hash value
610 n = 100
611 seq = [randrange(n) for i in xrange(n)]
612 results = set()
613 for i in xrange(200):
614 shuffle(seq)
615 results.add(hash(self.thetype(seq)))
616 self.assertEqual(len(results), 1)
617
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000618 def test_copy(self):
619 dup = self.s.copy()
620 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000621
622 def test_frozen_as_dictkey(self):
623 seq = range(10) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000624 key1 = self.thetype(seq)
625 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000626 self.assertEqual(key1, key2)
627 self.assertNotEqual(id(key1), id(key2))
628 d = {}
629 d[key1] = 42
630 self.assertEqual(d[key2], 42)
631
632 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000633 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000634 self.assertEqual(hash(f), hash(f))
635
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000636 def test_hash_effectiveness(self):
637 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000638 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000639 addhashvalue = hashvalues.add
640 elemmasks = [(i+1, 1<<i) for i in range(n)]
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000641 for i in xrange(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000642 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
643 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000644
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000645class FrozenSetSubclass(frozenset):
646 pass
647
648class TestFrozenSetSubclass(TestFrozenSet):
649 thetype = FrozenSetSubclass
650
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000651 def test_constructor_identity(self):
652 s = self.thetype(range(3))
653 t = self.thetype(s)
654 self.assertNotEqual(id(s), id(t))
655
656 def test_copy(self):
657 dup = self.s.copy()
658 self.assertNotEqual(id(self.s), id(dup))
659
660 def test_nested_empty_constructor(self):
661 s = self.thetype()
662 t = self.thetype(s)
663 self.assertEqual(s, t)
664
Raymond Hettingerd7946662005-08-01 21:39:29 +0000665 def test_singleton_empty_frozenset(self):
666 Frozenset = self.thetype
667 f = frozenset()
668 F = Frozenset()
669 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
670 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
671 Frozenset(xrange(0)), Frozenset(Frozenset()),
672 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
673 # All empty frozenset subclass instances should have different ids
674 self.assertEqual(len(set(map(id, efs))), len(efs))
675
Raymond Hettingera690a992003-11-16 16:17:49 +0000676# Tests taken from test_sets.py =============================================
677
678empty_set = set()
679
680#==============================================================================
681
682class TestBasicOps(unittest.TestCase):
683
684 def test_repr(self):
685 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000686 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000687
Raymond Hettingereae05de2004-07-09 04:51:24 +0000688 def test_print(self):
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000689 fo = open(test_support.TESTFN, "wb")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000690 try:
Raymond Hettingereae05de2004-07-09 04:51:24 +0000691 print >> fo, self.set,
692 fo.close()
693 fo = open(test_support.TESTFN, "rb")
694 self.assertEqual(fo.read(), repr(self.set))
695 finally:
696 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000697 test_support.unlink(test_support.TESTFN)
Raymond Hettingereae05de2004-07-09 04:51:24 +0000698
Raymond Hettingera690a992003-11-16 16:17:49 +0000699 def test_length(self):
700 self.assertEqual(len(self.set), self.length)
701
702 def test_self_equality(self):
703 self.assertEqual(self.set, self.set)
704
705 def test_equivalent_equality(self):
706 self.assertEqual(self.set, self.dup)
707
708 def test_copy(self):
709 self.assertEqual(self.set.copy(), self.dup)
710
711 def test_self_union(self):
712 result = self.set | self.set
713 self.assertEqual(result, self.dup)
714
715 def test_empty_union(self):
716 result = self.set | empty_set
717 self.assertEqual(result, self.dup)
718
719 def test_union_empty(self):
720 result = empty_set | self.set
721 self.assertEqual(result, self.dup)
722
723 def test_self_intersection(self):
724 result = self.set & self.set
725 self.assertEqual(result, self.dup)
726
727 def test_empty_intersection(self):
728 result = self.set & empty_set
729 self.assertEqual(result, empty_set)
730
731 def test_intersection_empty(self):
732 result = empty_set & self.set
733 self.assertEqual(result, empty_set)
734
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000735 def test_self_isdisjoint(self):
736 result = self.set.isdisjoint(self.set)
737 self.assertEqual(result, not self.set)
738
739 def test_empty_isdisjoint(self):
740 result = self.set.isdisjoint(empty_set)
741 self.assertEqual(result, True)
742
743 def test_isdisjoint_empty(self):
744 result = empty_set.isdisjoint(self.set)
745 self.assertEqual(result, True)
746
Raymond Hettingera690a992003-11-16 16:17:49 +0000747 def test_self_symmetric_difference(self):
748 result = self.set ^ self.set
749 self.assertEqual(result, empty_set)
750
751 def checkempty_symmetric_difference(self):
752 result = self.set ^ empty_set
753 self.assertEqual(result, self.set)
754
755 def test_self_difference(self):
756 result = self.set - self.set
757 self.assertEqual(result, empty_set)
758
759 def test_empty_difference(self):
760 result = self.set - empty_set
761 self.assertEqual(result, self.dup)
762
763 def test_empty_difference_rev(self):
764 result = empty_set - self.set
765 self.assertEqual(result, empty_set)
766
767 def test_iteration(self):
768 for v in self.set:
Ezio Melottiaa980582010-01-23 23:04:36 +0000769 self.assertIn(v, self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000770 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000771 # note: __length_hint__ is an internal undocumented API,
772 # don't rely on it in your own programs
773 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000774
775 def test_pickling(self):
776 p = pickle.dumps(self.set)
777 copy = pickle.loads(p)
778 self.assertEqual(self.set, copy,
779 "%s != %s" % (self.set, copy))
780
781#------------------------------------------------------------------------------
782
783class TestBasicOpsEmpty(TestBasicOps):
784 def setUp(self):
785 self.case = "empty set"
786 self.values = []
787 self.set = set(self.values)
788 self.dup = set(self.values)
789 self.length = 0
790 self.repr = "set([])"
791
792#------------------------------------------------------------------------------
793
794class TestBasicOpsSingleton(TestBasicOps):
795 def setUp(self):
796 self.case = "unit set (number)"
797 self.values = [3]
798 self.set = set(self.values)
799 self.dup = set(self.values)
800 self.length = 1
801 self.repr = "set([3])"
802
803 def test_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000804 self.assertIn(3, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000805
806 def test_not_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000807 self.assertNotIn(2, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000808
809#------------------------------------------------------------------------------
810
811class TestBasicOpsTuple(TestBasicOps):
812 def setUp(self):
813 self.case = "unit set (tuple)"
814 self.values = [(0, "zero")]
815 self.set = set(self.values)
816 self.dup = set(self.values)
817 self.length = 1
818 self.repr = "set([(0, 'zero')])"
819
820 def test_in(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000821 self.assertIn((0, "zero"), 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(9, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +0000825
826#------------------------------------------------------------------------------
827
828class TestBasicOpsTriple(TestBasicOps):
829 def setUp(self):
830 self.case = "triple set"
831 self.values = [0, "zero", operator.add]
832 self.set = set(self.values)
833 self.dup = set(self.values)
834 self.length = 3
835 self.repr = None
836
837#==============================================================================
838
839def baditer():
840 raise TypeError
841 yield True
842
843def gooditer():
844 yield True
845
846class TestExceptionPropagation(unittest.TestCase):
847 """SF 628246: Set constructor should not trap iterator TypeErrors"""
848
849 def test_instanceWithException(self):
850 self.assertRaises(TypeError, set, baditer())
851
852 def test_instancesWithoutException(self):
853 # All of these iterables should load without exception.
854 set([1,2,3])
855 set((1,2,3))
856 set({'one':1, 'two':2, 'three':3})
857 set(xrange(3))
858 set('abc')
859 set(gooditer())
860
Neal Norwitzfcf44352005-11-27 20:37:43 +0000861 def test_changingSizeWhileIterating(self):
862 s = set([1,2,3])
863 try:
864 for i in s:
865 s.update([4])
866 except RuntimeError:
867 pass
868 else:
869 self.fail("no exception when changing size during iteration")
870
Raymond Hettingera690a992003-11-16 16:17:49 +0000871#==============================================================================
872
873class TestSetOfSets(unittest.TestCase):
874 def test_constructor(self):
875 inner = frozenset([1])
876 outer = set([inner])
877 element = outer.pop()
878 self.assertEqual(type(element), frozenset)
879 outer.add(inner) # Rebuild set of sets with .add method
880 outer.remove(inner)
881 self.assertEqual(outer, set()) # Verify that remove worked
882 outer.discard(inner) # Absence of KeyError indicates working fine
883
884#==============================================================================
885
886class TestBinaryOps(unittest.TestCase):
887 def setUp(self):
888 self.set = set((2, 4, 6))
889
890 def test_eq(self): # SF bug 643115
891 self.assertEqual(self.set, set({2:1,4:3,6:5}))
892
893 def test_union_subset(self):
894 result = self.set | set([2])
895 self.assertEqual(result, set((2, 4, 6)))
896
897 def test_union_superset(self):
898 result = self.set | set([2, 4, 6, 8])
899 self.assertEqual(result, set([2, 4, 6, 8]))
900
901 def test_union_overlap(self):
902 result = self.set | set([3, 4, 5])
903 self.assertEqual(result, set([2, 3, 4, 5, 6]))
904
905 def test_union_non_overlap(self):
906 result = self.set | set([8])
907 self.assertEqual(result, set([2, 4, 6, 8]))
908
909 def test_intersection_subset(self):
910 result = self.set & set((2, 4))
911 self.assertEqual(result, set((2, 4)))
912
913 def test_intersection_superset(self):
914 result = self.set & set([2, 4, 6, 8])
915 self.assertEqual(result, set([2, 4, 6]))
916
917 def test_intersection_overlap(self):
918 result = self.set & set([3, 4, 5])
919 self.assertEqual(result, set([4]))
920
921 def test_intersection_non_overlap(self):
922 result = self.set & set([8])
923 self.assertEqual(result, empty_set)
924
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000925 def test_isdisjoint_subset(self):
926 result = self.set.isdisjoint(set((2, 4)))
927 self.assertEqual(result, False)
928
929 def test_isdisjoint_superset(self):
930 result = self.set.isdisjoint(set([2, 4, 6, 8]))
931 self.assertEqual(result, False)
932
933 def test_isdisjoint_overlap(self):
934 result = self.set.isdisjoint(set([3, 4, 5]))
935 self.assertEqual(result, False)
936
937 def test_isdisjoint_non_overlap(self):
938 result = self.set.isdisjoint(set([8]))
939 self.assertEqual(result, True)
940
Raymond Hettingera690a992003-11-16 16:17:49 +0000941 def test_sym_difference_subset(self):
942 result = self.set ^ set((2, 4))
943 self.assertEqual(result, set([6]))
944
945 def test_sym_difference_superset(self):
946 result = self.set ^ set((2, 4, 6, 8))
947 self.assertEqual(result, set([8]))
948
949 def test_sym_difference_overlap(self):
950 result = self.set ^ set((3, 4, 5))
951 self.assertEqual(result, set([2, 3, 5, 6]))
952
953 def test_sym_difference_non_overlap(self):
954 result = self.set ^ set([8])
955 self.assertEqual(result, set([2, 4, 6, 8]))
956
957 def test_cmp(self):
958 a, b = set('a'), set('b')
959 self.assertRaises(TypeError, cmp, a, b)
960
961 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
962 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
963 # which Python thinks is good enough to synthesize a cmp() result
964 # without calling __cmp__.
965 self.assertEqual(cmp(a, a), 0)
966
967 self.assertRaises(TypeError, cmp, a, 12)
968 self.assertRaises(TypeError, cmp, "abc", a)
969
970#==============================================================================
971
972class TestUpdateOps(unittest.TestCase):
973 def setUp(self):
974 self.set = set((2, 4, 6))
975
976 def test_union_subset(self):
977 self.set |= set([2])
978 self.assertEqual(self.set, set((2, 4, 6)))
979
980 def test_union_superset(self):
981 self.set |= set([2, 4, 6, 8])
982 self.assertEqual(self.set, set([2, 4, 6, 8]))
983
984 def test_union_overlap(self):
985 self.set |= set([3, 4, 5])
986 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
987
988 def test_union_non_overlap(self):
989 self.set |= set([8])
990 self.assertEqual(self.set, set([2, 4, 6, 8]))
991
992 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000993 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +0000994 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
995
996 def test_intersection_subset(self):
997 self.set &= set((2, 4))
998 self.assertEqual(self.set, set((2, 4)))
999
1000 def test_intersection_superset(self):
1001 self.set &= set([2, 4, 6, 8])
1002 self.assertEqual(self.set, set([2, 4, 6]))
1003
1004 def test_intersection_overlap(self):
1005 self.set &= set([3, 4, 5])
1006 self.assertEqual(self.set, set([4]))
1007
1008 def test_intersection_non_overlap(self):
1009 self.set &= set([8])
1010 self.assertEqual(self.set, empty_set)
1011
1012 def test_intersection_method_call(self):
1013 self.set.intersection_update(set([3, 4, 5]))
1014 self.assertEqual(self.set, set([4]))
1015
1016 def test_sym_difference_subset(self):
1017 self.set ^= set((2, 4))
1018 self.assertEqual(self.set, set([6]))
1019
1020 def test_sym_difference_superset(self):
1021 self.set ^= set((2, 4, 6, 8))
1022 self.assertEqual(self.set, set([8]))
1023
1024 def test_sym_difference_overlap(self):
1025 self.set ^= set((3, 4, 5))
1026 self.assertEqual(self.set, set([2, 3, 5, 6]))
1027
1028 def test_sym_difference_non_overlap(self):
1029 self.set ^= set([8])
1030 self.assertEqual(self.set, set([2, 4, 6, 8]))
1031
1032 def test_sym_difference_method_call(self):
1033 self.set.symmetric_difference_update(set([3, 4, 5]))
1034 self.assertEqual(self.set, set([2, 3, 5, 6]))
1035
1036 def test_difference_subset(self):
1037 self.set -= set((2, 4))
1038 self.assertEqual(self.set, set([6]))
1039
1040 def test_difference_superset(self):
1041 self.set -= set((2, 4, 6, 8))
1042 self.assertEqual(self.set, set([]))
1043
1044 def test_difference_overlap(self):
1045 self.set -= set((3, 4, 5))
1046 self.assertEqual(self.set, set([2, 6]))
1047
1048 def test_difference_non_overlap(self):
1049 self.set -= set([8])
1050 self.assertEqual(self.set, set([2, 4, 6]))
1051
1052 def test_difference_method_call(self):
1053 self.set.difference_update(set([3, 4, 5]))
1054 self.assertEqual(self.set, set([2, 6]))
1055
1056#==============================================================================
1057
1058class TestMutate(unittest.TestCase):
1059 def setUp(self):
1060 self.values = ["a", "b", "c"]
1061 self.set = set(self.values)
1062
1063 def test_add_present(self):
1064 self.set.add("c")
1065 self.assertEqual(self.set, set("abc"))
1066
1067 def test_add_absent(self):
1068 self.set.add("d")
1069 self.assertEqual(self.set, set("abcd"))
1070
1071 def test_add_until_full(self):
1072 tmp = set()
1073 expected_len = 0
1074 for v in self.values:
1075 tmp.add(v)
1076 expected_len += 1
1077 self.assertEqual(len(tmp), expected_len)
1078 self.assertEqual(tmp, self.set)
1079
1080 def test_remove_present(self):
1081 self.set.remove("b")
1082 self.assertEqual(self.set, set("ac"))
1083
1084 def test_remove_absent(self):
1085 try:
1086 self.set.remove("d")
1087 self.fail("Removing missing element should have raised LookupError")
1088 except LookupError:
1089 pass
1090
1091 def test_remove_until_empty(self):
1092 expected_len = len(self.set)
1093 for v in self.values:
1094 self.set.remove(v)
1095 expected_len -= 1
1096 self.assertEqual(len(self.set), expected_len)
1097
1098 def test_discard_present(self):
1099 self.set.discard("c")
1100 self.assertEqual(self.set, set("ab"))
1101
1102 def test_discard_absent(self):
1103 self.set.discard("d")
1104 self.assertEqual(self.set, set("abc"))
1105
1106 def test_clear(self):
1107 self.set.clear()
1108 self.assertEqual(len(self.set), 0)
1109
1110 def test_pop(self):
1111 popped = {}
1112 while self.set:
1113 popped[self.set.pop()] = None
1114 self.assertEqual(len(popped), len(self.values))
1115 for v in self.values:
Ezio Melottiaa980582010-01-23 23:04:36 +00001116 self.assertIn(v, popped)
Raymond Hettingera690a992003-11-16 16:17:49 +00001117
1118 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001119 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001120 self.assertEqual(self.set, set(self.values))
1121
1122 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001123 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001124 self.assertEqual(self.set, set(self.values))
1125
1126 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001127 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001128 self.assertEqual(self.set, set(self.values + ["z"]))
1129
1130#==============================================================================
1131
1132class TestSubsets(unittest.TestCase):
1133
1134 case2method = {"<=": "issubset",
1135 ">=": "issuperset",
1136 }
1137
1138 reverse = {"==": "==",
1139 "!=": "!=",
1140 "<": ">",
1141 ">": "<",
1142 "<=": ">=",
1143 ">=": "<=",
1144 }
1145
1146 def test_issubset(self):
1147 x = self.left
1148 y = self.right
1149 for case in "!=", "==", "<", "<=", ">", ">=":
1150 expected = case in self.cases
1151 # Test the binary infix spelling.
1152 result = eval("x" + case + "y", locals())
1153 self.assertEqual(result, expected)
1154 # Test the "friendly" method-name spelling, if one exists.
1155 if case in TestSubsets.case2method:
1156 method = getattr(x, TestSubsets.case2method[case])
1157 result = method(y)
1158 self.assertEqual(result, expected)
1159
1160 # Now do the same for the operands reversed.
1161 rcase = TestSubsets.reverse[case]
1162 result = eval("y" + rcase + "x", locals())
1163 self.assertEqual(result, expected)
1164 if rcase in TestSubsets.case2method:
1165 method = getattr(y, TestSubsets.case2method[rcase])
1166 result = method(x)
1167 self.assertEqual(result, expected)
1168#------------------------------------------------------------------------------
1169
1170class TestSubsetEqualEmpty(TestSubsets):
1171 left = set()
1172 right = set()
1173 name = "both empty"
1174 cases = "==", "<=", ">="
1175
1176#------------------------------------------------------------------------------
1177
1178class TestSubsetEqualNonEmpty(TestSubsets):
1179 left = set([1, 2])
1180 right = set([1, 2])
1181 name = "equal pair"
1182 cases = "==", "<=", ">="
1183
1184#------------------------------------------------------------------------------
1185
1186class TestSubsetEmptyNonEmpty(TestSubsets):
1187 left = set()
1188 right = set([1, 2])
1189 name = "one empty, one non-empty"
1190 cases = "!=", "<", "<="
1191
1192#------------------------------------------------------------------------------
1193
1194class TestSubsetPartial(TestSubsets):
1195 left = set([1])
1196 right = set([1, 2])
1197 name = "one a non-empty proper subset of other"
1198 cases = "!=", "<", "<="
1199
1200#------------------------------------------------------------------------------
1201
1202class TestSubsetNonOverlap(TestSubsets):
1203 left = set([1])
1204 right = set([2])
1205 name = "neither empty, neither contains"
1206 cases = "!="
1207
1208#==============================================================================
1209
1210class TestOnlySetsInBinaryOps(unittest.TestCase):
1211
1212 def test_eq_ne(self):
1213 # Unlike the others, this is testing that == and != *are* allowed.
1214 self.assertEqual(self.other == self.set, False)
1215 self.assertEqual(self.set == self.other, False)
1216 self.assertEqual(self.other != self.set, True)
1217 self.assertEqual(self.set != self.other, True)
1218
1219 def test_ge_gt_le_lt(self):
Senthil Kumarance8e33a2010-01-08 19:04:16 +00001220 self.assertRaises(TypeError, lambda: self.set < self.other)
1221 self.assertRaises(TypeError, lambda: self.set <= self.other)
1222 self.assertRaises(TypeError, lambda: self.set > self.other)
1223 self.assertRaises(TypeError, lambda: self.set >= self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001224
Senthil Kumarance8e33a2010-01-08 19:04:16 +00001225 self.assertRaises(TypeError, lambda: self.other < self.set)
1226 self.assertRaises(TypeError, lambda: self.other <= self.set)
1227 self.assertRaises(TypeError, lambda: self.other > self.set)
1228 self.assertRaises(TypeError, lambda: self.other >= self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +00001229
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001230 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001231 try:
1232 self.set |= self.other
1233 except TypeError:
1234 pass
1235 else:
1236 self.fail("expected TypeError")
1237
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001238 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001239 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001240 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001241 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001242 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001243
1244 def test_union(self):
1245 self.assertRaises(TypeError, lambda: self.set | self.other)
1246 self.assertRaises(TypeError, lambda: self.other | self.set)
1247 if self.otherIsIterable:
1248 self.set.union(self.other)
1249 else:
1250 self.assertRaises(TypeError, self.set.union, self.other)
1251
1252 def test_intersection_update_operator(self):
1253 try:
1254 self.set &= self.other
1255 except TypeError:
1256 pass
1257 else:
1258 self.fail("expected TypeError")
1259
1260 def test_intersection_update(self):
1261 if self.otherIsIterable:
1262 self.set.intersection_update(self.other)
1263 else:
1264 self.assertRaises(TypeError,
1265 self.set.intersection_update,
1266 self.other)
1267
1268 def test_intersection(self):
1269 self.assertRaises(TypeError, lambda: self.set & self.other)
1270 self.assertRaises(TypeError, lambda: self.other & self.set)
1271 if self.otherIsIterable:
1272 self.set.intersection(self.other)
1273 else:
1274 self.assertRaises(TypeError, self.set.intersection, self.other)
1275
1276 def test_sym_difference_update_operator(self):
1277 try:
1278 self.set ^= self.other
1279 except TypeError:
1280 pass
1281 else:
1282 self.fail("expected TypeError")
1283
1284 def test_sym_difference_update(self):
1285 if self.otherIsIterable:
1286 self.set.symmetric_difference_update(self.other)
1287 else:
1288 self.assertRaises(TypeError,
1289 self.set.symmetric_difference_update,
1290 self.other)
1291
1292 def test_sym_difference(self):
1293 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1294 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1295 if self.otherIsIterable:
1296 self.set.symmetric_difference(self.other)
1297 else:
1298 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1299
1300 def test_difference_update_operator(self):
1301 try:
1302 self.set -= self.other
1303 except TypeError:
1304 pass
1305 else:
1306 self.fail("expected TypeError")
1307
1308 def test_difference_update(self):
1309 if self.otherIsIterable:
1310 self.set.difference_update(self.other)
1311 else:
1312 self.assertRaises(TypeError,
1313 self.set.difference_update,
1314 self.other)
1315
1316 def test_difference(self):
1317 self.assertRaises(TypeError, lambda: self.set - self.other)
1318 self.assertRaises(TypeError, lambda: self.other - self.set)
1319 if self.otherIsIterable:
1320 self.set.difference(self.other)
1321 else:
1322 self.assertRaises(TypeError, self.set.difference, self.other)
1323
1324#------------------------------------------------------------------------------
1325
1326class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1327 def setUp(self):
1328 self.set = set((1, 2, 3))
1329 self.other = 19
1330 self.otherIsIterable = False
1331
1332#------------------------------------------------------------------------------
1333
1334class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1335 def setUp(self):
1336 self.set = set((1, 2, 3))
1337 self.other = {1:2, 3:4}
1338 self.otherIsIterable = True
1339
1340#------------------------------------------------------------------------------
1341
1342class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1343 def setUp(self):
1344 self.set = set((1, 2, 3))
1345 self.other = operator.add
1346 self.otherIsIterable = False
1347
1348#------------------------------------------------------------------------------
1349
1350class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1351 def setUp(self):
1352 self.set = set((1, 2, 3))
1353 self.other = (2, 4, 6)
1354 self.otherIsIterable = True
1355
1356#------------------------------------------------------------------------------
1357
1358class TestOnlySetsString(TestOnlySetsInBinaryOps):
1359 def setUp(self):
1360 self.set = set((1, 2, 3))
1361 self.other = 'abc'
1362 self.otherIsIterable = True
1363
1364#------------------------------------------------------------------------------
1365
1366class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1367 def setUp(self):
1368 def gen():
1369 for i in xrange(0, 10, 2):
1370 yield i
1371 self.set = set((1, 2, 3))
1372 self.other = gen()
1373 self.otherIsIterable = True
1374
1375#==============================================================================
1376
1377class TestCopying(unittest.TestCase):
1378
1379 def test_copy(self):
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001380 dup = list(self.set.copy())
1381 self.assertEqual(len(dup), len(self.set))
1382 for el in self.set:
1383 self.assertIn(el, dup)
1384 pos = dup.index(el)
1385 self.assertIs(el, dup.pop(pos))
1386 self.assertFalse(dup)
Raymond Hettingera690a992003-11-16 16:17:49 +00001387
1388 def test_deep_copy(self):
1389 dup = copy.deepcopy(self.set)
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001390 self.assertSetEqual(dup, self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +00001391
1392#------------------------------------------------------------------------------
1393
1394class TestCopyingEmpty(TestCopying):
1395 def setUp(self):
1396 self.set = set()
1397
1398#------------------------------------------------------------------------------
1399
1400class TestCopyingSingleton(TestCopying):
1401 def setUp(self):
1402 self.set = set(["hello"])
1403
1404#------------------------------------------------------------------------------
1405
1406class TestCopyingTriple(TestCopying):
1407 def setUp(self):
1408 self.set = set(["zero", 0, None])
1409
1410#------------------------------------------------------------------------------
1411
1412class TestCopyingTuple(TestCopying):
1413 def setUp(self):
1414 self.set = set([(1, 2)])
1415
1416#------------------------------------------------------------------------------
1417
1418class TestCopyingNested(TestCopying):
1419 def setUp(self):
1420 self.set = set([((1, 2), (3, 4))])
1421
1422#==============================================================================
1423
1424class TestIdentities(unittest.TestCase):
1425 def setUp(self):
1426 self.a = set('abracadabra')
1427 self.b = set('alacazam')
1428
1429 def test_binopsVsSubsets(self):
1430 a, b = self.a, self.b
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001431 self.assertTrue(a - b < a)
1432 self.assertTrue(b - a < b)
1433 self.assertTrue(a & b < a)
1434 self.assertTrue(a & b < b)
1435 self.assertTrue(a | b > a)
1436 self.assertTrue(a | b > b)
1437 self.assertTrue(a ^ b < a | b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001438
1439 def test_commutativity(self):
1440 a, b = self.a, self.b
1441 self.assertEqual(a&b, b&a)
1442 self.assertEqual(a|b, b|a)
1443 self.assertEqual(a^b, b^a)
1444 if a != b:
1445 self.assertNotEqual(a-b, b-a)
1446
1447 def test_summations(self):
1448 # check that sums of parts equal the whole
1449 a, b = self.a, self.b
1450 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1451 self.assertEqual((a&b)|(a^b), a|b)
1452 self.assertEqual(a|(b-a), a|b)
1453 self.assertEqual((a-b)|b, a|b)
1454 self.assertEqual((a-b)|(a&b), a)
1455 self.assertEqual((b-a)|(a&b), b)
1456 self.assertEqual((a-b)|(b-a), a^b)
1457
1458 def test_exclusion(self):
1459 # check that inverse operations show non-overlap
1460 a, b, zero = self.a, self.b, set()
1461 self.assertEqual((a-b)&b, zero)
1462 self.assertEqual((b-a)&a, zero)
1463 self.assertEqual((a&b)&(a^b), zero)
1464
1465# Tests derived from test_itertools.py =======================================
1466
1467def R(seqn):
1468 'Regular generator'
1469 for i in seqn:
1470 yield i
1471
1472class G:
1473 'Sequence using __getitem__'
1474 def __init__(self, seqn):
1475 self.seqn = seqn
1476 def __getitem__(self, i):
1477 return self.seqn[i]
1478
1479class I:
1480 'Sequence using iterator protocol'
1481 def __init__(self, seqn):
1482 self.seqn = seqn
1483 self.i = 0
1484 def __iter__(self):
1485 return self
1486 def next(self):
1487 if self.i >= len(self.seqn): raise StopIteration
1488 v = self.seqn[self.i]
1489 self.i += 1
1490 return v
1491
1492class Ig:
1493 'Sequence using iterator protocol defined with a generator'
1494 def __init__(self, seqn):
1495 self.seqn = seqn
1496 self.i = 0
1497 def __iter__(self):
1498 for val in self.seqn:
1499 yield val
1500
1501class X:
1502 'Missing __getitem__ and __iter__'
1503 def __init__(self, seqn):
1504 self.seqn = seqn
1505 self.i = 0
1506 def next(self):
1507 if self.i >= len(self.seqn): raise StopIteration
1508 v = self.seqn[self.i]
1509 self.i += 1
1510 return v
1511
1512class N:
1513 'Iterator missing next()'
1514 def __init__(self, seqn):
1515 self.seqn = seqn
1516 self.i = 0
1517 def __iter__(self):
1518 return self
1519
1520class E:
1521 'Test propagation of exceptions'
1522 def __init__(self, seqn):
1523 self.seqn = seqn
1524 self.i = 0
1525 def __iter__(self):
1526 return self
1527 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001528 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001529
1530class S:
1531 'Test immediate stop'
1532 def __init__(self, seqn):
1533 pass
1534 def __iter__(self):
1535 return self
1536 def next(self):
1537 raise StopIteration
1538
1539from itertools import chain, imap
1540def L(seqn):
1541 'Test multiple tiers of iterators'
1542 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1543
1544class TestVariousIteratorArgs(unittest.TestCase):
1545
1546 def test_constructor(self):
1547 for cons in (set, frozenset):
1548 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1549 for g in (G, I, Ig, S, L, R):
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001550 self.assertSetEqual(cons(g(s)), set(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001551 self.assertRaises(TypeError, cons , X(s))
1552 self.assertRaises(TypeError, cons , N(s))
1553 self.assertRaises(ZeroDivisionError, cons , E(s))
1554
1555 def test_inline_methods(self):
1556 s = set('november')
1557 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001558 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001559 for g in (G, I, Ig, L, R):
1560 expected = meth(data)
1561 actual = meth(G(data))
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001562 if isinstance(expected, bool):
1563 self.assertEqual(actual, expected)
1564 else:
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001565 self.assertSetEqual(actual, expected)
Raymond Hettingera690a992003-11-16 16:17:49 +00001566 self.assertRaises(TypeError, meth, X(s))
1567 self.assertRaises(TypeError, meth, N(s))
1568 self.assertRaises(ZeroDivisionError, meth, E(s))
1569
1570 def test_inplace_methods(self):
1571 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001572 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001573 'difference_update', 'symmetric_difference_update'):
1574 for g in (G, I, Ig, S, L, R):
1575 s = set('january')
1576 t = s.copy()
1577 getattr(s, methname)(list(g(data)))
1578 getattr(t, methname)(g(data))
Ezio Melottid80b4bf2010-03-17 13:52:48 +00001579 self.assertSetEqual(s, t)
Raymond Hettingera690a992003-11-16 16:17:49 +00001580
1581 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1582 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1583 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1584
Raymond Hettinger61708742008-01-24 21:23:58 +00001585# Application tests (based on David Eppstein's graph recipes ====================================
1586
1587def powerset(U):
1588 """Generates all subsets of a set or sequence U."""
1589 U = iter(U)
1590 try:
1591 x = frozenset([U.next()])
1592 for S in powerset(U):
1593 yield S
1594 yield S | x
1595 except StopIteration:
1596 yield frozenset()
1597
1598def cube(n):
1599 """Graph of n-dimensional hypercube."""
1600 singletons = [frozenset([x]) for x in range(n)]
1601 return dict([(x, frozenset([x^s for s in singletons]))
1602 for x in powerset(range(n))])
1603
1604def linegraph(G):
1605 """Graph, the vertices of which are edges of G,
1606 with two vertices being adjacent iff the corresponding
1607 edges share a vertex."""
1608 L = {}
1609 for x in G:
1610 for y in G[x]:
1611 nx = [frozenset([x,z]) for z in G[x] if z != y]
1612 ny = [frozenset([y,z]) for z in G[y] if z != x]
1613 L[frozenset([x,y])] = frozenset(nx+ny)
1614 return L
1615
1616def faces(G):
1617 'Return a set of faces in G. Where a face is a set of vertices on that face'
1618 # currently limited to triangles,squares, and pentagons
1619 f = set()
1620 for v1, edges in G.items():
1621 for v2 in edges:
1622 for v3 in G[v2]:
1623 if v1 == v3:
1624 continue
1625 if v1 in G[v3]:
1626 f.add(frozenset([v1, v2, v3]))
1627 else:
1628 for v4 in G[v3]:
1629 if v4 == v2:
1630 continue
1631 if v1 in G[v4]:
1632 f.add(frozenset([v1, v2, v3, v4]))
1633 else:
1634 for v5 in G[v4]:
1635 if v5 == v3 or v5 == v2:
1636 continue
1637 if v1 in G[v5]:
1638 f.add(frozenset([v1, v2, v3, v4, v5]))
1639 return f
1640
1641
1642class TestGraphs(unittest.TestCase):
1643
1644 def test_cube(self):
1645
1646 g = cube(3) # vert --> {v1, v2, v3}
1647 vertices1 = set(g)
1648 self.assertEqual(len(vertices1), 8) # eight vertices
1649 for edge in g.values():
1650 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1651 vertices2 = set(v for edges in g.values() for v in edges)
1652 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1653
1654 cubefaces = faces(g)
1655 self.assertEqual(len(cubefaces), 6) # six faces
1656 for face in cubefaces:
1657 self.assertEqual(len(face), 4) # each face is a square
1658
1659 def test_cuboctahedron(self):
1660
1661 # http://en.wikipedia.org/wiki/Cuboctahedron
1662 # 8 triangular faces and 6 square faces
1663 # 12 indentical vertices each connecting a triangle and square
1664
1665 g = cube(3)
1666 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1667 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1668
1669 vertices = set(cuboctahedron)
1670 for edges in cuboctahedron.values():
1671 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1672 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1673 self.assertEqual(vertices, othervertices) # edge vertices in original set
1674
1675 cubofaces = faces(cuboctahedron)
1676 facesizes = collections.defaultdict(int)
1677 for face in cubofaces:
1678 facesizes[len(face)] += 1
1679 self.assertEqual(facesizes[3], 8) # eight triangular faces
1680 self.assertEqual(facesizes[4], 6) # six square faces
1681
1682 for vertex in cuboctahedron:
1683 edge = vertex # Cuboctahedron vertices are edges in Cube
1684 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1685 for cubevert in edge:
Ezio Melottiaa980582010-01-23 23:04:36 +00001686 self.assertIn(cubevert, g)
Raymond Hettinger61708742008-01-24 21:23:58 +00001687
1688
Raymond Hettingera690a992003-11-16 16:17:49 +00001689#==============================================================================
1690
1691def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001692 test_classes = (
1693 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001694 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001695 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001696 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001697 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001698 TestSetOfSets,
1699 TestExceptionPropagation,
1700 TestBasicOpsEmpty,
1701 TestBasicOpsSingleton,
1702 TestBasicOpsTuple,
1703 TestBasicOpsTriple,
1704 TestBinaryOps,
1705 TestUpdateOps,
1706 TestMutate,
1707 TestSubsetEqualEmpty,
1708 TestSubsetEqualNonEmpty,
1709 TestSubsetEmptyNonEmpty,
1710 TestSubsetPartial,
1711 TestSubsetNonOverlap,
1712 TestOnlySetsNumeric,
1713 TestOnlySetsDict,
1714 TestOnlySetsOperator,
1715 TestOnlySetsTuple,
1716 TestOnlySetsString,
1717 TestOnlySetsGenerator,
1718 TestCopyingEmpty,
1719 TestCopyingSingleton,
1720 TestCopyingTriple,
1721 TestCopyingTuple,
1722 TestCopyingNested,
1723 TestIdentities,
1724 TestVariousIteratorArgs,
Raymond Hettinger61708742008-01-24 21:23:58 +00001725 TestGraphs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001726 )
1727
1728 test_support.run_unittest(*test_classes)
1729
1730 # verify reference counting
1731 if verbose and hasattr(sys, "gettotalrefcount"):
1732 import gc
1733 counts = [None] * 5
1734 for i in xrange(len(counts)):
1735 test_support.run_unittest(*test_classes)
1736 gc.collect()
1737 counts[i] = sys.gettotalrefcount()
1738 print counts
1739
1740if __name__ == "__main__":
1741 test_main(verbose=True)