blob: c2e2ad191a699eda4310506f7e9bebaabf2aeaad [file] [log] [blame]
Raymond Hettingerefa19842010-04-18 22:59:34 +00001
Raymond Hettingera690a992003-11-16 16:17:49 +00002import unittest
3from test import test_support
Georg Brandl47fe9812009-01-01 15:46:10 +00004import gc
5import weakref
Raymond Hettingera690a992003-11-16 16:17:49 +00006import operator
7import copy
8import pickle
Raymond Hettingereae05de2004-07-09 04:51:24 +00009import os
Raymond Hettinger82cb9a22005-07-05 05:34:43 +000010from random import randrange, shuffle
Raymond Hettingerc47e01d2005-08-16 10:44:15 +000011import sys
Raymond Hettinger61708742008-01-24 21:23:58 +000012import collections
Raymond Hettingera690a992003-11-16 16:17:49 +000013
14class PassThru(Exception):
15 pass
16
17def check_pass_thru():
18 raise PassThru
19 yield 1
20
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000021class BadCmp:
22 def __hash__(self):
23 return 1
24 def __cmp__(self, other):
25 raise RuntimeError
26
Raymond Hettinger53999102006-12-30 04:01:17 +000027class ReprWrapper:
28 'Used to test self-referential repr() calls'
29 def __repr__(self):
30 return repr(self.value)
31
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +000032class HashCountingInt(int):
33 'int-like object that counts the number of times __hash__ is called'
34 def __init__(self, *args):
35 self.hash_count = 0
36 def __hash__(self):
37 self.hash_count += 1
38 return int.__hash__(self)
39
Raymond Hettingera690a992003-11-16 16:17:49 +000040class TestJointOps(unittest.TestCase):
41 # Tests common to both set and frozenset
42
43 def setUp(self):
44 self.word = word = 'simsalabim'
45 self.otherword = 'madagascar'
46 self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
47 self.s = self.thetype(word)
48 self.d = dict.fromkeys(word)
49
Raymond Hettinger6429a472004-09-28 01:51:35 +000050 def test_new_or_init(self):
51 self.assertRaises(TypeError, self.thetype, [], 2)
Raymond Hettingerefa19842010-04-18 22:59:34 +000052 self.assertRaises(TypeError, set().__init__, a=1)
Raymond Hettinger6429a472004-09-28 01:51:35 +000053
Raymond Hettingera690a992003-11-16 16:17:49 +000054 def test_uniquification(self):
Raymond Hettinger64958a12003-12-17 20:43:33 +000055 actual = sorted(self.s)
56 expected = sorted(self.d)
Raymond Hettingera690a992003-11-16 16:17:49 +000057 self.assertEqual(actual, expected)
58 self.assertRaises(PassThru, self.thetype, check_pass_thru())
59 self.assertRaises(TypeError, self.thetype, [[]])
60
61 def test_len(self):
62 self.assertEqual(len(self.s), len(self.d))
63
64 def test_contains(self):
65 for c in self.letters:
66 self.assertEqual(c in self.s, c in self.d)
67 self.assertRaises(TypeError, self.s.__contains__, [[]])
Raymond Hettinger19c2d772003-11-21 18:36:54 +000068 s = self.thetype([frozenset(self.letters)])
69 self.assert_(self.thetype(self.letters) in s)
Raymond Hettingera690a992003-11-16 16:17:49 +000070
Raymond Hettingera690a992003-11-16 16:17:49 +000071 def test_union(self):
72 u = self.s.union(self.otherword)
73 for c in self.letters:
74 self.assertEqual(c in u, c in self.d or c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000075 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000076 self.assertEqual(type(u), self.thetype)
77 self.assertRaises(PassThru, self.s.union, check_pass_thru())
78 self.assertRaises(TypeError, self.s.union, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000079 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
80 self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
81 self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
82 self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
83 self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +000084 self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
Raymond Hettingera690a992003-11-16 16:17:49 +000085
Raymond Hettinger30006c72009-07-27 20:33:25 +000086 # Issue #6573
87 x = self.thetype()
88 self.assertEqual(x.union(set([1]), x, set([2])), self.thetype([1, 2]))
89
Raymond Hettingera690a992003-11-16 16:17:49 +000090 def test_or(self):
91 i = self.s.union(self.otherword)
92 self.assertEqual(self.s | set(self.otherword), i)
93 self.assertEqual(self.s | frozenset(self.otherword), i)
94 try:
95 self.s | self.otherword
96 except TypeError:
97 pass
98 else:
99 self.fail("s|t did not screen-out general iterables")
100
101 def test_intersection(self):
102 i = self.s.intersection(self.otherword)
103 for c in self.letters:
104 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000105 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000106 self.assertEqual(type(i), self.thetype)
107 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000108 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
109 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
110 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
111 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
112 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000113 self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
Raymond Hettinger610a93e2008-06-11 00:44:47 +0000114 s = self.thetype('abcba')
115 z = s.intersection()
116 if self.thetype == frozenset():
117 self.assertEqual(id(s), id(z))
118 else:
119 self.assertNotEqual(id(s), id(z))
Raymond Hettingera690a992003-11-16 16:17:49 +0000120
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000121 def test_isdisjoint(self):
122 def f(s1, s2):
123 'Pure python equivalent of isdisjoint()'
124 return not set(s1).intersection(s2)
125 for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
126 s1 = self.thetype(larg)
127 for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
128 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
129 s2 = C(rarg)
130 actual = s1.isdisjoint(s2)
131 expected = f(s1, s2)
132 self.assertEqual(actual, expected)
133 self.assert_(actual is True or actual is False)
134
Raymond Hettingera690a992003-11-16 16:17:49 +0000135 def test_and(self):
136 i = self.s.intersection(self.otherword)
137 self.assertEqual(self.s & set(self.otherword), i)
138 self.assertEqual(self.s & frozenset(self.otherword), i)
139 try:
140 self.s & self.otherword
141 except TypeError:
142 pass
143 else:
144 self.fail("s&t did not screen-out general iterables")
145
146 def test_difference(self):
147 i = self.s.difference(self.otherword)
148 for c in self.letters:
149 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000150 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000151 self.assertEqual(type(i), self.thetype)
152 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
153 self.assertRaises(TypeError, self.s.difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000154 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
155 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
156 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
157 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
158 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettinger4267be62008-06-11 10:30:54 +0000159 self.assertEqual(self.thetype('abcba').difference(), set('abc'))
160 self.assertEqual(self.thetype('abcba').difference(C('a'), C('b')), set('c'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000161
162 def test_sub(self):
163 i = self.s.difference(self.otherword)
164 self.assertEqual(self.s - set(self.otherword), i)
165 self.assertEqual(self.s - frozenset(self.otherword), i)
166 try:
167 self.s - self.otherword
168 except TypeError:
169 pass
170 else:
171 self.fail("s-t did not screen-out general iterables")
172
173 def test_symmetric_difference(self):
174 i = self.s.symmetric_difference(self.otherword)
175 for c in self.letters:
176 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000177 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000178 self.assertEqual(type(i), self.thetype)
179 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
180 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000181 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
182 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
183 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
184 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
185 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000186
187 def test_xor(self):
188 i = self.s.symmetric_difference(self.otherword)
189 self.assertEqual(self.s ^ set(self.otherword), i)
190 self.assertEqual(self.s ^ frozenset(self.otherword), i)
191 try:
192 self.s ^ self.otherword
193 except TypeError:
194 pass
195 else:
196 self.fail("s^t did not screen-out general iterables")
197
198 def test_equality(self):
199 self.assertEqual(self.s, set(self.word))
200 self.assertEqual(self.s, frozenset(self.word))
201 self.assertEqual(self.s == self.word, False)
202 self.assertNotEqual(self.s, set(self.otherword))
203 self.assertNotEqual(self.s, frozenset(self.otherword))
204 self.assertEqual(self.s != self.word, True)
205
206 def test_setOfFrozensets(self):
207 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
208 s = self.thetype(t)
209 self.assertEqual(len(s), 3)
210
211 def test_compare(self):
212 self.assertRaises(TypeError, self.s.__cmp__, self.s)
213
214 def test_sub_and_super(self):
215 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
216 self.assert_(p < q)
217 self.assert_(p <= q)
218 self.assert_(q <= q)
219 self.assert_(q > p)
220 self.assert_(q >= p)
221 self.failIf(q < r)
222 self.failIf(q <= r)
223 self.failIf(q > r)
224 self.failIf(q >= r)
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000225 self.assert_(set('a').issubset('abc'))
226 self.assert_(set('abc').issuperset('a'))
227 self.failIf(set('a').issubset('cbs'))
228 self.failIf(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000229
230 def test_pickling(self):
Benjamin Peterson828a7062008-12-27 17:05:29 +0000231 for i in range(pickle.HIGHEST_PROTOCOL + 1):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000232 p = pickle.dumps(self.s, i)
233 dup = pickle.loads(p)
234 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
235 if type(self.s) not in (set, frozenset):
236 self.s.x = 10
237 p = pickle.dumps(self.s)
238 dup = pickle.loads(p)
239 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000240
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000241 def test_deepcopy(self):
242 class Tracer:
243 def __init__(self, value):
244 self.value = value
245 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000246 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000247 def __deepcopy__(self, memo=None):
248 return Tracer(self.value + 1)
249 t = Tracer(10)
250 s = self.thetype([t])
251 dup = copy.deepcopy(s)
252 self.assertNotEqual(id(s), id(dup))
253 for elem in dup:
254 newt = elem
255 self.assertNotEqual(id(t), id(newt))
256 self.assertEqual(t.value + 1, newt.value)
257
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000258 def test_gc(self):
259 # Create a nest of cycles to exercise overall ref count check
260 class A:
261 pass
262 s = set(A() for i in xrange(1000))
263 for elem in s:
264 elem.cycle = s
265 elem.sub = elem
266 elem.set = set([elem])
267
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000268 def test_subclass_with_custom_hash(self):
269 # Bug #1257731
270 class H(self.thetype):
271 def __hash__(self):
Tim Peters6902b442006-04-11 00:43:27 +0000272 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000273 s=H()
274 f=set()
275 f.add(s)
276 self.assert_(s in f)
277 f.remove(s)
278 f.add(s)
279 f.discard(s)
280
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000281 def test_badcmp(self):
282 s = self.thetype([BadCmp()])
283 # Detect comparison errors during insertion and lookup
284 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
285 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
286 # Detect errors during mutating operations
287 if hasattr(s, 'add'):
288 self.assertRaises(RuntimeError, s.add, BadCmp())
289 self.assertRaises(RuntimeError, s.discard, BadCmp())
290 self.assertRaises(RuntimeError, s.remove, BadCmp())
291
Raymond Hettinger53999102006-12-30 04:01:17 +0000292 def test_cyclical_repr(self):
293 w = ReprWrapper()
294 s = self.thetype([w])
295 w.value = s
296 name = repr(s).partition('(')[0] # strip class name from repr string
297 self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
298
299 def test_cyclical_print(self):
300 w = ReprWrapper()
301 s = self.thetype([w])
302 w.value = s
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000303 fo = open(test_support.TESTFN, "wb")
Raymond Hettinger53999102006-12-30 04:01:17 +0000304 try:
Raymond Hettinger53999102006-12-30 04:01:17 +0000305 print >> fo, s,
306 fo.close()
307 fo = open(test_support.TESTFN, "rb")
308 self.assertEqual(fo.read(), repr(s))
309 finally:
310 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000311 test_support.unlink(test_support.TESTFN)
Raymond Hettinger53999102006-12-30 04:01:17 +0000312
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000313 def test_do_not_rehash_dict_keys(self):
314 n = 10
315 d = dict.fromkeys(map(HashCountingInt, xrange(n)))
316 self.assertEqual(sum(elem.hash_count for elem in d), n)
317 s = self.thetype(d)
318 self.assertEqual(sum(elem.hash_count for elem in d), n)
319 s.difference(d)
Tim Petersea5962f2007-03-12 18:07:52 +0000320 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000321 if hasattr(s, 'symmetric_difference_update'):
322 s.symmetric_difference_update(d)
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000323 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettinger0bbbfc42007-03-20 21:27:24 +0000324 d2 = dict.fromkeys(set(d))
325 self.assertEqual(sum(elem.hash_count for elem in d), n)
326 d3 = dict.fromkeys(frozenset(d))
Tim Petersea5962f2007-03-12 18:07:52 +0000327 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingere3146f52007-03-21 20:33:57 +0000328 d3 = dict.fromkeys(frozenset(d), 123)
329 self.assertEqual(sum(elem.hash_count for elem in d), n)
330 self.assertEqual(d3, dict.fromkeys(d, 123))
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000331
Georg Brandl47fe9812009-01-01 15:46:10 +0000332 def test_container_iterator(self):
Georg Brandl734373c2009-01-03 21:55:17 +0000333 # Bug #3680: tp_traverse was not implemented for set iterator object
Georg Brandl47fe9812009-01-01 15:46:10 +0000334 class C(object):
335 pass
336 obj = C()
337 ref = weakref.ref(obj)
338 container = set([obj, 1])
339 obj.x = iter(container)
340 del obj, container
341 gc.collect()
342 self.assert_(ref() is None, "Cycle was not collected")
343
Raymond Hettingera690a992003-11-16 16:17:49 +0000344class TestSet(TestJointOps):
345 thetype = set
346
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000347 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000348 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000349 s.__init__(self.word)
350 self.assertEqual(s, set(self.word))
351 s.__init__(self.otherword)
352 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000353 self.assertRaises(TypeError, s.__init__, s, 2);
354 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000355
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000356 def test_constructor_identity(self):
357 s = self.thetype(range(3))
358 t = self.thetype(s)
359 self.assertNotEqual(id(s), id(t))
360
Raymond Hettingera690a992003-11-16 16:17:49 +0000361 def test_hash(self):
362 self.assertRaises(TypeError, hash, self.s)
363
364 def test_clear(self):
365 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000366 self.assertEqual(self.s, set())
367 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000368
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000369 def test_copy(self):
370 dup = self.s.copy()
371 self.assertEqual(self.s, dup)
372 self.assertNotEqual(id(self.s), id(dup))
373
Raymond Hettingera690a992003-11-16 16:17:49 +0000374 def test_add(self):
375 self.s.add('Q')
376 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000377 dup = self.s.copy()
378 self.s.add('Q')
379 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000380 self.assertRaises(TypeError, self.s.add, [])
381
382 def test_remove(self):
383 self.s.remove('a')
384 self.assert_('a' not in self.s)
385 self.assertRaises(KeyError, self.s.remove, 'Q')
386 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000387 s = self.thetype([frozenset(self.word)])
388 self.assert_(self.thetype(self.word) in s)
389 s.remove(self.thetype(self.word))
390 self.assert_(self.thetype(self.word) not in s)
391 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000392
Raymond Hettingerc789f342006-12-08 17:35:25 +0000393 def test_remove_keyerror_unpacking(self):
394 # bug: www.python.org/sf/1576657
395 for v1 in ['Q', (1,)]:
396 try:
397 self.s.remove(v1)
398 except KeyError, e:
399 v2 = e.args[0]
400 self.assertEqual(v1, v2)
401 else:
402 self.fail()
403
Amaury Forgeot d'Arc00c94ed2008-10-07 20:40:09 +0000404 def test_remove_keyerror_set(self):
405 key = self.thetype([3, 4])
406 try:
407 self.s.remove(key)
408 except KeyError as e:
409 self.assert_(e.args[0] is key,
410 "KeyError should be {0}, not {1}".format(key,
411 e.args[0]))
412 else:
413 self.fail()
414
Raymond Hettingera690a992003-11-16 16:17:49 +0000415 def test_discard(self):
416 self.s.discard('a')
417 self.assert_('a' not in self.s)
418 self.s.discard('Q')
419 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000420 s = self.thetype([frozenset(self.word)])
421 self.assert_(self.thetype(self.word) in s)
422 s.discard(self.thetype(self.word))
423 self.assert_(self.thetype(self.word) not in s)
424 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000425
426 def test_pop(self):
427 for i in xrange(len(self.s)):
428 elem = self.s.pop()
429 self.assert_(elem not in self.s)
430 self.assertRaises(KeyError, self.s.pop)
431
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000432 def test_update(self):
433 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000434 self.assertEqual(retval, None)
435 for c in (self.word + self.otherword):
436 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000437 self.assertRaises(PassThru, self.s.update, check_pass_thru())
438 self.assertRaises(TypeError, self.s.update, [[]])
439 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
440 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
441 s = self.thetype('abcba')
442 self.assertEqual(s.update(C(p)), None)
443 self.assertEqual(s, set(q))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +0000444 for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
445 q = 'ahi'
446 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
447 s = self.thetype('abcba')
448 self.assertEqual(s.update(C(p), C(q)), None)
449 self.assertEqual(s, set(s) | set(p) | set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000450
451 def test_ior(self):
452 self.s |= set(self.otherword)
453 for c in (self.word + self.otherword):
454 self.assert_(c in self.s)
455
456 def test_intersection_update(self):
457 retval = self.s.intersection_update(self.otherword)
458 self.assertEqual(retval, None)
459 for c in (self.word + self.otherword):
460 if c in self.otherword and c in self.word:
461 self.assert_(c in self.s)
462 else:
463 self.assert_(c not in self.s)
464 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
465 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000466 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
467 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
468 s = self.thetype('abcba')
469 self.assertEqual(s.intersection_update(C(p)), None)
470 self.assertEqual(s, set(q))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000471 ss = 'abcba'
472 s = self.thetype(ss)
473 t = 'cbc'
474 self.assertEqual(s.intersection_update(C(p), C(t)), None)
475 self.assertEqual(s, set('abcba')&set(p)&set(t))
Raymond Hettingera690a992003-11-16 16:17:49 +0000476
477 def test_iand(self):
478 self.s &= set(self.otherword)
479 for c in (self.word + self.otherword):
480 if c in self.otherword and c in self.word:
481 self.assert_(c in self.s)
482 else:
483 self.assert_(c not in self.s)
484
485 def test_difference_update(self):
486 retval = self.s.difference_update(self.otherword)
487 self.assertEqual(retval, None)
488 for c in (self.word + self.otherword):
489 if c in self.word and c not in self.otherword:
490 self.assert_(c in self.s)
491 else:
492 self.assert_(c not in self.s)
493 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
494 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000495 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
496 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
497 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
498 s = self.thetype('abcba')
499 self.assertEqual(s.difference_update(C(p)), None)
500 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000501
Raymond Hettinger4267be62008-06-11 10:30:54 +0000502 s = self.thetype('abcdefghih')
503 s.difference_update()
504 self.assertEqual(s, self.thetype('abcdefghih'))
505
506 s = self.thetype('abcdefghih')
507 s.difference_update(C('aba'))
508 self.assertEqual(s, self.thetype('cdefghih'))
509
510 s = self.thetype('abcdefghih')
511 s.difference_update(C('cdc'), C('aba'))
512 self.assertEqual(s, self.thetype('efghih'))
513
Raymond Hettingera690a992003-11-16 16:17:49 +0000514 def test_isub(self):
515 self.s -= set(self.otherword)
516 for c in (self.word + self.otherword):
517 if c in self.word and c not in self.otherword:
518 self.assert_(c in self.s)
519 else:
520 self.assert_(c not in self.s)
521
522 def test_symmetric_difference_update(self):
523 retval = self.s.symmetric_difference_update(self.otherword)
524 self.assertEqual(retval, None)
525 for c in (self.word + self.otherword):
526 if (c in self.word) ^ (c in self.otherword):
527 self.assert_(c in self.s)
528 else:
529 self.assert_(c not in self.s)
530 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
531 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000532 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
533 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
534 s = self.thetype('abcba')
535 self.assertEqual(s.symmetric_difference_update(C(p)), None)
536 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000537
538 def test_ixor(self):
539 self.s ^= set(self.otherword)
540 for c in (self.word + self.otherword):
541 if (c in self.word) ^ (c in self.otherword):
542 self.assert_(c in self.s)
543 else:
544 self.assert_(c not in self.s)
545
Raymond Hettingerc991db22005-08-11 07:58:45 +0000546 def test_inplace_on_self(self):
547 t = self.s.copy()
548 t |= t
549 self.assertEqual(t, self.s)
550 t &= t
551 self.assertEqual(t, self.s)
552 t -= t
553 self.assertEqual(t, self.thetype())
554 t = self.s.copy()
555 t ^= t
556 self.assertEqual(t, self.thetype())
557
Raymond Hettinger691d8052004-05-30 07:26:47 +0000558 def test_weakref(self):
559 s = self.thetype('gallahad')
Georg Brandl47fe9812009-01-01 15:46:10 +0000560 p = weakref.proxy(s)
Raymond Hettinger691d8052004-05-30 07:26:47 +0000561 self.assertEqual(str(p), str(s))
562 s = None
563 self.assertRaises(ReferenceError, str, p)
564
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000565 # C API test only available in a debug build
Barry Warsaw176014f2006-03-30 22:45:35 +0000566 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000567 def test_c_api(self):
568 self.assertEqual(set('abc').test_c_api(), True)
569
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000570class SetSubclass(set):
571 pass
572
573class TestSetSubclass(TestSet):
574 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000575
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000576class SetSubclassWithKeywordArgs(set):
577 def __init__(self, iterable=[], newarg=None):
578 set.__init__(self, iterable)
579
580class TestSetSubclassWithKeywordArgs(TestSet):
Tim Petersf733abb2007-01-30 03:03:46 +0000581
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000582 def test_keywords_in_subclass(self):
583 'SF bug #1486663 -- this used to erroneously raise a TypeError'
584 SetSubclassWithKeywordArgs(newarg=1)
585
Raymond Hettingera690a992003-11-16 16:17:49 +0000586class TestFrozenSet(TestJointOps):
587 thetype = frozenset
588
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000589 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000590 s = self.thetype(self.word)
591 s.__init__(self.otherword)
592 self.assertEqual(s, set(self.word))
593
Raymond Hettingerd7946662005-08-01 21:39:29 +0000594 def test_singleton_empty_frozenset(self):
595 f = frozenset()
596 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
597 frozenset(), frozenset([]), frozenset(()), frozenset(''),
598 frozenset(xrange(0)), frozenset(frozenset()),
599 frozenset(f), f]
600 # All of the empty frozensets should have just one id()
601 self.assertEqual(len(set(map(id, efs))), 1)
602
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000603 def test_constructor_identity(self):
604 s = self.thetype(range(3))
605 t = self.thetype(s)
606 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000607
Raymond Hettingera690a992003-11-16 16:17:49 +0000608 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000609 self.assertEqual(hash(self.thetype('abcdeb')),
610 hash(self.thetype('ebecda')))
611
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000612 # make sure that all permutations give the same hash value
613 n = 100
614 seq = [randrange(n) for i in xrange(n)]
615 results = set()
616 for i in xrange(200):
617 shuffle(seq)
618 results.add(hash(self.thetype(seq)))
619 self.assertEqual(len(results), 1)
620
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000621 def test_copy(self):
622 dup = self.s.copy()
623 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000624
625 def test_frozen_as_dictkey(self):
626 seq = range(10) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000627 key1 = self.thetype(seq)
628 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000629 self.assertEqual(key1, key2)
630 self.assertNotEqual(id(key1), id(key2))
631 d = {}
632 d[key1] = 42
633 self.assertEqual(d[key2], 42)
634
635 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000636 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000637 self.assertEqual(hash(f), hash(f))
638
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000639 def test_hash_effectiveness(self):
640 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000641 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000642 addhashvalue = hashvalues.add
643 elemmasks = [(i+1, 1<<i) for i in range(n)]
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000644 for i in xrange(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000645 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
646 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000647
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000648class FrozenSetSubclass(frozenset):
649 pass
650
651class TestFrozenSetSubclass(TestFrozenSet):
652 thetype = FrozenSetSubclass
653
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000654 def test_constructor_identity(self):
655 s = self.thetype(range(3))
656 t = self.thetype(s)
657 self.assertNotEqual(id(s), id(t))
658
659 def test_copy(self):
660 dup = self.s.copy()
661 self.assertNotEqual(id(self.s), id(dup))
662
663 def test_nested_empty_constructor(self):
664 s = self.thetype()
665 t = self.thetype(s)
666 self.assertEqual(s, t)
667
Raymond Hettingerd7946662005-08-01 21:39:29 +0000668 def test_singleton_empty_frozenset(self):
669 Frozenset = self.thetype
670 f = frozenset()
671 F = Frozenset()
672 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
673 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
674 Frozenset(xrange(0)), Frozenset(Frozenset()),
675 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
676 # All empty frozenset subclass instances should have different ids
677 self.assertEqual(len(set(map(id, efs))), len(efs))
678
Raymond Hettingera690a992003-11-16 16:17:49 +0000679# Tests taken from test_sets.py =============================================
680
681empty_set = set()
682
683#==============================================================================
684
685class TestBasicOps(unittest.TestCase):
686
687 def test_repr(self):
688 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000689 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000690
Raymond Hettingereae05de2004-07-09 04:51:24 +0000691 def test_print(self):
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000692 fo = open(test_support.TESTFN, "wb")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000693 try:
Raymond Hettingereae05de2004-07-09 04:51:24 +0000694 print >> fo, self.set,
695 fo.close()
696 fo = open(test_support.TESTFN, "rb")
697 self.assertEqual(fo.read(), repr(self.set))
698 finally:
699 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000700 test_support.unlink(test_support.TESTFN)
Raymond Hettingereae05de2004-07-09 04:51:24 +0000701
Raymond Hettingera690a992003-11-16 16:17:49 +0000702 def test_length(self):
703 self.assertEqual(len(self.set), self.length)
704
705 def test_self_equality(self):
706 self.assertEqual(self.set, self.set)
707
708 def test_equivalent_equality(self):
709 self.assertEqual(self.set, self.dup)
710
711 def test_copy(self):
712 self.assertEqual(self.set.copy(), self.dup)
713
714 def test_self_union(self):
715 result = self.set | self.set
716 self.assertEqual(result, self.dup)
717
718 def test_empty_union(self):
719 result = self.set | empty_set
720 self.assertEqual(result, self.dup)
721
722 def test_union_empty(self):
723 result = empty_set | self.set
724 self.assertEqual(result, self.dup)
725
726 def test_self_intersection(self):
727 result = self.set & self.set
728 self.assertEqual(result, self.dup)
729
730 def test_empty_intersection(self):
731 result = self.set & empty_set
732 self.assertEqual(result, empty_set)
733
734 def test_intersection_empty(self):
735 result = empty_set & self.set
736 self.assertEqual(result, empty_set)
737
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000738 def test_self_isdisjoint(self):
739 result = self.set.isdisjoint(self.set)
740 self.assertEqual(result, not self.set)
741
742 def test_empty_isdisjoint(self):
743 result = self.set.isdisjoint(empty_set)
744 self.assertEqual(result, True)
745
746 def test_isdisjoint_empty(self):
747 result = empty_set.isdisjoint(self.set)
748 self.assertEqual(result, True)
749
Raymond Hettingera690a992003-11-16 16:17:49 +0000750 def test_self_symmetric_difference(self):
751 result = self.set ^ self.set
752 self.assertEqual(result, empty_set)
753
Georg Brandld9ede202010-08-01 22:13:33 +0000754 def test_empty_symmetric_difference(self):
Raymond Hettingera690a992003-11-16 16:17:49 +0000755 result = self.set ^ empty_set
756 self.assertEqual(result, self.set)
757
758 def test_self_difference(self):
759 result = self.set - self.set
760 self.assertEqual(result, empty_set)
761
762 def test_empty_difference(self):
763 result = self.set - empty_set
764 self.assertEqual(result, self.dup)
765
766 def test_empty_difference_rev(self):
767 result = empty_set - self.set
768 self.assertEqual(result, empty_set)
769
770 def test_iteration(self):
771 for v in self.set:
772 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000773 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000774 # note: __length_hint__ is an internal undocumented API,
775 # don't rely on it in your own programs
776 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000777
778 def test_pickling(self):
779 p = pickle.dumps(self.set)
780 copy = pickle.loads(p)
781 self.assertEqual(self.set, copy,
782 "%s != %s" % (self.set, copy))
783
784#------------------------------------------------------------------------------
785
786class TestBasicOpsEmpty(TestBasicOps):
787 def setUp(self):
788 self.case = "empty set"
789 self.values = []
790 self.set = set(self.values)
791 self.dup = set(self.values)
792 self.length = 0
793 self.repr = "set([])"
794
795#------------------------------------------------------------------------------
796
797class TestBasicOpsSingleton(TestBasicOps):
798 def setUp(self):
799 self.case = "unit set (number)"
800 self.values = [3]
801 self.set = set(self.values)
802 self.dup = set(self.values)
803 self.length = 1
804 self.repr = "set([3])"
805
806 def test_in(self):
807 self.failUnless(3 in self.set)
808
809 def test_not_in(self):
810 self.failUnless(2 not in self.set)
811
812#------------------------------------------------------------------------------
813
814class TestBasicOpsTuple(TestBasicOps):
815 def setUp(self):
816 self.case = "unit set (tuple)"
817 self.values = [(0, "zero")]
818 self.set = set(self.values)
819 self.dup = set(self.values)
820 self.length = 1
821 self.repr = "set([(0, 'zero')])"
822
823 def test_in(self):
824 self.failUnless((0, "zero") in self.set)
825
826 def test_not_in(self):
827 self.failUnless(9 not in self.set)
828
829#------------------------------------------------------------------------------
830
831class TestBasicOpsTriple(TestBasicOps):
832 def setUp(self):
833 self.case = "triple set"
834 self.values = [0, "zero", operator.add]
835 self.set = set(self.values)
836 self.dup = set(self.values)
837 self.length = 3
838 self.repr = None
839
840#==============================================================================
841
842def baditer():
843 raise TypeError
844 yield True
845
846def gooditer():
847 yield True
848
849class TestExceptionPropagation(unittest.TestCase):
850 """SF 628246: Set constructor should not trap iterator TypeErrors"""
851
852 def test_instanceWithException(self):
853 self.assertRaises(TypeError, set, baditer())
854
855 def test_instancesWithoutException(self):
856 # All of these iterables should load without exception.
857 set([1,2,3])
858 set((1,2,3))
859 set({'one':1, 'two':2, 'three':3})
860 set(xrange(3))
861 set('abc')
862 set(gooditer())
863
Neal Norwitzfcf44352005-11-27 20:37:43 +0000864 def test_changingSizeWhileIterating(self):
865 s = set([1,2,3])
866 try:
867 for i in s:
868 s.update([4])
869 except RuntimeError:
870 pass
871 else:
872 self.fail("no exception when changing size during iteration")
873
Raymond Hettingera690a992003-11-16 16:17:49 +0000874#==============================================================================
875
876class TestSetOfSets(unittest.TestCase):
877 def test_constructor(self):
878 inner = frozenset([1])
879 outer = set([inner])
880 element = outer.pop()
881 self.assertEqual(type(element), frozenset)
882 outer.add(inner) # Rebuild set of sets with .add method
883 outer.remove(inner)
884 self.assertEqual(outer, set()) # Verify that remove worked
885 outer.discard(inner) # Absence of KeyError indicates working fine
886
887#==============================================================================
888
889class TestBinaryOps(unittest.TestCase):
890 def setUp(self):
891 self.set = set((2, 4, 6))
892
893 def test_eq(self): # SF bug 643115
894 self.assertEqual(self.set, set({2:1,4:3,6:5}))
895
896 def test_union_subset(self):
897 result = self.set | set([2])
898 self.assertEqual(result, set((2, 4, 6)))
899
900 def test_union_superset(self):
901 result = self.set | set([2, 4, 6, 8])
902 self.assertEqual(result, set([2, 4, 6, 8]))
903
904 def test_union_overlap(self):
905 result = self.set | set([3, 4, 5])
906 self.assertEqual(result, set([2, 3, 4, 5, 6]))
907
908 def test_union_non_overlap(self):
909 result = self.set | set([8])
910 self.assertEqual(result, set([2, 4, 6, 8]))
911
912 def test_intersection_subset(self):
913 result = self.set & set((2, 4))
914 self.assertEqual(result, set((2, 4)))
915
916 def test_intersection_superset(self):
917 result = self.set & set([2, 4, 6, 8])
918 self.assertEqual(result, set([2, 4, 6]))
919
920 def test_intersection_overlap(self):
921 result = self.set & set([3, 4, 5])
922 self.assertEqual(result, set([4]))
923
924 def test_intersection_non_overlap(self):
925 result = self.set & set([8])
926 self.assertEqual(result, empty_set)
927
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000928 def test_isdisjoint_subset(self):
929 result = self.set.isdisjoint(set((2, 4)))
930 self.assertEqual(result, False)
931
932 def test_isdisjoint_superset(self):
933 result = self.set.isdisjoint(set([2, 4, 6, 8]))
934 self.assertEqual(result, False)
935
936 def test_isdisjoint_overlap(self):
937 result = self.set.isdisjoint(set([3, 4, 5]))
938 self.assertEqual(result, False)
939
940 def test_isdisjoint_non_overlap(self):
941 result = self.set.isdisjoint(set([8]))
942 self.assertEqual(result, True)
943
Raymond Hettingera690a992003-11-16 16:17:49 +0000944 def test_sym_difference_subset(self):
945 result = self.set ^ set((2, 4))
946 self.assertEqual(result, set([6]))
947
948 def test_sym_difference_superset(self):
949 result = self.set ^ set((2, 4, 6, 8))
950 self.assertEqual(result, set([8]))
951
952 def test_sym_difference_overlap(self):
953 result = self.set ^ set((3, 4, 5))
954 self.assertEqual(result, set([2, 3, 5, 6]))
955
956 def test_sym_difference_non_overlap(self):
957 result = self.set ^ set([8])
958 self.assertEqual(result, set([2, 4, 6, 8]))
959
960 def test_cmp(self):
961 a, b = set('a'), set('b')
962 self.assertRaises(TypeError, cmp, a, b)
963
964 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
965 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
966 # which Python thinks is good enough to synthesize a cmp() result
967 # without calling __cmp__.
968 self.assertEqual(cmp(a, a), 0)
969
970 self.assertRaises(TypeError, cmp, a, 12)
971 self.assertRaises(TypeError, cmp, "abc", a)
972
973#==============================================================================
974
975class TestUpdateOps(unittest.TestCase):
976 def setUp(self):
977 self.set = set((2, 4, 6))
978
979 def test_union_subset(self):
980 self.set |= set([2])
981 self.assertEqual(self.set, set((2, 4, 6)))
982
983 def test_union_superset(self):
984 self.set |= set([2, 4, 6, 8])
985 self.assertEqual(self.set, set([2, 4, 6, 8]))
986
987 def test_union_overlap(self):
988 self.set |= set([3, 4, 5])
989 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
990
991 def test_union_non_overlap(self):
992 self.set |= set([8])
993 self.assertEqual(self.set, set([2, 4, 6, 8]))
994
995 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000996 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +0000997 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
998
999 def test_intersection_subset(self):
1000 self.set &= set((2, 4))
1001 self.assertEqual(self.set, set((2, 4)))
1002
1003 def test_intersection_superset(self):
1004 self.set &= set([2, 4, 6, 8])
1005 self.assertEqual(self.set, set([2, 4, 6]))
1006
1007 def test_intersection_overlap(self):
1008 self.set &= set([3, 4, 5])
1009 self.assertEqual(self.set, set([4]))
1010
1011 def test_intersection_non_overlap(self):
1012 self.set &= set([8])
1013 self.assertEqual(self.set, empty_set)
1014
1015 def test_intersection_method_call(self):
1016 self.set.intersection_update(set([3, 4, 5]))
1017 self.assertEqual(self.set, set([4]))
1018
1019 def test_sym_difference_subset(self):
1020 self.set ^= set((2, 4))
1021 self.assertEqual(self.set, set([6]))
1022
1023 def test_sym_difference_superset(self):
1024 self.set ^= set((2, 4, 6, 8))
1025 self.assertEqual(self.set, set([8]))
1026
1027 def test_sym_difference_overlap(self):
1028 self.set ^= set((3, 4, 5))
1029 self.assertEqual(self.set, set([2, 3, 5, 6]))
1030
1031 def test_sym_difference_non_overlap(self):
1032 self.set ^= set([8])
1033 self.assertEqual(self.set, set([2, 4, 6, 8]))
1034
1035 def test_sym_difference_method_call(self):
1036 self.set.symmetric_difference_update(set([3, 4, 5]))
1037 self.assertEqual(self.set, set([2, 3, 5, 6]))
1038
1039 def test_difference_subset(self):
1040 self.set -= set((2, 4))
1041 self.assertEqual(self.set, set([6]))
1042
1043 def test_difference_superset(self):
1044 self.set -= set((2, 4, 6, 8))
1045 self.assertEqual(self.set, set([]))
1046
1047 def test_difference_overlap(self):
1048 self.set -= set((3, 4, 5))
1049 self.assertEqual(self.set, set([2, 6]))
1050
1051 def test_difference_non_overlap(self):
1052 self.set -= set([8])
1053 self.assertEqual(self.set, set([2, 4, 6]))
1054
1055 def test_difference_method_call(self):
1056 self.set.difference_update(set([3, 4, 5]))
1057 self.assertEqual(self.set, set([2, 6]))
1058
1059#==============================================================================
1060
1061class TestMutate(unittest.TestCase):
1062 def setUp(self):
1063 self.values = ["a", "b", "c"]
1064 self.set = set(self.values)
1065
1066 def test_add_present(self):
1067 self.set.add("c")
1068 self.assertEqual(self.set, set("abc"))
1069
1070 def test_add_absent(self):
1071 self.set.add("d")
1072 self.assertEqual(self.set, set("abcd"))
1073
1074 def test_add_until_full(self):
1075 tmp = set()
1076 expected_len = 0
1077 for v in self.values:
1078 tmp.add(v)
1079 expected_len += 1
1080 self.assertEqual(len(tmp), expected_len)
1081 self.assertEqual(tmp, self.set)
1082
1083 def test_remove_present(self):
1084 self.set.remove("b")
1085 self.assertEqual(self.set, set("ac"))
1086
1087 def test_remove_absent(self):
1088 try:
1089 self.set.remove("d")
1090 self.fail("Removing missing element should have raised LookupError")
1091 except LookupError:
1092 pass
1093
1094 def test_remove_until_empty(self):
1095 expected_len = len(self.set)
1096 for v in self.values:
1097 self.set.remove(v)
1098 expected_len -= 1
1099 self.assertEqual(len(self.set), expected_len)
1100
1101 def test_discard_present(self):
1102 self.set.discard("c")
1103 self.assertEqual(self.set, set("ab"))
1104
1105 def test_discard_absent(self):
1106 self.set.discard("d")
1107 self.assertEqual(self.set, set("abc"))
1108
1109 def test_clear(self):
1110 self.set.clear()
1111 self.assertEqual(len(self.set), 0)
1112
1113 def test_pop(self):
1114 popped = {}
1115 while self.set:
1116 popped[self.set.pop()] = None
1117 self.assertEqual(len(popped), len(self.values))
1118 for v in self.values:
1119 self.failUnless(v in popped)
1120
1121 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001122 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001123 self.assertEqual(self.set, set(self.values))
1124
1125 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001126 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001127 self.assertEqual(self.set, set(self.values))
1128
1129 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001130 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001131 self.assertEqual(self.set, set(self.values + ["z"]))
1132
1133#==============================================================================
1134
1135class TestSubsets(unittest.TestCase):
1136
1137 case2method = {"<=": "issubset",
1138 ">=": "issuperset",
1139 }
1140
1141 reverse = {"==": "==",
1142 "!=": "!=",
1143 "<": ">",
1144 ">": "<",
1145 "<=": ">=",
1146 ">=": "<=",
1147 }
1148
1149 def test_issubset(self):
1150 x = self.left
1151 y = self.right
1152 for case in "!=", "==", "<", "<=", ">", ">=":
1153 expected = case in self.cases
1154 # Test the binary infix spelling.
1155 result = eval("x" + case + "y", locals())
1156 self.assertEqual(result, expected)
1157 # Test the "friendly" method-name spelling, if one exists.
1158 if case in TestSubsets.case2method:
1159 method = getattr(x, TestSubsets.case2method[case])
1160 result = method(y)
1161 self.assertEqual(result, expected)
1162
1163 # Now do the same for the operands reversed.
1164 rcase = TestSubsets.reverse[case]
1165 result = eval("y" + rcase + "x", locals())
1166 self.assertEqual(result, expected)
1167 if rcase in TestSubsets.case2method:
1168 method = getattr(y, TestSubsets.case2method[rcase])
1169 result = method(x)
1170 self.assertEqual(result, expected)
1171#------------------------------------------------------------------------------
1172
1173class TestSubsetEqualEmpty(TestSubsets):
1174 left = set()
1175 right = set()
1176 name = "both empty"
1177 cases = "==", "<=", ">="
1178
1179#------------------------------------------------------------------------------
1180
1181class TestSubsetEqualNonEmpty(TestSubsets):
1182 left = set([1, 2])
1183 right = set([1, 2])
1184 name = "equal pair"
1185 cases = "==", "<=", ">="
1186
1187#------------------------------------------------------------------------------
1188
1189class TestSubsetEmptyNonEmpty(TestSubsets):
1190 left = set()
1191 right = set([1, 2])
1192 name = "one empty, one non-empty"
1193 cases = "!=", "<", "<="
1194
1195#------------------------------------------------------------------------------
1196
1197class TestSubsetPartial(TestSubsets):
1198 left = set([1])
1199 right = set([1, 2])
1200 name = "one a non-empty proper subset of other"
1201 cases = "!=", "<", "<="
1202
1203#------------------------------------------------------------------------------
1204
1205class TestSubsetNonOverlap(TestSubsets):
1206 left = set([1])
1207 right = set([2])
1208 name = "neither empty, neither contains"
1209 cases = "!="
1210
1211#==============================================================================
1212
1213class TestOnlySetsInBinaryOps(unittest.TestCase):
1214
1215 def test_eq_ne(self):
1216 # Unlike the others, this is testing that == and != *are* allowed.
1217 self.assertEqual(self.other == self.set, False)
1218 self.assertEqual(self.set == self.other, False)
1219 self.assertEqual(self.other != self.set, True)
1220 self.assertEqual(self.set != self.other, True)
1221
1222 def test_ge_gt_le_lt(self):
1223 self.assertRaises(TypeError, lambda: self.set < self.other)
1224 self.assertRaises(TypeError, lambda: self.set <= self.other)
1225 self.assertRaises(TypeError, lambda: self.set > self.other)
1226 self.assertRaises(TypeError, lambda: self.set >= self.other)
1227
1228 self.assertRaises(TypeError, lambda: self.other < self.set)
1229 self.assertRaises(TypeError, lambda: self.other <= self.set)
1230 self.assertRaises(TypeError, lambda: self.other > self.set)
1231 self.assertRaises(TypeError, lambda: self.other >= self.set)
1232
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001233 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001234 try:
1235 self.set |= self.other
1236 except TypeError:
1237 pass
1238 else:
1239 self.fail("expected TypeError")
1240
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001241 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001242 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001243 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001244 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001245 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001246
1247 def test_union(self):
1248 self.assertRaises(TypeError, lambda: self.set | self.other)
1249 self.assertRaises(TypeError, lambda: self.other | self.set)
1250 if self.otherIsIterable:
1251 self.set.union(self.other)
1252 else:
1253 self.assertRaises(TypeError, self.set.union, self.other)
1254
1255 def test_intersection_update_operator(self):
1256 try:
1257 self.set &= self.other
1258 except TypeError:
1259 pass
1260 else:
1261 self.fail("expected TypeError")
1262
1263 def test_intersection_update(self):
1264 if self.otherIsIterable:
1265 self.set.intersection_update(self.other)
1266 else:
1267 self.assertRaises(TypeError,
1268 self.set.intersection_update,
1269 self.other)
1270
1271 def test_intersection(self):
1272 self.assertRaises(TypeError, lambda: self.set & self.other)
1273 self.assertRaises(TypeError, lambda: self.other & self.set)
1274 if self.otherIsIterable:
1275 self.set.intersection(self.other)
1276 else:
1277 self.assertRaises(TypeError, self.set.intersection, self.other)
1278
1279 def test_sym_difference_update_operator(self):
1280 try:
1281 self.set ^= self.other
1282 except TypeError:
1283 pass
1284 else:
1285 self.fail("expected TypeError")
1286
1287 def test_sym_difference_update(self):
1288 if self.otherIsIterable:
1289 self.set.symmetric_difference_update(self.other)
1290 else:
1291 self.assertRaises(TypeError,
1292 self.set.symmetric_difference_update,
1293 self.other)
1294
1295 def test_sym_difference(self):
1296 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1297 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1298 if self.otherIsIterable:
1299 self.set.symmetric_difference(self.other)
1300 else:
1301 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1302
1303 def test_difference_update_operator(self):
1304 try:
1305 self.set -= self.other
1306 except TypeError:
1307 pass
1308 else:
1309 self.fail("expected TypeError")
1310
1311 def test_difference_update(self):
1312 if self.otherIsIterable:
1313 self.set.difference_update(self.other)
1314 else:
1315 self.assertRaises(TypeError,
1316 self.set.difference_update,
1317 self.other)
1318
1319 def test_difference(self):
1320 self.assertRaises(TypeError, lambda: self.set - self.other)
1321 self.assertRaises(TypeError, lambda: self.other - self.set)
1322 if self.otherIsIterable:
1323 self.set.difference(self.other)
1324 else:
1325 self.assertRaises(TypeError, self.set.difference, self.other)
1326
1327#------------------------------------------------------------------------------
1328
1329class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1330 def setUp(self):
1331 self.set = set((1, 2, 3))
1332 self.other = 19
1333 self.otherIsIterable = False
1334
1335#------------------------------------------------------------------------------
1336
1337class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1338 def setUp(self):
1339 self.set = set((1, 2, 3))
1340 self.other = {1:2, 3:4}
1341 self.otherIsIterable = True
1342
1343#------------------------------------------------------------------------------
1344
1345class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1346 def setUp(self):
1347 self.set = set((1, 2, 3))
1348 self.other = operator.add
1349 self.otherIsIterable = False
1350
1351#------------------------------------------------------------------------------
1352
1353class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1354 def setUp(self):
1355 self.set = set((1, 2, 3))
1356 self.other = (2, 4, 6)
1357 self.otherIsIterable = True
1358
1359#------------------------------------------------------------------------------
1360
1361class TestOnlySetsString(TestOnlySetsInBinaryOps):
1362 def setUp(self):
1363 self.set = set((1, 2, 3))
1364 self.other = 'abc'
1365 self.otherIsIterable = True
1366
1367#------------------------------------------------------------------------------
1368
1369class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1370 def setUp(self):
1371 def gen():
1372 for i in xrange(0, 10, 2):
1373 yield i
1374 self.set = set((1, 2, 3))
1375 self.other = gen()
1376 self.otherIsIterable = True
1377
1378#==============================================================================
1379
1380class TestCopying(unittest.TestCase):
1381
1382 def test_copy(self):
1383 dup = self.set.copy()
1384 dup_list = list(dup); dup_list.sort()
1385 set_list = list(self.set); set_list.sort()
1386 self.assertEqual(len(dup_list), len(set_list))
1387 for i in range(len(dup_list)):
1388 self.failUnless(dup_list[i] is set_list[i])
1389
1390 def test_deep_copy(self):
1391 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001392 ##print type(dup), repr(dup)
Raymond Hettingera690a992003-11-16 16:17:49 +00001393 dup_list = list(dup); dup_list.sort()
1394 set_list = list(self.set); set_list.sort()
1395 self.assertEqual(len(dup_list), len(set_list))
1396 for i in range(len(dup_list)):
1397 self.assertEqual(dup_list[i], set_list[i])
1398
1399#------------------------------------------------------------------------------
1400
1401class TestCopyingEmpty(TestCopying):
1402 def setUp(self):
1403 self.set = set()
1404
1405#------------------------------------------------------------------------------
1406
1407class TestCopyingSingleton(TestCopying):
1408 def setUp(self):
1409 self.set = set(["hello"])
1410
1411#------------------------------------------------------------------------------
1412
1413class TestCopyingTriple(TestCopying):
1414 def setUp(self):
1415 self.set = set(["zero", 0, None])
1416
1417#------------------------------------------------------------------------------
1418
1419class TestCopyingTuple(TestCopying):
1420 def setUp(self):
1421 self.set = set([(1, 2)])
1422
1423#------------------------------------------------------------------------------
1424
1425class TestCopyingNested(TestCopying):
1426 def setUp(self):
1427 self.set = set([((1, 2), (3, 4))])
1428
1429#==============================================================================
1430
1431class TestIdentities(unittest.TestCase):
1432 def setUp(self):
1433 self.a = set('abracadabra')
1434 self.b = set('alacazam')
1435
1436 def test_binopsVsSubsets(self):
1437 a, b = self.a, self.b
1438 self.assert_(a - b < a)
1439 self.assert_(b - a < b)
1440 self.assert_(a & b < a)
1441 self.assert_(a & b < b)
1442 self.assert_(a | b > a)
1443 self.assert_(a | b > b)
1444 self.assert_(a ^ b < a | b)
1445
1446 def test_commutativity(self):
1447 a, b = self.a, self.b
1448 self.assertEqual(a&b, b&a)
1449 self.assertEqual(a|b, b|a)
1450 self.assertEqual(a^b, b^a)
1451 if a != b:
1452 self.assertNotEqual(a-b, b-a)
1453
1454 def test_summations(self):
1455 # check that sums of parts equal the whole
1456 a, b = self.a, self.b
1457 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1458 self.assertEqual((a&b)|(a^b), a|b)
1459 self.assertEqual(a|(b-a), a|b)
1460 self.assertEqual((a-b)|b, a|b)
1461 self.assertEqual((a-b)|(a&b), a)
1462 self.assertEqual((b-a)|(a&b), b)
1463 self.assertEqual((a-b)|(b-a), a^b)
1464
1465 def test_exclusion(self):
1466 # check that inverse operations show non-overlap
1467 a, b, zero = self.a, self.b, set()
1468 self.assertEqual((a-b)&b, zero)
1469 self.assertEqual((b-a)&a, zero)
1470 self.assertEqual((a&b)&(a^b), zero)
1471
1472# Tests derived from test_itertools.py =======================================
1473
1474def R(seqn):
1475 'Regular generator'
1476 for i in seqn:
1477 yield i
1478
1479class G:
1480 'Sequence using __getitem__'
1481 def __init__(self, seqn):
1482 self.seqn = seqn
1483 def __getitem__(self, i):
1484 return self.seqn[i]
1485
1486class I:
1487 'Sequence using iterator protocol'
1488 def __init__(self, seqn):
1489 self.seqn = seqn
1490 self.i = 0
1491 def __iter__(self):
1492 return self
1493 def next(self):
1494 if self.i >= len(self.seqn): raise StopIteration
1495 v = self.seqn[self.i]
1496 self.i += 1
1497 return v
1498
1499class Ig:
1500 'Sequence using iterator protocol defined with a generator'
1501 def __init__(self, seqn):
1502 self.seqn = seqn
1503 self.i = 0
1504 def __iter__(self):
1505 for val in self.seqn:
1506 yield val
1507
1508class X:
1509 'Missing __getitem__ and __iter__'
1510 def __init__(self, seqn):
1511 self.seqn = seqn
1512 self.i = 0
1513 def next(self):
1514 if self.i >= len(self.seqn): raise StopIteration
1515 v = self.seqn[self.i]
1516 self.i += 1
1517 return v
1518
1519class N:
1520 'Iterator missing next()'
1521 def __init__(self, seqn):
1522 self.seqn = seqn
1523 self.i = 0
1524 def __iter__(self):
1525 return self
1526
1527class E:
1528 'Test propagation of exceptions'
1529 def __init__(self, seqn):
1530 self.seqn = seqn
1531 self.i = 0
1532 def __iter__(self):
1533 return self
1534 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001535 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001536
1537class S:
1538 'Test immediate stop'
1539 def __init__(self, seqn):
1540 pass
1541 def __iter__(self):
1542 return self
1543 def next(self):
1544 raise StopIteration
1545
1546from itertools import chain, imap
1547def L(seqn):
1548 'Test multiple tiers of iterators'
1549 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1550
1551class TestVariousIteratorArgs(unittest.TestCase):
1552
1553 def test_constructor(self):
1554 for cons in (set, frozenset):
1555 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1556 for g in (G, I, Ig, S, L, R):
Raymond Hettinger64958a12003-12-17 20:43:33 +00001557 self.assertEqual(sorted(cons(g(s))), sorted(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001558 self.assertRaises(TypeError, cons , X(s))
1559 self.assertRaises(TypeError, cons , N(s))
1560 self.assertRaises(ZeroDivisionError, cons , E(s))
1561
1562 def test_inline_methods(self):
1563 s = set('november')
1564 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001565 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001566 for g in (G, I, Ig, L, R):
1567 expected = meth(data)
1568 actual = meth(G(data))
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001569 if isinstance(expected, bool):
1570 self.assertEqual(actual, expected)
1571 else:
1572 self.assertEqual(sorted(actual), sorted(expected))
Raymond Hettingera690a992003-11-16 16:17:49 +00001573 self.assertRaises(TypeError, meth, X(s))
1574 self.assertRaises(TypeError, meth, N(s))
1575 self.assertRaises(ZeroDivisionError, meth, E(s))
1576
1577 def test_inplace_methods(self):
1578 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001579 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001580 'difference_update', 'symmetric_difference_update'):
1581 for g in (G, I, Ig, S, L, R):
1582 s = set('january')
1583 t = s.copy()
1584 getattr(s, methname)(list(g(data)))
1585 getattr(t, methname)(g(data))
Raymond Hettinger64958a12003-12-17 20:43:33 +00001586 self.assertEqual(sorted(s), sorted(t))
Raymond Hettingera690a992003-11-16 16:17:49 +00001587
1588 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1589 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1590 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1591
Raymond Hettinger61708742008-01-24 21:23:58 +00001592# Application tests (based on David Eppstein's graph recipes ====================================
1593
1594def powerset(U):
1595 """Generates all subsets of a set or sequence U."""
1596 U = iter(U)
1597 try:
1598 x = frozenset([U.next()])
1599 for S in powerset(U):
1600 yield S
1601 yield S | x
1602 except StopIteration:
1603 yield frozenset()
1604
1605def cube(n):
1606 """Graph of n-dimensional hypercube."""
1607 singletons = [frozenset([x]) for x in range(n)]
1608 return dict([(x, frozenset([x^s for s in singletons]))
1609 for x in powerset(range(n))])
1610
1611def linegraph(G):
1612 """Graph, the vertices of which are edges of G,
1613 with two vertices being adjacent iff the corresponding
1614 edges share a vertex."""
1615 L = {}
1616 for x in G:
1617 for y in G[x]:
1618 nx = [frozenset([x,z]) for z in G[x] if z != y]
1619 ny = [frozenset([y,z]) for z in G[y] if z != x]
1620 L[frozenset([x,y])] = frozenset(nx+ny)
1621 return L
1622
1623def faces(G):
1624 'Return a set of faces in G. Where a face is a set of vertices on that face'
1625 # currently limited to triangles,squares, and pentagons
1626 f = set()
1627 for v1, edges in G.items():
1628 for v2 in edges:
1629 for v3 in G[v2]:
1630 if v1 == v3:
1631 continue
1632 if v1 in G[v3]:
1633 f.add(frozenset([v1, v2, v3]))
1634 else:
1635 for v4 in G[v3]:
1636 if v4 == v2:
1637 continue
1638 if v1 in G[v4]:
1639 f.add(frozenset([v1, v2, v3, v4]))
1640 else:
1641 for v5 in G[v4]:
1642 if v5 == v3 or v5 == v2:
1643 continue
1644 if v1 in G[v5]:
1645 f.add(frozenset([v1, v2, v3, v4, v5]))
1646 return f
1647
1648
1649class TestGraphs(unittest.TestCase):
1650
1651 def test_cube(self):
1652
1653 g = cube(3) # vert --> {v1, v2, v3}
1654 vertices1 = set(g)
1655 self.assertEqual(len(vertices1), 8) # eight vertices
1656 for edge in g.values():
1657 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1658 vertices2 = set(v for edges in g.values() for v in edges)
1659 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1660
1661 cubefaces = faces(g)
1662 self.assertEqual(len(cubefaces), 6) # six faces
1663 for face in cubefaces:
1664 self.assertEqual(len(face), 4) # each face is a square
1665
1666 def test_cuboctahedron(self):
1667
1668 # http://en.wikipedia.org/wiki/Cuboctahedron
1669 # 8 triangular faces and 6 square faces
1670 # 12 indentical vertices each connecting a triangle and square
1671
1672 g = cube(3)
1673 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1674 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1675
1676 vertices = set(cuboctahedron)
1677 for edges in cuboctahedron.values():
1678 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1679 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1680 self.assertEqual(vertices, othervertices) # edge vertices in original set
1681
1682 cubofaces = faces(cuboctahedron)
1683 facesizes = collections.defaultdict(int)
1684 for face in cubofaces:
1685 facesizes[len(face)] += 1
1686 self.assertEqual(facesizes[3], 8) # eight triangular faces
1687 self.assertEqual(facesizes[4], 6) # six square faces
1688
1689 for vertex in cuboctahedron:
1690 edge = vertex # Cuboctahedron vertices are edges in Cube
1691 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1692 for cubevert in edge:
1693 self.assert_(cubevert in g)
1694
1695
Raymond Hettingera690a992003-11-16 16:17:49 +00001696#==============================================================================
1697
1698def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001699 from test import test_sets
1700 test_classes = (
1701 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001702 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001703 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001704 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001705 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001706 TestSetOfSets,
1707 TestExceptionPropagation,
1708 TestBasicOpsEmpty,
1709 TestBasicOpsSingleton,
1710 TestBasicOpsTuple,
1711 TestBasicOpsTriple,
1712 TestBinaryOps,
1713 TestUpdateOps,
1714 TestMutate,
1715 TestSubsetEqualEmpty,
1716 TestSubsetEqualNonEmpty,
1717 TestSubsetEmptyNonEmpty,
1718 TestSubsetPartial,
1719 TestSubsetNonOverlap,
1720 TestOnlySetsNumeric,
1721 TestOnlySetsDict,
1722 TestOnlySetsOperator,
1723 TestOnlySetsTuple,
1724 TestOnlySetsString,
1725 TestOnlySetsGenerator,
1726 TestCopyingEmpty,
1727 TestCopyingSingleton,
1728 TestCopyingTriple,
1729 TestCopyingTuple,
1730 TestCopyingNested,
1731 TestIdentities,
1732 TestVariousIteratorArgs,
Raymond Hettinger61708742008-01-24 21:23:58 +00001733 TestGraphs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001734 )
1735
1736 test_support.run_unittest(*test_classes)
1737
1738 # verify reference counting
1739 if verbose and hasattr(sys, "gettotalrefcount"):
1740 import gc
1741 counts = [None] * 5
1742 for i in xrange(len(counts)):
1743 test_support.run_unittest(*test_classes)
1744 gc.collect()
1745 counts[i] = sys.gettotalrefcount()
1746 print counts
1747
1748if __name__ == "__main__":
1749 test_main(verbose=True)