blob: 18822cad59dd0743da9ed8bf705c27eee7d9ef36 [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 Hettinger82cb9a22005-07-05 05:34:43 +00009from random import randrange, shuffle
Raymond Hettingerc47e01d2005-08-16 10:44:15 +000010import sys
Raymond Hettinger61708742008-01-24 21:23:58 +000011import collections
Raymond Hettingera690a992003-11-16 16:17:49 +000012
13class PassThru(Exception):
14 pass
15
16def check_pass_thru():
17 raise PassThru
18 yield 1
19
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000020class BadCmp:
21 def __hash__(self):
22 return 1
23 def __cmp__(self, other):
24 raise RuntimeError
25
Raymond Hettinger53999102006-12-30 04:01:17 +000026class ReprWrapper:
27 'Used to test self-referential repr() calls'
28 def __repr__(self):
29 return repr(self.value)
30
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +000031class HashCountingInt(int):
32 'int-like object that counts the number of times __hash__ is called'
33 def __init__(self, *args):
34 self.hash_count = 0
35 def __hash__(self):
36 self.hash_count += 1
37 return int.__hash__(self)
38
Raymond Hettingera690a992003-11-16 16:17:49 +000039class TestJointOps(unittest.TestCase):
40 # Tests common to both set and frozenset
41
42 def setUp(self):
43 self.word = word = 'simsalabim'
44 self.otherword = 'madagascar'
45 self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
46 self.s = self.thetype(word)
47 self.d = dict.fromkeys(word)
48
Raymond Hettinger6429a472004-09-28 01:51:35 +000049 def test_new_or_init(self):
50 self.assertRaises(TypeError, self.thetype, [], 2)
Raymond Hettingerefa19842010-04-18 22:59:34 +000051 self.assertRaises(TypeError, set().__init__, a=1)
Raymond Hettinger6429a472004-09-28 01:51:35 +000052
Raymond Hettingera690a992003-11-16 16:17:49 +000053 def test_uniquification(self):
Raymond Hettinger64958a12003-12-17 20:43:33 +000054 actual = sorted(self.s)
55 expected = sorted(self.d)
Raymond Hettingera690a992003-11-16 16:17:49 +000056 self.assertEqual(actual, expected)
57 self.assertRaises(PassThru, self.thetype, check_pass_thru())
58 self.assertRaises(TypeError, self.thetype, [[]])
59
60 def test_len(self):
61 self.assertEqual(len(self.s), len(self.d))
62
63 def test_contains(self):
64 for c in self.letters:
65 self.assertEqual(c in self.s, c in self.d)
66 self.assertRaises(TypeError, self.s.__contains__, [[]])
Raymond Hettinger19c2d772003-11-21 18:36:54 +000067 s = self.thetype([frozenset(self.letters)])
68 self.assert_(self.thetype(self.letters) in s)
Raymond Hettingera690a992003-11-16 16:17:49 +000069
Raymond Hettingera690a992003-11-16 16:17:49 +000070 def test_union(self):
71 u = self.s.union(self.otherword)
72 for c in self.letters:
73 self.assertEqual(c in u, c in self.d or c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000074 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000075 self.assertEqual(type(u), self.thetype)
76 self.assertRaises(PassThru, self.s.union, check_pass_thru())
77 self.assertRaises(TypeError, self.s.union, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000078 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
79 self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
80 self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
81 self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
82 self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +000083 self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
Raymond Hettingera690a992003-11-16 16:17:49 +000084
Raymond Hettinger30006c72009-07-27 20:33:25 +000085 # Issue #6573
86 x = self.thetype()
87 self.assertEqual(x.union(set([1]), x, set([2])), self.thetype([1, 2]))
88
Raymond Hettingera690a992003-11-16 16:17:49 +000089 def test_or(self):
90 i = self.s.union(self.otherword)
91 self.assertEqual(self.s | set(self.otherword), i)
92 self.assertEqual(self.s | frozenset(self.otherword), i)
93 try:
94 self.s | self.otherword
95 except TypeError:
96 pass
97 else:
98 self.fail("s|t did not screen-out general iterables")
99
100 def test_intersection(self):
101 i = self.s.intersection(self.otherword)
102 for c in self.letters:
103 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000104 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000105 self.assertEqual(type(i), self.thetype)
106 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000107 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
108 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
109 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
110 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
111 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000112 self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
Raymond Hettinger610a93e2008-06-11 00:44:47 +0000113 s = self.thetype('abcba')
114 z = s.intersection()
115 if self.thetype == frozenset():
116 self.assertEqual(id(s), id(z))
117 else:
118 self.assertNotEqual(id(s), id(z))
Raymond Hettingera690a992003-11-16 16:17:49 +0000119
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000120 def test_isdisjoint(self):
121 def f(s1, s2):
122 'Pure python equivalent of isdisjoint()'
123 return not set(s1).intersection(s2)
124 for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
125 s1 = self.thetype(larg)
126 for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
127 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
128 s2 = C(rarg)
129 actual = s1.isdisjoint(s2)
130 expected = f(s1, s2)
131 self.assertEqual(actual, expected)
132 self.assert_(actual is True or actual is False)
133
Raymond Hettingera690a992003-11-16 16:17:49 +0000134 def test_and(self):
135 i = self.s.intersection(self.otherword)
136 self.assertEqual(self.s & set(self.otherword), i)
137 self.assertEqual(self.s & frozenset(self.otherword), i)
138 try:
139 self.s & self.otherword
140 except TypeError:
141 pass
142 else:
143 self.fail("s&t did not screen-out general iterables")
144
145 def test_difference(self):
146 i = self.s.difference(self.otherword)
147 for c in self.letters:
148 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000149 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000150 self.assertEqual(type(i), self.thetype)
151 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
152 self.assertRaises(TypeError, self.s.difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000153 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
154 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
155 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
156 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
157 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettinger4267be62008-06-11 10:30:54 +0000158 self.assertEqual(self.thetype('abcba').difference(), set('abc'))
159 self.assertEqual(self.thetype('abcba').difference(C('a'), C('b')), set('c'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000160
161 def test_sub(self):
162 i = self.s.difference(self.otherword)
163 self.assertEqual(self.s - set(self.otherword), i)
164 self.assertEqual(self.s - frozenset(self.otherword), i)
165 try:
166 self.s - self.otherword
167 except TypeError:
168 pass
169 else:
170 self.fail("s-t did not screen-out general iterables")
171
172 def test_symmetric_difference(self):
173 i = self.s.symmetric_difference(self.otherword)
174 for c in self.letters:
175 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000176 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000177 self.assertEqual(type(i), self.thetype)
178 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
179 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000180 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
181 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
182 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
183 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
184 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000185
186 def test_xor(self):
187 i = self.s.symmetric_difference(self.otherword)
188 self.assertEqual(self.s ^ set(self.otherword), i)
189 self.assertEqual(self.s ^ frozenset(self.otherword), i)
190 try:
191 self.s ^ self.otherword
192 except TypeError:
193 pass
194 else:
195 self.fail("s^t did not screen-out general iterables")
196
197 def test_equality(self):
198 self.assertEqual(self.s, set(self.word))
199 self.assertEqual(self.s, frozenset(self.word))
200 self.assertEqual(self.s == self.word, False)
201 self.assertNotEqual(self.s, set(self.otherword))
202 self.assertNotEqual(self.s, frozenset(self.otherword))
203 self.assertEqual(self.s != self.word, True)
204
205 def test_setOfFrozensets(self):
206 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
207 s = self.thetype(t)
208 self.assertEqual(len(s), 3)
209
210 def test_compare(self):
211 self.assertRaises(TypeError, self.s.__cmp__, self.s)
212
213 def test_sub_and_super(self):
214 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
215 self.assert_(p < q)
216 self.assert_(p <= q)
217 self.assert_(q <= q)
218 self.assert_(q > p)
219 self.assert_(q >= p)
220 self.failIf(q < r)
221 self.failIf(q <= r)
222 self.failIf(q > r)
223 self.failIf(q >= r)
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000224 self.assert_(set('a').issubset('abc'))
225 self.assert_(set('abc').issuperset('a'))
226 self.failIf(set('a').issubset('cbs'))
227 self.failIf(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000228
229 def test_pickling(self):
Benjamin Peterson828a7062008-12-27 17:05:29 +0000230 for i in range(pickle.HIGHEST_PROTOCOL + 1):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000231 p = pickle.dumps(self.s, i)
232 dup = pickle.loads(p)
233 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
234 if type(self.s) not in (set, frozenset):
235 self.s.x = 10
236 p = pickle.dumps(self.s)
237 dup = pickle.loads(p)
238 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000239
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000240 def test_deepcopy(self):
241 class Tracer:
242 def __init__(self, value):
243 self.value = value
244 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000245 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000246 def __deepcopy__(self, memo=None):
247 return Tracer(self.value + 1)
248 t = Tracer(10)
249 s = self.thetype([t])
250 dup = copy.deepcopy(s)
251 self.assertNotEqual(id(s), id(dup))
252 for elem in dup:
253 newt = elem
254 self.assertNotEqual(id(t), id(newt))
255 self.assertEqual(t.value + 1, newt.value)
256
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000257 def test_gc(self):
258 # Create a nest of cycles to exercise overall ref count check
259 class A:
260 pass
261 s = set(A() for i in xrange(1000))
262 for elem in s:
263 elem.cycle = s
264 elem.sub = elem
265 elem.set = set([elem])
266
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000267 def test_subclass_with_custom_hash(self):
268 # Bug #1257731
269 class H(self.thetype):
270 def __hash__(self):
Tim Peters6902b442006-04-11 00:43:27 +0000271 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000272 s=H()
273 f=set()
274 f.add(s)
275 self.assert_(s in f)
276 f.remove(s)
277 f.add(s)
278 f.discard(s)
279
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000280 def test_badcmp(self):
281 s = self.thetype([BadCmp()])
282 # Detect comparison errors during insertion and lookup
283 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
284 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
285 # Detect errors during mutating operations
286 if hasattr(s, 'add'):
287 self.assertRaises(RuntimeError, s.add, BadCmp())
288 self.assertRaises(RuntimeError, s.discard, BadCmp())
289 self.assertRaises(RuntimeError, s.remove, BadCmp())
290
Raymond Hettinger53999102006-12-30 04:01:17 +0000291 def test_cyclical_repr(self):
292 w = ReprWrapper()
293 s = self.thetype([w])
294 w.value = s
295 name = repr(s).partition('(')[0] # strip class name from repr string
296 self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
297
298 def test_cyclical_print(self):
299 w = ReprWrapper()
300 s = self.thetype([w])
301 w.value = s
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000302 fo = open(test_support.TESTFN, "wb")
Raymond Hettinger53999102006-12-30 04:01:17 +0000303 try:
Raymond Hettinger53999102006-12-30 04:01:17 +0000304 print >> fo, s,
305 fo.close()
306 fo = open(test_support.TESTFN, "rb")
307 self.assertEqual(fo.read(), repr(s))
308 finally:
309 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000310 test_support.unlink(test_support.TESTFN)
Raymond Hettinger53999102006-12-30 04:01:17 +0000311
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000312 def test_do_not_rehash_dict_keys(self):
313 n = 10
314 d = dict.fromkeys(map(HashCountingInt, xrange(n)))
315 self.assertEqual(sum(elem.hash_count for elem in d), n)
316 s = self.thetype(d)
317 self.assertEqual(sum(elem.hash_count for elem in d), n)
318 s.difference(d)
Tim Petersea5962f2007-03-12 18:07:52 +0000319 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000320 if hasattr(s, 'symmetric_difference_update'):
321 s.symmetric_difference_update(d)
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000322 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettinger0bbbfc42007-03-20 21:27:24 +0000323 d2 = dict.fromkeys(set(d))
324 self.assertEqual(sum(elem.hash_count for elem in d), n)
325 d3 = dict.fromkeys(frozenset(d))
Tim Petersea5962f2007-03-12 18:07:52 +0000326 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingere3146f52007-03-21 20:33:57 +0000327 d3 = dict.fromkeys(frozenset(d), 123)
328 self.assertEqual(sum(elem.hash_count for elem in d), n)
329 self.assertEqual(d3, dict.fromkeys(d, 123))
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000330
Georg Brandl47fe9812009-01-01 15:46:10 +0000331 def test_container_iterator(self):
Georg Brandl734373c2009-01-03 21:55:17 +0000332 # Bug #3680: tp_traverse was not implemented for set iterator object
Georg Brandl47fe9812009-01-01 15:46:10 +0000333 class C(object):
334 pass
335 obj = C()
336 ref = weakref.ref(obj)
337 container = set([obj, 1])
338 obj.x = iter(container)
339 del obj, container
340 gc.collect()
341 self.assert_(ref() is None, "Cycle was not collected")
342
Raymond Hettingera690a992003-11-16 16:17:49 +0000343class TestSet(TestJointOps):
344 thetype = set
345
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000346 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000347 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000348 s.__init__(self.word)
349 self.assertEqual(s, set(self.word))
350 s.__init__(self.otherword)
351 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000352 self.assertRaises(TypeError, s.__init__, s, 2);
353 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000354
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000355 def test_constructor_identity(self):
356 s = self.thetype(range(3))
357 t = self.thetype(s)
358 self.assertNotEqual(id(s), id(t))
359
Raymond Hettingera690a992003-11-16 16:17:49 +0000360 def test_hash(self):
361 self.assertRaises(TypeError, hash, self.s)
362
363 def test_clear(self):
364 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000365 self.assertEqual(self.s, set())
366 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000367
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000368 def test_copy(self):
369 dup = self.s.copy()
370 self.assertEqual(self.s, dup)
371 self.assertNotEqual(id(self.s), id(dup))
372
Raymond Hettingera690a992003-11-16 16:17:49 +0000373 def test_add(self):
374 self.s.add('Q')
375 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000376 dup = self.s.copy()
377 self.s.add('Q')
378 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000379 self.assertRaises(TypeError, self.s.add, [])
380
381 def test_remove(self):
382 self.s.remove('a')
383 self.assert_('a' not in self.s)
384 self.assertRaises(KeyError, self.s.remove, 'Q')
385 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000386 s = self.thetype([frozenset(self.word)])
387 self.assert_(self.thetype(self.word) in s)
388 s.remove(self.thetype(self.word))
389 self.assert_(self.thetype(self.word) not in s)
390 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000391
Raymond Hettingerc789f342006-12-08 17:35:25 +0000392 def test_remove_keyerror_unpacking(self):
393 # bug: www.python.org/sf/1576657
394 for v1 in ['Q', (1,)]:
395 try:
396 self.s.remove(v1)
397 except KeyError, e:
398 v2 = e.args[0]
399 self.assertEqual(v1, v2)
400 else:
401 self.fail()
402
Amaury Forgeot d'Arc00c94ed2008-10-07 20:40:09 +0000403 def test_remove_keyerror_set(self):
404 key = self.thetype([3, 4])
405 try:
406 self.s.remove(key)
407 except KeyError as e:
408 self.assert_(e.args[0] is key,
409 "KeyError should be {0}, not {1}".format(key,
410 e.args[0]))
411 else:
412 self.fail()
413
Raymond Hettingera690a992003-11-16 16:17:49 +0000414 def test_discard(self):
415 self.s.discard('a')
416 self.assert_('a' not in self.s)
417 self.s.discard('Q')
418 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000419 s = self.thetype([frozenset(self.word)])
420 self.assert_(self.thetype(self.word) in s)
421 s.discard(self.thetype(self.word))
422 self.assert_(self.thetype(self.word) not in s)
423 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000424
425 def test_pop(self):
426 for i in xrange(len(self.s)):
427 elem = self.s.pop()
428 self.assert_(elem not in self.s)
429 self.assertRaises(KeyError, self.s.pop)
430
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000431 def test_update(self):
432 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000433 self.assertEqual(retval, None)
434 for c in (self.word + self.otherword):
435 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000436 self.assertRaises(PassThru, self.s.update, check_pass_thru())
437 self.assertRaises(TypeError, self.s.update, [[]])
438 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
439 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
440 s = self.thetype('abcba')
441 self.assertEqual(s.update(C(p)), None)
442 self.assertEqual(s, set(q))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +0000443 for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
444 q = 'ahi'
445 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
446 s = self.thetype('abcba')
447 self.assertEqual(s.update(C(p), C(q)), None)
448 self.assertEqual(s, set(s) | set(p) | set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000449
450 def test_ior(self):
451 self.s |= set(self.otherword)
452 for c in (self.word + self.otherword):
453 self.assert_(c in self.s)
454
455 def test_intersection_update(self):
456 retval = self.s.intersection_update(self.otherword)
457 self.assertEqual(retval, None)
458 for c in (self.word + self.otherword):
459 if c in self.otherword and c in self.word:
460 self.assert_(c in self.s)
461 else:
462 self.assert_(c not in self.s)
463 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
464 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000465 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
466 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
467 s = self.thetype('abcba')
468 self.assertEqual(s.intersection_update(C(p)), None)
469 self.assertEqual(s, set(q))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000470 ss = 'abcba'
471 s = self.thetype(ss)
472 t = 'cbc'
473 self.assertEqual(s.intersection_update(C(p), C(t)), None)
474 self.assertEqual(s, set('abcba')&set(p)&set(t))
Raymond Hettingera690a992003-11-16 16:17:49 +0000475
476 def test_iand(self):
477 self.s &= set(self.otherword)
478 for c in (self.word + self.otherword):
479 if c in self.otherword and c in self.word:
480 self.assert_(c in self.s)
481 else:
482 self.assert_(c not in self.s)
483
484 def test_difference_update(self):
485 retval = self.s.difference_update(self.otherword)
486 self.assertEqual(retval, None)
487 for c in (self.word + self.otherword):
488 if c in self.word and c not in self.otherword:
489 self.assert_(c in self.s)
490 else:
491 self.assert_(c not in self.s)
492 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
493 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000494 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
495 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
496 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
497 s = self.thetype('abcba')
498 self.assertEqual(s.difference_update(C(p)), None)
499 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000500
Raymond Hettinger4267be62008-06-11 10:30:54 +0000501 s = self.thetype('abcdefghih')
502 s.difference_update()
503 self.assertEqual(s, self.thetype('abcdefghih'))
504
505 s = self.thetype('abcdefghih')
506 s.difference_update(C('aba'))
507 self.assertEqual(s, self.thetype('cdefghih'))
508
509 s = self.thetype('abcdefghih')
510 s.difference_update(C('cdc'), C('aba'))
511 self.assertEqual(s, self.thetype('efghih'))
512
Raymond Hettingera690a992003-11-16 16:17:49 +0000513 def test_isub(self):
514 self.s -= set(self.otherword)
515 for c in (self.word + self.otherword):
516 if c in self.word and c not in self.otherword:
517 self.assert_(c in self.s)
518 else:
519 self.assert_(c not in self.s)
520
521 def test_symmetric_difference_update(self):
522 retval = self.s.symmetric_difference_update(self.otherword)
523 self.assertEqual(retval, None)
524 for c in (self.word + self.otherword):
525 if (c in self.word) ^ (c in self.otherword):
526 self.assert_(c in self.s)
527 else:
528 self.assert_(c not in self.s)
529 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
530 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000531 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
532 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
533 s = self.thetype('abcba')
534 self.assertEqual(s.symmetric_difference_update(C(p)), None)
535 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000536
537 def test_ixor(self):
538 self.s ^= set(self.otherword)
539 for c in (self.word + self.otherword):
540 if (c in self.word) ^ (c in self.otherword):
541 self.assert_(c in self.s)
542 else:
543 self.assert_(c not in self.s)
544
Raymond Hettingerc991db22005-08-11 07:58:45 +0000545 def test_inplace_on_self(self):
546 t = self.s.copy()
547 t |= t
548 self.assertEqual(t, self.s)
549 t &= t
550 self.assertEqual(t, self.s)
551 t -= t
552 self.assertEqual(t, self.thetype())
553 t = self.s.copy()
554 t ^= t
555 self.assertEqual(t, self.thetype())
556
Raymond Hettinger691d8052004-05-30 07:26:47 +0000557 def test_weakref(self):
558 s = self.thetype('gallahad')
Georg Brandl47fe9812009-01-01 15:46:10 +0000559 p = weakref.proxy(s)
Raymond Hettinger691d8052004-05-30 07:26:47 +0000560 self.assertEqual(str(p), str(s))
561 s = None
562 self.assertRaises(ReferenceError, str, p)
563
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000564 # C API test only available in a debug build
Barry Warsaw176014f2006-03-30 22:45:35 +0000565 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000566 def test_c_api(self):
567 self.assertEqual(set('abc').test_c_api(), True)
568
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000569class SetSubclass(set):
570 pass
571
572class TestSetSubclass(TestSet):
573 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000574
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000575class SetSubclassWithKeywordArgs(set):
576 def __init__(self, iterable=[], newarg=None):
577 set.__init__(self, iterable)
578
579class TestSetSubclassWithKeywordArgs(TestSet):
Tim Petersf733abb2007-01-30 03:03:46 +0000580
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000581 def test_keywords_in_subclass(self):
582 'SF bug #1486663 -- this used to erroneously raise a TypeError'
583 SetSubclassWithKeywordArgs(newarg=1)
584
Raymond Hettingera690a992003-11-16 16:17:49 +0000585class TestFrozenSet(TestJointOps):
586 thetype = frozenset
587
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000588 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000589 s = self.thetype(self.word)
590 s.__init__(self.otherword)
591 self.assertEqual(s, set(self.word))
592
Raymond Hettingerd7946662005-08-01 21:39:29 +0000593 def test_singleton_empty_frozenset(self):
594 f = frozenset()
595 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
596 frozenset(), frozenset([]), frozenset(()), frozenset(''),
597 frozenset(xrange(0)), frozenset(frozenset()),
598 frozenset(f), f]
599 # All of the empty frozensets should have just one id()
600 self.assertEqual(len(set(map(id, efs))), 1)
601
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000602 def test_constructor_identity(self):
603 s = self.thetype(range(3))
604 t = self.thetype(s)
605 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000606
Raymond Hettingera690a992003-11-16 16:17:49 +0000607 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000608 self.assertEqual(hash(self.thetype('abcdeb')),
609 hash(self.thetype('ebecda')))
610
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000611 # make sure that all permutations give the same hash value
612 n = 100
613 seq = [randrange(n) for i in xrange(n)]
614 results = set()
615 for i in xrange(200):
616 shuffle(seq)
617 results.add(hash(self.thetype(seq)))
618 self.assertEqual(len(results), 1)
619
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000620 def test_copy(self):
621 dup = self.s.copy()
622 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000623
624 def test_frozen_as_dictkey(self):
625 seq = range(10) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000626 key1 = self.thetype(seq)
627 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000628 self.assertEqual(key1, key2)
629 self.assertNotEqual(id(key1), id(key2))
630 d = {}
631 d[key1] = 42
632 self.assertEqual(d[key2], 42)
633
634 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000635 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000636 self.assertEqual(hash(f), hash(f))
637
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000638 def test_hash_effectiveness(self):
639 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000640 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000641 addhashvalue = hashvalues.add
642 elemmasks = [(i+1, 1<<i) for i in range(n)]
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000643 for i in xrange(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000644 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
645 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000646
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000647class FrozenSetSubclass(frozenset):
648 pass
649
650class TestFrozenSetSubclass(TestFrozenSet):
651 thetype = FrozenSetSubclass
652
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000653 def test_constructor_identity(self):
654 s = self.thetype(range(3))
655 t = self.thetype(s)
656 self.assertNotEqual(id(s), id(t))
657
658 def test_copy(self):
659 dup = self.s.copy()
660 self.assertNotEqual(id(self.s), id(dup))
661
662 def test_nested_empty_constructor(self):
663 s = self.thetype()
664 t = self.thetype(s)
665 self.assertEqual(s, t)
666
Raymond Hettingerd7946662005-08-01 21:39:29 +0000667 def test_singleton_empty_frozenset(self):
668 Frozenset = self.thetype
669 f = frozenset()
670 F = Frozenset()
671 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
672 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
673 Frozenset(xrange(0)), Frozenset(Frozenset()),
674 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
675 # All empty frozenset subclass instances should have different ids
676 self.assertEqual(len(set(map(id, efs))), len(efs))
677
Raymond Hettingera690a992003-11-16 16:17:49 +0000678# Tests taken from test_sets.py =============================================
679
680empty_set = set()
681
682#==============================================================================
683
684class TestBasicOps(unittest.TestCase):
685
686 def test_repr(self):
687 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000688 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000689
Barry Warsaw1e13eb02012-02-20 20:42:21 -0500690 def check_repr_against_values(self):
691 text = repr(self.set)
692 self.assertTrue(text.startswith('{'))
693 self.assertTrue(text.endswith('}'))
694
695 result = text[1:-1].split(', ')
696 result.sort()
697 sorted_repr_values = [repr(value) for value in self.values]
698 sorted_repr_values.sort()
699 self.assertEqual(result, sorted_repr_values)
700
Raymond Hettingereae05de2004-07-09 04:51:24 +0000701 def test_print(self):
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000702 fo = open(test_support.TESTFN, "wb")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000703 try:
Raymond Hettingereae05de2004-07-09 04:51:24 +0000704 print >> fo, self.set,
705 fo.close()
706 fo = open(test_support.TESTFN, "rb")
707 self.assertEqual(fo.read(), repr(self.set))
708 finally:
709 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000710 test_support.unlink(test_support.TESTFN)
Raymond Hettingereae05de2004-07-09 04:51:24 +0000711
Raymond Hettingera690a992003-11-16 16:17:49 +0000712 def test_length(self):
713 self.assertEqual(len(self.set), self.length)
714
715 def test_self_equality(self):
716 self.assertEqual(self.set, self.set)
717
718 def test_equivalent_equality(self):
719 self.assertEqual(self.set, self.dup)
720
721 def test_copy(self):
722 self.assertEqual(self.set.copy(), self.dup)
723
724 def test_self_union(self):
725 result = self.set | self.set
726 self.assertEqual(result, self.dup)
727
728 def test_empty_union(self):
729 result = self.set | empty_set
730 self.assertEqual(result, self.dup)
731
732 def test_union_empty(self):
733 result = empty_set | self.set
734 self.assertEqual(result, self.dup)
735
736 def test_self_intersection(self):
737 result = self.set & self.set
738 self.assertEqual(result, self.dup)
739
740 def test_empty_intersection(self):
741 result = self.set & empty_set
742 self.assertEqual(result, empty_set)
743
744 def test_intersection_empty(self):
745 result = empty_set & self.set
746 self.assertEqual(result, empty_set)
747
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000748 def test_self_isdisjoint(self):
749 result = self.set.isdisjoint(self.set)
750 self.assertEqual(result, not self.set)
751
752 def test_empty_isdisjoint(self):
753 result = self.set.isdisjoint(empty_set)
754 self.assertEqual(result, True)
755
756 def test_isdisjoint_empty(self):
757 result = empty_set.isdisjoint(self.set)
758 self.assertEqual(result, True)
759
Raymond Hettingera690a992003-11-16 16:17:49 +0000760 def test_self_symmetric_difference(self):
761 result = self.set ^ self.set
762 self.assertEqual(result, empty_set)
763
Georg Brandld9ede202010-08-01 22:13:33 +0000764 def test_empty_symmetric_difference(self):
Raymond Hettingera690a992003-11-16 16:17:49 +0000765 result = self.set ^ empty_set
766 self.assertEqual(result, self.set)
767
768 def test_self_difference(self):
769 result = self.set - self.set
770 self.assertEqual(result, empty_set)
771
772 def test_empty_difference(self):
773 result = self.set - empty_set
774 self.assertEqual(result, self.dup)
775
776 def test_empty_difference_rev(self):
777 result = empty_set - self.set
778 self.assertEqual(result, empty_set)
779
780 def test_iteration(self):
781 for v in self.set:
782 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000783 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000784 # note: __length_hint__ is an internal undocumented API,
785 # don't rely on it in your own programs
786 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000787
788 def test_pickling(self):
789 p = pickle.dumps(self.set)
790 copy = pickle.loads(p)
791 self.assertEqual(self.set, copy,
792 "%s != %s" % (self.set, copy))
793
794#------------------------------------------------------------------------------
795
796class TestBasicOpsEmpty(TestBasicOps):
797 def setUp(self):
798 self.case = "empty set"
799 self.values = []
800 self.set = set(self.values)
801 self.dup = set(self.values)
802 self.length = 0
803 self.repr = "set([])"
804
805#------------------------------------------------------------------------------
806
807class TestBasicOpsSingleton(TestBasicOps):
808 def setUp(self):
809 self.case = "unit set (number)"
810 self.values = [3]
811 self.set = set(self.values)
812 self.dup = set(self.values)
813 self.length = 1
814 self.repr = "set([3])"
815
816 def test_in(self):
817 self.failUnless(3 in self.set)
818
819 def test_not_in(self):
820 self.failUnless(2 not in self.set)
821
822#------------------------------------------------------------------------------
823
824class TestBasicOpsTuple(TestBasicOps):
825 def setUp(self):
826 self.case = "unit set (tuple)"
827 self.values = [(0, "zero")]
828 self.set = set(self.values)
829 self.dup = set(self.values)
830 self.length = 1
831 self.repr = "set([(0, 'zero')])"
832
833 def test_in(self):
834 self.failUnless((0, "zero") in self.set)
835
836 def test_not_in(self):
837 self.failUnless(9 not in self.set)
838
839#------------------------------------------------------------------------------
840
841class TestBasicOpsTriple(TestBasicOps):
842 def setUp(self):
843 self.case = "triple set"
844 self.values = [0, "zero", operator.add]
845 self.set = set(self.values)
846 self.dup = set(self.values)
847 self.length = 3
848 self.repr = None
849
Barry Warsaw1e13eb02012-02-20 20:42:21 -0500850#------------------------------------------------------------------------------
851
852class TestBasicOpsString(TestBasicOps):
853 def setUp(self):
854 self.case = "string set"
855 self.values = ["a", "b", "c"]
856 self.set = set(self.values)
857 self.dup = set(self.values)
858 self.length = 3
859
860 def test_repr(self):
861 self.check_repr_against_values()
862
863#------------------------------------------------------------------------------
864
865class TestBasicOpsUnicode(TestBasicOps):
866 def setUp(self):
867 self.case = "unicode set"
868 self.values = [u"a", u"b", u"c"]
869 self.set = set(self.values)
870 self.dup = set(self.values)
871 self.length = 3
872
873 def test_repr(self):
874 self.check_repr_against_values()
875
876#------------------------------------------------------------------------------
877
878class TestBasicOpsMixedStringUnicode(TestBasicOps):
879 def setUp(self):
880 self.case = "string and bytes set"
881 self.values = ["a", "b", u"a", u"b"]
882 self.set = set(self.values)
883 self.dup = set(self.values)
884 self.length = 4
885
886 def test_repr(self):
887 with test_support.check_warnings():
888 self.check_repr_against_values()
889
Raymond Hettingera690a992003-11-16 16:17:49 +0000890#==============================================================================
891
892def baditer():
893 raise TypeError
894 yield True
895
896def gooditer():
897 yield True
898
899class TestExceptionPropagation(unittest.TestCase):
900 """SF 628246: Set constructor should not trap iterator TypeErrors"""
901
902 def test_instanceWithException(self):
903 self.assertRaises(TypeError, set, baditer())
904
905 def test_instancesWithoutException(self):
906 # All of these iterables should load without exception.
907 set([1,2,3])
908 set((1,2,3))
909 set({'one':1, 'two':2, 'three':3})
910 set(xrange(3))
911 set('abc')
912 set(gooditer())
913
Neal Norwitzfcf44352005-11-27 20:37:43 +0000914 def test_changingSizeWhileIterating(self):
915 s = set([1,2,3])
916 try:
917 for i in s:
918 s.update([4])
919 except RuntimeError:
920 pass
921 else:
922 self.fail("no exception when changing size during iteration")
923
Raymond Hettingera690a992003-11-16 16:17:49 +0000924#==============================================================================
925
926class TestSetOfSets(unittest.TestCase):
927 def test_constructor(self):
928 inner = frozenset([1])
929 outer = set([inner])
930 element = outer.pop()
931 self.assertEqual(type(element), frozenset)
932 outer.add(inner) # Rebuild set of sets with .add method
933 outer.remove(inner)
934 self.assertEqual(outer, set()) # Verify that remove worked
935 outer.discard(inner) # Absence of KeyError indicates working fine
936
937#==============================================================================
938
939class TestBinaryOps(unittest.TestCase):
940 def setUp(self):
941 self.set = set((2, 4, 6))
942
943 def test_eq(self): # SF bug 643115
944 self.assertEqual(self.set, set({2:1,4:3,6:5}))
945
946 def test_union_subset(self):
947 result = self.set | set([2])
948 self.assertEqual(result, set((2, 4, 6)))
949
950 def test_union_superset(self):
951 result = self.set | set([2, 4, 6, 8])
952 self.assertEqual(result, set([2, 4, 6, 8]))
953
954 def test_union_overlap(self):
955 result = self.set | set([3, 4, 5])
956 self.assertEqual(result, set([2, 3, 4, 5, 6]))
957
958 def test_union_non_overlap(self):
959 result = self.set | set([8])
960 self.assertEqual(result, set([2, 4, 6, 8]))
961
962 def test_intersection_subset(self):
963 result = self.set & set((2, 4))
964 self.assertEqual(result, set((2, 4)))
965
966 def test_intersection_superset(self):
967 result = self.set & set([2, 4, 6, 8])
968 self.assertEqual(result, set([2, 4, 6]))
969
970 def test_intersection_overlap(self):
971 result = self.set & set([3, 4, 5])
972 self.assertEqual(result, set([4]))
973
974 def test_intersection_non_overlap(self):
975 result = self.set & set([8])
976 self.assertEqual(result, empty_set)
977
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000978 def test_isdisjoint_subset(self):
979 result = self.set.isdisjoint(set((2, 4)))
980 self.assertEqual(result, False)
981
982 def test_isdisjoint_superset(self):
983 result = self.set.isdisjoint(set([2, 4, 6, 8]))
984 self.assertEqual(result, False)
985
986 def test_isdisjoint_overlap(self):
987 result = self.set.isdisjoint(set([3, 4, 5]))
988 self.assertEqual(result, False)
989
990 def test_isdisjoint_non_overlap(self):
991 result = self.set.isdisjoint(set([8]))
992 self.assertEqual(result, True)
993
Raymond Hettingera690a992003-11-16 16:17:49 +0000994 def test_sym_difference_subset(self):
995 result = self.set ^ set((2, 4))
996 self.assertEqual(result, set([6]))
997
998 def test_sym_difference_superset(self):
999 result = self.set ^ set((2, 4, 6, 8))
1000 self.assertEqual(result, set([8]))
1001
1002 def test_sym_difference_overlap(self):
1003 result = self.set ^ set((3, 4, 5))
1004 self.assertEqual(result, set([2, 3, 5, 6]))
1005
1006 def test_sym_difference_non_overlap(self):
1007 result = self.set ^ set([8])
1008 self.assertEqual(result, set([2, 4, 6, 8]))
1009
1010 def test_cmp(self):
1011 a, b = set('a'), set('b')
1012 self.assertRaises(TypeError, cmp, a, b)
1013
1014 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
1015 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
1016 # which Python thinks is good enough to synthesize a cmp() result
1017 # without calling __cmp__.
1018 self.assertEqual(cmp(a, a), 0)
1019
1020 self.assertRaises(TypeError, cmp, a, 12)
1021 self.assertRaises(TypeError, cmp, "abc", a)
1022
1023#==============================================================================
1024
1025class TestUpdateOps(unittest.TestCase):
1026 def setUp(self):
1027 self.set = set((2, 4, 6))
1028
1029 def test_union_subset(self):
1030 self.set |= set([2])
1031 self.assertEqual(self.set, set((2, 4, 6)))
1032
1033 def test_union_superset(self):
1034 self.set |= set([2, 4, 6, 8])
1035 self.assertEqual(self.set, set([2, 4, 6, 8]))
1036
1037 def test_union_overlap(self):
1038 self.set |= set([3, 4, 5])
1039 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1040
1041 def test_union_non_overlap(self):
1042 self.set |= set([8])
1043 self.assertEqual(self.set, set([2, 4, 6, 8]))
1044
1045 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001046 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +00001047 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1048
1049 def test_intersection_subset(self):
1050 self.set &= set((2, 4))
1051 self.assertEqual(self.set, set((2, 4)))
1052
1053 def test_intersection_superset(self):
1054 self.set &= set([2, 4, 6, 8])
1055 self.assertEqual(self.set, set([2, 4, 6]))
1056
1057 def test_intersection_overlap(self):
1058 self.set &= set([3, 4, 5])
1059 self.assertEqual(self.set, set([4]))
1060
1061 def test_intersection_non_overlap(self):
1062 self.set &= set([8])
1063 self.assertEqual(self.set, empty_set)
1064
1065 def test_intersection_method_call(self):
1066 self.set.intersection_update(set([3, 4, 5]))
1067 self.assertEqual(self.set, set([4]))
1068
1069 def test_sym_difference_subset(self):
1070 self.set ^= set((2, 4))
1071 self.assertEqual(self.set, set([6]))
1072
1073 def test_sym_difference_superset(self):
1074 self.set ^= set((2, 4, 6, 8))
1075 self.assertEqual(self.set, set([8]))
1076
1077 def test_sym_difference_overlap(self):
1078 self.set ^= set((3, 4, 5))
1079 self.assertEqual(self.set, set([2, 3, 5, 6]))
1080
1081 def test_sym_difference_non_overlap(self):
1082 self.set ^= set([8])
1083 self.assertEqual(self.set, set([2, 4, 6, 8]))
1084
1085 def test_sym_difference_method_call(self):
1086 self.set.symmetric_difference_update(set([3, 4, 5]))
1087 self.assertEqual(self.set, set([2, 3, 5, 6]))
1088
1089 def test_difference_subset(self):
1090 self.set -= set((2, 4))
1091 self.assertEqual(self.set, set([6]))
1092
1093 def test_difference_superset(self):
1094 self.set -= set((2, 4, 6, 8))
1095 self.assertEqual(self.set, set([]))
1096
1097 def test_difference_overlap(self):
1098 self.set -= set((3, 4, 5))
1099 self.assertEqual(self.set, set([2, 6]))
1100
1101 def test_difference_non_overlap(self):
1102 self.set -= set([8])
1103 self.assertEqual(self.set, set([2, 4, 6]))
1104
1105 def test_difference_method_call(self):
1106 self.set.difference_update(set([3, 4, 5]))
1107 self.assertEqual(self.set, set([2, 6]))
1108
1109#==============================================================================
1110
1111class TestMutate(unittest.TestCase):
1112 def setUp(self):
1113 self.values = ["a", "b", "c"]
1114 self.set = set(self.values)
1115
1116 def test_add_present(self):
1117 self.set.add("c")
1118 self.assertEqual(self.set, set("abc"))
1119
1120 def test_add_absent(self):
1121 self.set.add("d")
1122 self.assertEqual(self.set, set("abcd"))
1123
1124 def test_add_until_full(self):
1125 tmp = set()
1126 expected_len = 0
1127 for v in self.values:
1128 tmp.add(v)
1129 expected_len += 1
1130 self.assertEqual(len(tmp), expected_len)
1131 self.assertEqual(tmp, self.set)
1132
1133 def test_remove_present(self):
1134 self.set.remove("b")
1135 self.assertEqual(self.set, set("ac"))
1136
1137 def test_remove_absent(self):
1138 try:
1139 self.set.remove("d")
1140 self.fail("Removing missing element should have raised LookupError")
1141 except LookupError:
1142 pass
1143
1144 def test_remove_until_empty(self):
1145 expected_len = len(self.set)
1146 for v in self.values:
1147 self.set.remove(v)
1148 expected_len -= 1
1149 self.assertEqual(len(self.set), expected_len)
1150
1151 def test_discard_present(self):
1152 self.set.discard("c")
1153 self.assertEqual(self.set, set("ab"))
1154
1155 def test_discard_absent(self):
1156 self.set.discard("d")
1157 self.assertEqual(self.set, set("abc"))
1158
1159 def test_clear(self):
1160 self.set.clear()
1161 self.assertEqual(len(self.set), 0)
1162
1163 def test_pop(self):
1164 popped = {}
1165 while self.set:
1166 popped[self.set.pop()] = None
1167 self.assertEqual(len(popped), len(self.values))
1168 for v in self.values:
1169 self.failUnless(v in popped)
1170
1171 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001172 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001173 self.assertEqual(self.set, set(self.values))
1174
1175 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001176 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001177 self.assertEqual(self.set, set(self.values))
1178
1179 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001180 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001181 self.assertEqual(self.set, set(self.values + ["z"]))
1182
1183#==============================================================================
1184
1185class TestSubsets(unittest.TestCase):
1186
1187 case2method = {"<=": "issubset",
1188 ">=": "issuperset",
1189 }
1190
1191 reverse = {"==": "==",
1192 "!=": "!=",
1193 "<": ">",
1194 ">": "<",
1195 "<=": ">=",
1196 ">=": "<=",
1197 }
1198
1199 def test_issubset(self):
1200 x = self.left
1201 y = self.right
1202 for case in "!=", "==", "<", "<=", ">", ">=":
1203 expected = case in self.cases
1204 # Test the binary infix spelling.
1205 result = eval("x" + case + "y", locals())
1206 self.assertEqual(result, expected)
1207 # Test the "friendly" method-name spelling, if one exists.
1208 if case in TestSubsets.case2method:
1209 method = getattr(x, TestSubsets.case2method[case])
1210 result = method(y)
1211 self.assertEqual(result, expected)
1212
1213 # Now do the same for the operands reversed.
1214 rcase = TestSubsets.reverse[case]
1215 result = eval("y" + rcase + "x", locals())
1216 self.assertEqual(result, expected)
1217 if rcase in TestSubsets.case2method:
1218 method = getattr(y, TestSubsets.case2method[rcase])
1219 result = method(x)
1220 self.assertEqual(result, expected)
1221#------------------------------------------------------------------------------
1222
1223class TestSubsetEqualEmpty(TestSubsets):
1224 left = set()
1225 right = set()
1226 name = "both empty"
1227 cases = "==", "<=", ">="
1228
1229#------------------------------------------------------------------------------
1230
1231class TestSubsetEqualNonEmpty(TestSubsets):
1232 left = set([1, 2])
1233 right = set([1, 2])
1234 name = "equal pair"
1235 cases = "==", "<=", ">="
1236
1237#------------------------------------------------------------------------------
1238
1239class TestSubsetEmptyNonEmpty(TestSubsets):
1240 left = set()
1241 right = set([1, 2])
1242 name = "one empty, one non-empty"
1243 cases = "!=", "<", "<="
1244
1245#------------------------------------------------------------------------------
1246
1247class TestSubsetPartial(TestSubsets):
1248 left = set([1])
1249 right = set([1, 2])
1250 name = "one a non-empty proper subset of other"
1251 cases = "!=", "<", "<="
1252
1253#------------------------------------------------------------------------------
1254
1255class TestSubsetNonOverlap(TestSubsets):
1256 left = set([1])
1257 right = set([2])
1258 name = "neither empty, neither contains"
1259 cases = "!="
1260
1261#==============================================================================
1262
1263class TestOnlySetsInBinaryOps(unittest.TestCase):
1264
1265 def test_eq_ne(self):
1266 # Unlike the others, this is testing that == and != *are* allowed.
1267 self.assertEqual(self.other == self.set, False)
1268 self.assertEqual(self.set == self.other, False)
1269 self.assertEqual(self.other != self.set, True)
1270 self.assertEqual(self.set != self.other, True)
1271
1272 def test_ge_gt_le_lt(self):
1273 self.assertRaises(TypeError, lambda: self.set < self.other)
1274 self.assertRaises(TypeError, lambda: self.set <= self.other)
1275 self.assertRaises(TypeError, lambda: self.set > self.other)
1276 self.assertRaises(TypeError, lambda: self.set >= self.other)
1277
1278 self.assertRaises(TypeError, lambda: self.other < self.set)
1279 self.assertRaises(TypeError, lambda: self.other <= self.set)
1280 self.assertRaises(TypeError, lambda: self.other > self.set)
1281 self.assertRaises(TypeError, lambda: self.other >= self.set)
1282
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001283 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001284 try:
1285 self.set |= self.other
1286 except TypeError:
1287 pass
1288 else:
1289 self.fail("expected TypeError")
1290
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001291 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001292 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001293 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001294 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001295 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001296
1297 def test_union(self):
1298 self.assertRaises(TypeError, lambda: self.set | self.other)
1299 self.assertRaises(TypeError, lambda: self.other | self.set)
1300 if self.otherIsIterable:
1301 self.set.union(self.other)
1302 else:
1303 self.assertRaises(TypeError, self.set.union, self.other)
1304
1305 def test_intersection_update_operator(self):
1306 try:
1307 self.set &= self.other
1308 except TypeError:
1309 pass
1310 else:
1311 self.fail("expected TypeError")
1312
1313 def test_intersection_update(self):
1314 if self.otherIsIterable:
1315 self.set.intersection_update(self.other)
1316 else:
1317 self.assertRaises(TypeError,
1318 self.set.intersection_update,
1319 self.other)
1320
1321 def test_intersection(self):
1322 self.assertRaises(TypeError, lambda: self.set & self.other)
1323 self.assertRaises(TypeError, lambda: self.other & self.set)
1324 if self.otherIsIterable:
1325 self.set.intersection(self.other)
1326 else:
1327 self.assertRaises(TypeError, self.set.intersection, self.other)
1328
1329 def test_sym_difference_update_operator(self):
1330 try:
1331 self.set ^= self.other
1332 except TypeError:
1333 pass
1334 else:
1335 self.fail("expected TypeError")
1336
1337 def test_sym_difference_update(self):
1338 if self.otherIsIterable:
1339 self.set.symmetric_difference_update(self.other)
1340 else:
1341 self.assertRaises(TypeError,
1342 self.set.symmetric_difference_update,
1343 self.other)
1344
1345 def test_sym_difference(self):
1346 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1347 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1348 if self.otherIsIterable:
1349 self.set.symmetric_difference(self.other)
1350 else:
1351 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1352
1353 def test_difference_update_operator(self):
1354 try:
1355 self.set -= self.other
1356 except TypeError:
1357 pass
1358 else:
1359 self.fail("expected TypeError")
1360
1361 def test_difference_update(self):
1362 if self.otherIsIterable:
1363 self.set.difference_update(self.other)
1364 else:
1365 self.assertRaises(TypeError,
1366 self.set.difference_update,
1367 self.other)
1368
1369 def test_difference(self):
1370 self.assertRaises(TypeError, lambda: self.set - self.other)
1371 self.assertRaises(TypeError, lambda: self.other - self.set)
1372 if self.otherIsIterable:
1373 self.set.difference(self.other)
1374 else:
1375 self.assertRaises(TypeError, self.set.difference, self.other)
1376
1377#------------------------------------------------------------------------------
1378
1379class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1380 def setUp(self):
1381 self.set = set((1, 2, 3))
1382 self.other = 19
1383 self.otherIsIterable = False
1384
1385#------------------------------------------------------------------------------
1386
1387class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1388 def setUp(self):
1389 self.set = set((1, 2, 3))
1390 self.other = {1:2, 3:4}
1391 self.otherIsIterable = True
1392
1393#------------------------------------------------------------------------------
1394
1395class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1396 def setUp(self):
1397 self.set = set((1, 2, 3))
1398 self.other = operator.add
1399 self.otherIsIterable = False
1400
Ezio Melottia65e2af2010-08-02 19:56:05 +00001401 def test_ge_gt_le_lt(self):
1402 with test_support._check_py3k_warnings():
1403 super(TestOnlySetsOperator, self).test_ge_gt_le_lt()
1404
Raymond Hettingera690a992003-11-16 16:17:49 +00001405#------------------------------------------------------------------------------
1406
1407class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1408 def setUp(self):
1409 self.set = set((1, 2, 3))
1410 self.other = (2, 4, 6)
1411 self.otherIsIterable = True
1412
1413#------------------------------------------------------------------------------
1414
1415class TestOnlySetsString(TestOnlySetsInBinaryOps):
1416 def setUp(self):
1417 self.set = set((1, 2, 3))
1418 self.other = 'abc'
1419 self.otherIsIterable = True
1420
1421#------------------------------------------------------------------------------
1422
1423class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1424 def setUp(self):
1425 def gen():
1426 for i in xrange(0, 10, 2):
1427 yield i
1428 self.set = set((1, 2, 3))
1429 self.other = gen()
1430 self.otherIsIterable = True
1431
1432#==============================================================================
1433
1434class TestCopying(unittest.TestCase):
1435
1436 def test_copy(self):
1437 dup = self.set.copy()
Ezio Melotti5c752352010-08-03 08:41:02 +00001438 with test_support.check_warnings():
1439 dup_list = sorted(dup)
1440 set_list = sorted(self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +00001441 self.assertEqual(len(dup_list), len(set_list))
1442 for i in range(len(dup_list)):
1443 self.failUnless(dup_list[i] is set_list[i])
1444
1445 def test_deep_copy(self):
1446 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001447 ##print type(dup), repr(dup)
Ezio Melotti5c752352010-08-03 08:41:02 +00001448 with test_support.check_warnings():
1449 dup_list = sorted(dup)
1450 set_list = sorted(self.set)
Raymond Hettingera690a992003-11-16 16:17:49 +00001451 self.assertEqual(len(dup_list), len(set_list))
1452 for i in range(len(dup_list)):
1453 self.assertEqual(dup_list[i], set_list[i])
1454
1455#------------------------------------------------------------------------------
1456
1457class TestCopyingEmpty(TestCopying):
1458 def setUp(self):
1459 self.set = set()
1460
1461#------------------------------------------------------------------------------
1462
1463class TestCopyingSingleton(TestCopying):
1464 def setUp(self):
1465 self.set = set(["hello"])
1466
1467#------------------------------------------------------------------------------
1468
1469class TestCopyingTriple(TestCopying):
1470 def setUp(self):
1471 self.set = set(["zero", 0, None])
1472
1473#------------------------------------------------------------------------------
1474
1475class TestCopyingTuple(TestCopying):
1476 def setUp(self):
1477 self.set = set([(1, 2)])
1478
1479#------------------------------------------------------------------------------
1480
1481class TestCopyingNested(TestCopying):
1482 def setUp(self):
1483 self.set = set([((1, 2), (3, 4))])
1484
1485#==============================================================================
1486
1487class TestIdentities(unittest.TestCase):
1488 def setUp(self):
1489 self.a = set('abracadabra')
1490 self.b = set('alacazam')
1491
1492 def test_binopsVsSubsets(self):
1493 a, b = self.a, self.b
1494 self.assert_(a - b < a)
1495 self.assert_(b - a < b)
1496 self.assert_(a & b < a)
1497 self.assert_(a & b < b)
1498 self.assert_(a | b > a)
1499 self.assert_(a | b > b)
1500 self.assert_(a ^ b < a | b)
1501
1502 def test_commutativity(self):
1503 a, b = self.a, self.b
1504 self.assertEqual(a&b, b&a)
1505 self.assertEqual(a|b, b|a)
1506 self.assertEqual(a^b, b^a)
1507 if a != b:
1508 self.assertNotEqual(a-b, b-a)
1509
1510 def test_summations(self):
1511 # check that sums of parts equal the whole
1512 a, b = self.a, self.b
1513 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1514 self.assertEqual((a&b)|(a^b), a|b)
1515 self.assertEqual(a|(b-a), a|b)
1516 self.assertEqual((a-b)|b, a|b)
1517 self.assertEqual((a-b)|(a&b), a)
1518 self.assertEqual((b-a)|(a&b), b)
1519 self.assertEqual((a-b)|(b-a), a^b)
1520
1521 def test_exclusion(self):
1522 # check that inverse operations show non-overlap
1523 a, b, zero = self.a, self.b, set()
1524 self.assertEqual((a-b)&b, zero)
1525 self.assertEqual((b-a)&a, zero)
1526 self.assertEqual((a&b)&(a^b), zero)
1527
1528# Tests derived from test_itertools.py =======================================
1529
1530def R(seqn):
1531 'Regular generator'
1532 for i in seqn:
1533 yield i
1534
1535class G:
1536 'Sequence using __getitem__'
1537 def __init__(self, seqn):
1538 self.seqn = seqn
1539 def __getitem__(self, i):
1540 return self.seqn[i]
1541
1542class I:
1543 'Sequence using iterator protocol'
1544 def __init__(self, seqn):
1545 self.seqn = seqn
1546 self.i = 0
1547 def __iter__(self):
1548 return self
1549 def next(self):
1550 if self.i >= len(self.seqn): raise StopIteration
1551 v = self.seqn[self.i]
1552 self.i += 1
1553 return v
1554
1555class Ig:
1556 'Sequence using iterator protocol defined with a generator'
1557 def __init__(self, seqn):
1558 self.seqn = seqn
1559 self.i = 0
1560 def __iter__(self):
1561 for val in self.seqn:
1562 yield val
1563
1564class X:
1565 'Missing __getitem__ and __iter__'
1566 def __init__(self, seqn):
1567 self.seqn = seqn
1568 self.i = 0
1569 def next(self):
1570 if self.i >= len(self.seqn): raise StopIteration
1571 v = self.seqn[self.i]
1572 self.i += 1
1573 return v
1574
1575class N:
1576 'Iterator missing next()'
1577 def __init__(self, seqn):
1578 self.seqn = seqn
1579 self.i = 0
1580 def __iter__(self):
1581 return self
1582
1583class E:
1584 'Test propagation of exceptions'
1585 def __init__(self, seqn):
1586 self.seqn = seqn
1587 self.i = 0
1588 def __iter__(self):
1589 return self
1590 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001591 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001592
1593class S:
1594 'Test immediate stop'
1595 def __init__(self, seqn):
1596 pass
1597 def __iter__(self):
1598 return self
1599 def next(self):
1600 raise StopIteration
1601
1602from itertools import chain, imap
1603def L(seqn):
1604 'Test multiple tiers of iterators'
1605 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1606
1607class TestVariousIteratorArgs(unittest.TestCase):
1608
1609 def test_constructor(self):
1610 for cons in (set, frozenset):
1611 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
Ezio Melotti5c752352010-08-03 08:41:02 +00001612 with test_support.check_warnings():
1613 for g in (G, I, Ig, S, L, R):
1614 self.assertEqual(sorted(cons(g(s))), sorted(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001615 self.assertRaises(TypeError, cons , X(s))
1616 self.assertRaises(TypeError, cons , N(s))
1617 self.assertRaises(ZeroDivisionError, cons , E(s))
1618
1619 def test_inline_methods(self):
1620 s = set('november')
1621 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001622 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001623 for g in (G, I, Ig, L, R):
1624 expected = meth(data)
1625 actual = meth(G(data))
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001626 if isinstance(expected, bool):
1627 self.assertEqual(actual, expected)
1628 else:
Ezio Melotti5c752352010-08-03 08:41:02 +00001629 with test_support.check_warnings():
1630 self.assertEqual(sorted(actual), sorted(expected))
Raymond Hettingera690a992003-11-16 16:17:49 +00001631 self.assertRaises(TypeError, meth, X(s))
1632 self.assertRaises(TypeError, meth, N(s))
1633 self.assertRaises(ZeroDivisionError, meth, E(s))
1634
1635 def test_inplace_methods(self):
1636 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001637 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001638 'difference_update', 'symmetric_difference_update'):
1639 for g in (G, I, Ig, S, L, R):
1640 s = set('january')
1641 t = s.copy()
1642 getattr(s, methname)(list(g(data)))
1643 getattr(t, methname)(g(data))
Ezio Melotti5c752352010-08-03 08:41:02 +00001644 with test_support.check_warnings():
1645 self.assertEqual(sorted(s), sorted(t))
Raymond Hettingera690a992003-11-16 16:17:49 +00001646
1647 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1648 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1649 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1650
Raymond Hettinger61708742008-01-24 21:23:58 +00001651# Application tests (based on David Eppstein's graph recipes ====================================
1652
1653def powerset(U):
1654 """Generates all subsets of a set or sequence U."""
1655 U = iter(U)
1656 try:
1657 x = frozenset([U.next()])
1658 for S in powerset(U):
1659 yield S
1660 yield S | x
1661 except StopIteration:
1662 yield frozenset()
1663
1664def cube(n):
1665 """Graph of n-dimensional hypercube."""
1666 singletons = [frozenset([x]) for x in range(n)]
1667 return dict([(x, frozenset([x^s for s in singletons]))
1668 for x in powerset(range(n))])
1669
1670def linegraph(G):
1671 """Graph, the vertices of which are edges of G,
1672 with two vertices being adjacent iff the corresponding
1673 edges share a vertex."""
1674 L = {}
1675 for x in G:
1676 for y in G[x]:
1677 nx = [frozenset([x,z]) for z in G[x] if z != y]
1678 ny = [frozenset([y,z]) for z in G[y] if z != x]
1679 L[frozenset([x,y])] = frozenset(nx+ny)
1680 return L
1681
1682def faces(G):
1683 'Return a set of faces in G. Where a face is a set of vertices on that face'
1684 # currently limited to triangles,squares, and pentagons
1685 f = set()
1686 for v1, edges in G.items():
1687 for v2 in edges:
1688 for v3 in G[v2]:
1689 if v1 == v3:
1690 continue
1691 if v1 in G[v3]:
1692 f.add(frozenset([v1, v2, v3]))
1693 else:
1694 for v4 in G[v3]:
1695 if v4 == v2:
1696 continue
1697 if v1 in G[v4]:
1698 f.add(frozenset([v1, v2, v3, v4]))
1699 else:
1700 for v5 in G[v4]:
1701 if v5 == v3 or v5 == v2:
1702 continue
1703 if v1 in G[v5]:
1704 f.add(frozenset([v1, v2, v3, v4, v5]))
1705 return f
1706
1707
1708class TestGraphs(unittest.TestCase):
1709
1710 def test_cube(self):
1711
1712 g = cube(3) # vert --> {v1, v2, v3}
1713 vertices1 = set(g)
1714 self.assertEqual(len(vertices1), 8) # eight vertices
1715 for edge in g.values():
1716 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1717 vertices2 = set(v for edges in g.values() for v in edges)
1718 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1719
1720 cubefaces = faces(g)
1721 self.assertEqual(len(cubefaces), 6) # six faces
1722 for face in cubefaces:
1723 self.assertEqual(len(face), 4) # each face is a square
1724
1725 def test_cuboctahedron(self):
1726
1727 # http://en.wikipedia.org/wiki/Cuboctahedron
1728 # 8 triangular faces and 6 square faces
1729 # 12 indentical vertices each connecting a triangle and square
1730
1731 g = cube(3)
1732 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1733 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1734
1735 vertices = set(cuboctahedron)
1736 for edges in cuboctahedron.values():
1737 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1738 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1739 self.assertEqual(vertices, othervertices) # edge vertices in original set
1740
1741 cubofaces = faces(cuboctahedron)
1742 facesizes = collections.defaultdict(int)
1743 for face in cubofaces:
1744 facesizes[len(face)] += 1
1745 self.assertEqual(facesizes[3], 8) # eight triangular faces
1746 self.assertEqual(facesizes[4], 6) # six square faces
1747
1748 for vertex in cuboctahedron:
1749 edge = vertex # Cuboctahedron vertices are edges in Cube
1750 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1751 for cubevert in edge:
1752 self.assert_(cubevert in g)
1753
1754
Raymond Hettingera690a992003-11-16 16:17:49 +00001755#==============================================================================
1756
1757def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001758 from test import test_sets
1759 test_classes = (
1760 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001761 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001762 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001763 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001764 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001765 TestSetOfSets,
1766 TestExceptionPropagation,
1767 TestBasicOpsEmpty,
1768 TestBasicOpsSingleton,
1769 TestBasicOpsTuple,
1770 TestBasicOpsTriple,
1771 TestBinaryOps,
1772 TestUpdateOps,
1773 TestMutate,
1774 TestSubsetEqualEmpty,
1775 TestSubsetEqualNonEmpty,
1776 TestSubsetEmptyNonEmpty,
1777 TestSubsetPartial,
1778 TestSubsetNonOverlap,
1779 TestOnlySetsNumeric,
1780 TestOnlySetsDict,
1781 TestOnlySetsOperator,
1782 TestOnlySetsTuple,
1783 TestOnlySetsString,
1784 TestOnlySetsGenerator,
1785 TestCopyingEmpty,
1786 TestCopyingSingleton,
1787 TestCopyingTriple,
1788 TestCopyingTuple,
1789 TestCopyingNested,
1790 TestIdentities,
1791 TestVariousIteratorArgs,
Raymond Hettinger61708742008-01-24 21:23:58 +00001792 TestGraphs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001793 )
1794
1795 test_support.run_unittest(*test_classes)
1796
1797 # verify reference counting
1798 if verbose and hasattr(sys, "gettotalrefcount"):
1799 import gc
1800 counts = [None] * 5
1801 for i in xrange(len(counts)):
1802 test_support.run_unittest(*test_classes)
1803 gc.collect()
1804 counts[i] = sys.gettotalrefcount()
1805 print counts
1806
1807if __name__ == "__main__":
1808 test_main(verbose=True)