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