blob: 3539a14065813b41cfe2429b135389fab8bc688d [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
Ezio Melottia65e2af2010-08-02 19:56:05 +00001351 def test_ge_gt_le_lt(self):
1352 with test_support._check_py3k_warnings():
1353 super(TestOnlySetsOperator, self).test_ge_gt_le_lt()
1354
Raymond Hettingera690a992003-11-16 16:17:49 +00001355#------------------------------------------------------------------------------
1356
1357class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1358 def setUp(self):
1359 self.set = set((1, 2, 3))
1360 self.other = (2, 4, 6)
1361 self.otherIsIterable = True
1362
1363#------------------------------------------------------------------------------
1364
1365class TestOnlySetsString(TestOnlySetsInBinaryOps):
1366 def setUp(self):
1367 self.set = set((1, 2, 3))
1368 self.other = 'abc'
1369 self.otherIsIterable = True
1370
1371#------------------------------------------------------------------------------
1372
1373class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1374 def setUp(self):
1375 def gen():
1376 for i in xrange(0, 10, 2):
1377 yield i
1378 self.set = set((1, 2, 3))
1379 self.other = gen()
1380 self.otherIsIterable = True
1381
1382#==============================================================================
1383
1384class TestCopying(unittest.TestCase):
1385
1386 def test_copy(self):
1387 dup = self.set.copy()
Ezio Melotti5c752352010-08-03 08:41:02 +00001388 with test_support.check_warnings():
1389 dup_list = sorted(dup)
1390 set_list = sorted(self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +00001391 self.assertEqual(len(dup_list), len(set_list))
1392 for i in range(len(dup_list)):
1393 self.failUnless(dup_list[i] is set_list[i])
1394
1395 def test_deep_copy(self):
1396 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001397 ##print type(dup), repr(dup)
Ezio Melotti5c752352010-08-03 08:41:02 +00001398 with test_support.check_warnings():
1399 dup_list = sorted(dup)
1400 set_list = sorted(self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +00001401 self.assertEqual(len(dup_list), len(set_list))
1402 for i in range(len(dup_list)):
1403 self.assertEqual(dup_list[i], set_list[i])
1404
1405#------------------------------------------------------------------------------
1406
1407class TestCopyingEmpty(TestCopying):
1408 def setUp(self):
1409 self.set = set()
1410
1411#------------------------------------------------------------------------------
1412
1413class TestCopyingSingleton(TestCopying):
1414 def setUp(self):
1415 self.set = set(["hello"])
1416
1417#------------------------------------------------------------------------------
1418
1419class TestCopyingTriple(TestCopying):
1420 def setUp(self):
1421 self.set = set(["zero", 0, None])
1422
1423#------------------------------------------------------------------------------
1424
1425class TestCopyingTuple(TestCopying):
1426 def setUp(self):
1427 self.set = set([(1, 2)])
1428
1429#------------------------------------------------------------------------------
1430
1431class TestCopyingNested(TestCopying):
1432 def setUp(self):
1433 self.set = set([((1, 2), (3, 4))])
1434
1435#==============================================================================
1436
1437class TestIdentities(unittest.TestCase):
1438 def setUp(self):
1439 self.a = set('abracadabra')
1440 self.b = set('alacazam')
1441
1442 def test_binopsVsSubsets(self):
1443 a, b = self.a, self.b
1444 self.assert_(a - b < a)
1445 self.assert_(b - a < b)
1446 self.assert_(a & b < a)
1447 self.assert_(a & b < b)
1448 self.assert_(a | b > a)
1449 self.assert_(a | b > b)
1450 self.assert_(a ^ b < a | b)
1451
1452 def test_commutativity(self):
1453 a, b = self.a, self.b
1454 self.assertEqual(a&b, b&a)
1455 self.assertEqual(a|b, b|a)
1456 self.assertEqual(a^b, b^a)
1457 if a != b:
1458 self.assertNotEqual(a-b, b-a)
1459
1460 def test_summations(self):
1461 # check that sums of parts equal the whole
1462 a, b = self.a, self.b
1463 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1464 self.assertEqual((a&b)|(a^b), a|b)
1465 self.assertEqual(a|(b-a), a|b)
1466 self.assertEqual((a-b)|b, a|b)
1467 self.assertEqual((a-b)|(a&b), a)
1468 self.assertEqual((b-a)|(a&b), b)
1469 self.assertEqual((a-b)|(b-a), a^b)
1470
1471 def test_exclusion(self):
1472 # check that inverse operations show non-overlap
1473 a, b, zero = self.a, self.b, set()
1474 self.assertEqual((a-b)&b, zero)
1475 self.assertEqual((b-a)&a, zero)
1476 self.assertEqual((a&b)&(a^b), zero)
1477
1478# Tests derived from test_itertools.py =======================================
1479
1480def R(seqn):
1481 'Regular generator'
1482 for i in seqn:
1483 yield i
1484
1485class G:
1486 'Sequence using __getitem__'
1487 def __init__(self, seqn):
1488 self.seqn = seqn
1489 def __getitem__(self, i):
1490 return self.seqn[i]
1491
1492class I:
1493 'Sequence using iterator protocol'
1494 def __init__(self, seqn):
1495 self.seqn = seqn
1496 self.i = 0
1497 def __iter__(self):
1498 return self
1499 def next(self):
1500 if self.i >= len(self.seqn): raise StopIteration
1501 v = self.seqn[self.i]
1502 self.i += 1
1503 return v
1504
1505class Ig:
1506 'Sequence using iterator protocol defined with a generator'
1507 def __init__(self, seqn):
1508 self.seqn = seqn
1509 self.i = 0
1510 def __iter__(self):
1511 for val in self.seqn:
1512 yield val
1513
1514class X:
1515 'Missing __getitem__ and __iter__'
1516 def __init__(self, seqn):
1517 self.seqn = seqn
1518 self.i = 0
1519 def next(self):
1520 if self.i >= len(self.seqn): raise StopIteration
1521 v = self.seqn[self.i]
1522 self.i += 1
1523 return v
1524
1525class N:
1526 'Iterator missing next()'
1527 def __init__(self, seqn):
1528 self.seqn = seqn
1529 self.i = 0
1530 def __iter__(self):
1531 return self
1532
1533class E:
1534 'Test propagation of exceptions'
1535 def __init__(self, seqn):
1536 self.seqn = seqn
1537 self.i = 0
1538 def __iter__(self):
1539 return self
1540 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001541 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001542
1543class S:
1544 'Test immediate stop'
1545 def __init__(self, seqn):
1546 pass
1547 def __iter__(self):
1548 return self
1549 def next(self):
1550 raise StopIteration
1551
1552from itertools import chain, imap
1553def L(seqn):
1554 'Test multiple tiers of iterators'
1555 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1556
1557class TestVariousIteratorArgs(unittest.TestCase):
1558
1559 def test_constructor(self):
1560 for cons in (set, frozenset):
1561 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
Ezio Melotti5c752352010-08-03 08:41:02 +00001562 with test_support.check_warnings():
1563 for g in (G, I, Ig, S, L, R):
1564 self.assertEqual(sorted(cons(g(s))), sorted(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001565 self.assertRaises(TypeError, cons , X(s))
1566 self.assertRaises(TypeError, cons , N(s))
1567 self.assertRaises(ZeroDivisionError, cons , E(s))
1568
1569 def test_inline_methods(self):
1570 s = set('november')
1571 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001572 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001573 for g in (G, I, Ig, L, R):
1574 expected = meth(data)
1575 actual = meth(G(data))
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001576 if isinstance(expected, bool):
1577 self.assertEqual(actual, expected)
1578 else:
Ezio Melotti5c752352010-08-03 08:41:02 +00001579 with test_support.check_warnings():
1580 self.assertEqual(sorted(actual), sorted(expected))
Raymond Hettingera690a992003-11-16 16:17:49 +00001581 self.assertRaises(TypeError, meth, X(s))
1582 self.assertRaises(TypeError, meth, N(s))
1583 self.assertRaises(ZeroDivisionError, meth, E(s))
1584
1585 def test_inplace_methods(self):
1586 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001587 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001588 'difference_update', 'symmetric_difference_update'):
1589 for g in (G, I, Ig, S, L, R):
1590 s = set('january')
1591 t = s.copy()
1592 getattr(s, methname)(list(g(data)))
1593 getattr(t, methname)(g(data))
Ezio Melotti5c752352010-08-03 08:41:02 +00001594 with test_support.check_warnings():
1595 self.assertEqual(sorted(s), sorted(t))
Raymond Hettingera690a992003-11-16 16:17:49 +00001596
1597 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1598 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1599 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1600
Raymond Hettinger61708742008-01-24 21:23:58 +00001601# Application tests (based on David Eppstein's graph recipes ====================================
1602
1603def powerset(U):
1604 """Generates all subsets of a set or sequence U."""
1605 U = iter(U)
1606 try:
1607 x = frozenset([U.next()])
1608 for S in powerset(U):
1609 yield S
1610 yield S | x
1611 except StopIteration:
1612 yield frozenset()
1613
1614def cube(n):
1615 """Graph of n-dimensional hypercube."""
1616 singletons = [frozenset([x]) for x in range(n)]
1617 return dict([(x, frozenset([x^s for s in singletons]))
1618 for x in powerset(range(n))])
1619
1620def linegraph(G):
1621 """Graph, the vertices of which are edges of G,
1622 with two vertices being adjacent iff the corresponding
1623 edges share a vertex."""
1624 L = {}
1625 for x in G:
1626 for y in G[x]:
1627 nx = [frozenset([x,z]) for z in G[x] if z != y]
1628 ny = [frozenset([y,z]) for z in G[y] if z != x]
1629 L[frozenset([x,y])] = frozenset(nx+ny)
1630 return L
1631
1632def faces(G):
1633 'Return a set of faces in G. Where a face is a set of vertices on that face'
1634 # currently limited to triangles,squares, and pentagons
1635 f = set()
1636 for v1, edges in G.items():
1637 for v2 in edges:
1638 for v3 in G[v2]:
1639 if v1 == v3:
1640 continue
1641 if v1 in G[v3]:
1642 f.add(frozenset([v1, v2, v3]))
1643 else:
1644 for v4 in G[v3]:
1645 if v4 == v2:
1646 continue
1647 if v1 in G[v4]:
1648 f.add(frozenset([v1, v2, v3, v4]))
1649 else:
1650 for v5 in G[v4]:
1651 if v5 == v3 or v5 == v2:
1652 continue
1653 if v1 in G[v5]:
1654 f.add(frozenset([v1, v2, v3, v4, v5]))
1655 return f
1656
1657
1658class TestGraphs(unittest.TestCase):
1659
1660 def test_cube(self):
1661
1662 g = cube(3) # vert --> {v1, v2, v3}
1663 vertices1 = set(g)
1664 self.assertEqual(len(vertices1), 8) # eight vertices
1665 for edge in g.values():
1666 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1667 vertices2 = set(v for edges in g.values() for v in edges)
1668 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1669
1670 cubefaces = faces(g)
1671 self.assertEqual(len(cubefaces), 6) # six faces
1672 for face in cubefaces:
1673 self.assertEqual(len(face), 4) # each face is a square
1674
1675 def test_cuboctahedron(self):
1676
1677 # http://en.wikipedia.org/wiki/Cuboctahedron
1678 # 8 triangular faces and 6 square faces
1679 # 12 indentical vertices each connecting a triangle and square
1680
1681 g = cube(3)
1682 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1683 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1684
1685 vertices = set(cuboctahedron)
1686 for edges in cuboctahedron.values():
1687 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1688 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1689 self.assertEqual(vertices, othervertices) # edge vertices in original set
1690
1691 cubofaces = faces(cuboctahedron)
1692 facesizes = collections.defaultdict(int)
1693 for face in cubofaces:
1694 facesizes[len(face)] += 1
1695 self.assertEqual(facesizes[3], 8) # eight triangular faces
1696 self.assertEqual(facesizes[4], 6) # six square faces
1697
1698 for vertex in cuboctahedron:
1699 edge = vertex # Cuboctahedron vertices are edges in Cube
1700 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1701 for cubevert in edge:
1702 self.assert_(cubevert in g)
1703
1704
Raymond Hettingera690a992003-11-16 16:17:49 +00001705#==============================================================================
1706
1707def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001708 from test import test_sets
1709 test_classes = (
1710 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001711 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001712 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001713 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001714 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001715 TestSetOfSets,
1716 TestExceptionPropagation,
1717 TestBasicOpsEmpty,
1718 TestBasicOpsSingleton,
1719 TestBasicOpsTuple,
1720 TestBasicOpsTriple,
1721 TestBinaryOps,
1722 TestUpdateOps,
1723 TestMutate,
1724 TestSubsetEqualEmpty,
1725 TestSubsetEqualNonEmpty,
1726 TestSubsetEmptyNonEmpty,
1727 TestSubsetPartial,
1728 TestSubsetNonOverlap,
1729 TestOnlySetsNumeric,
1730 TestOnlySetsDict,
1731 TestOnlySetsOperator,
1732 TestOnlySetsTuple,
1733 TestOnlySetsString,
1734 TestOnlySetsGenerator,
1735 TestCopyingEmpty,
1736 TestCopyingSingleton,
1737 TestCopyingTriple,
1738 TestCopyingTuple,
1739 TestCopyingNested,
1740 TestIdentities,
1741 TestVariousIteratorArgs,
Raymond Hettinger61708742008-01-24 21:23:58 +00001742 TestGraphs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001743 )
1744
1745 test_support.run_unittest(*test_classes)
1746
1747 # verify reference counting
1748 if verbose and hasattr(sys, "gettotalrefcount"):
1749 import gc
1750 counts = [None] * 5
1751 for i in xrange(len(counts)):
1752 test_support.run_unittest(*test_classes)
1753 gc.collect()
1754 counts[i] = sys.gettotalrefcount()
1755 print counts
1756
1757if __name__ == "__main__":
1758 test_main(verbose=True)