blob: d05df3f24dec382fa0ea3c58c1d1cf6c3694d764 [file] [log] [blame]
Raymond Hettingera690a992003-11-16 16:17:49 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Raymond Hettinger691d8052004-05-30 07:26:47 +00003from weakref import proxy
Raymond Hettingera690a992003-11-16 16:17:49 +00004import operator
5import copy
6import pickle
Raymond Hettingereae05de2004-07-09 04:51:24 +00007import os
Raymond Hettinger82cb9a22005-07-05 05:34:43 +00008from random import randrange, shuffle
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00009import sys
Christian Heimes0ded5b52007-12-10 15:50:56 +000010import warnings
Christian Heimes969fe572008-01-25 11:23:10 +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
Guido van Rossum47b9ff62006-08-24 00:41:19 +000023 def __eq__(self, other):
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000024 raise RuntimeError
25
Thomas Wouters902d6eb2007-01-09 23:18:33 +000026class ReprWrapper:
27 'Used to test self-referential repr() calls'
28 def __repr__(self):
29 return repr(self.value)
30
Thomas Wouterscf297e42007-02-23 15:07:44 +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)
51
Raymond Hettingera690a992003-11-16 16:17:49 +000052 def test_uniquification(self):
Raymond Hettinger64958a12003-12-17 20:43:33 +000053 actual = sorted(self.s)
54 expected = sorted(self.d)
Raymond Hettingera690a992003-11-16 16:17:49 +000055 self.assertEqual(actual, expected)
56 self.assertRaises(PassThru, self.thetype, check_pass_thru())
57 self.assertRaises(TypeError, self.thetype, [[]])
58
59 def test_len(self):
60 self.assertEqual(len(self.s), len(self.d))
61
62 def test_contains(self):
63 for c in self.letters:
64 self.assertEqual(c in self.s, c in self.d)
65 self.assertRaises(TypeError, self.s.__contains__, [[]])
Raymond Hettinger19c2d772003-11-21 18:36:54 +000066 s = self.thetype([frozenset(self.letters)])
67 self.assert_(self.thetype(self.letters) in s)
Raymond Hettingera690a992003-11-16 16:17:49 +000068
Raymond Hettingera690a992003-11-16 16:17:49 +000069 def test_union(self):
70 u = self.s.union(self.otherword)
71 for c in self.letters:
72 self.assertEqual(c in u, c in self.d or c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000073 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000074 self.assertEqual(type(u), self.thetype)
75 self.assertRaises(PassThru, self.s.union, check_pass_thru())
76 self.assertRaises(TypeError, self.s.union, [[]])
Guido van Rossum75a902d2007-10-19 22:06:24 +000077 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000078 self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
79 self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
80 self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
81 self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +000082
83 def test_or(self):
84 i = self.s.union(self.otherword)
85 self.assertEqual(self.s | set(self.otherword), i)
86 self.assertEqual(self.s | frozenset(self.otherword), i)
87 try:
88 self.s | self.otherword
89 except TypeError:
90 pass
91 else:
92 self.fail("s|t did not screen-out general iterables")
93
94 def test_intersection(self):
95 i = self.s.intersection(self.otherword)
96 for c in self.letters:
97 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000098 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000099 self.assertEqual(type(i), self.thetype)
100 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Guido van Rossum75a902d2007-10-19 22:06:24 +0000101 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000102 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
103 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
104 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
105 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Raymond Hettingera690a992003-11-16 16:17:49 +0000106
Guido van Rossum58da9312007-11-10 23:39:45 +0000107 def test_isdisjoint(self):
108 def f(s1, s2):
109 'Pure python equivalent of isdisjoint()'
110 return not set(s1).intersection(s2)
111 for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
112 s1 = self.thetype(larg)
113 for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
114 for C in set, frozenset, dict.fromkeys, str, list, tuple:
115 s2 = C(rarg)
116 actual = s1.isdisjoint(s2)
117 expected = f(s1, s2)
118 self.assertEqual(actual, expected)
119 self.assert_(actual is True or actual is False)
120
Raymond Hettingera690a992003-11-16 16:17:49 +0000121 def test_and(self):
122 i = self.s.intersection(self.otherword)
123 self.assertEqual(self.s & set(self.otherword), i)
124 self.assertEqual(self.s & frozenset(self.otherword), i)
125 try:
126 self.s & self.otherword
127 except TypeError:
128 pass
129 else:
130 self.fail("s&t did not screen-out general iterables")
131
132 def test_difference(self):
133 i = self.s.difference(self.otherword)
134 for c in self.letters:
135 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000136 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000137 self.assertEqual(type(i), self.thetype)
138 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
139 self.assertRaises(TypeError, self.s.difference, [[]])
Guido van Rossum75a902d2007-10-19 22:06:24 +0000140 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000141 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
142 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
143 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
144 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000145
146 def test_sub(self):
147 i = self.s.difference(self.otherword)
148 self.assertEqual(self.s - set(self.otherword), i)
149 self.assertEqual(self.s - frozenset(self.otherword), i)
150 try:
151 self.s - self.otherword
152 except TypeError:
153 pass
154 else:
155 self.fail("s-t did not screen-out general iterables")
156
157 def test_symmetric_difference(self):
158 i = self.s.symmetric_difference(self.otherword)
159 for c in self.letters:
160 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000161 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000162 self.assertEqual(type(i), self.thetype)
163 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
164 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Guido van Rossum75a902d2007-10-19 22:06:24 +0000165 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000166 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
167 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
168 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
169 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000170
171 def test_xor(self):
172 i = self.s.symmetric_difference(self.otherword)
173 self.assertEqual(self.s ^ set(self.otherword), i)
174 self.assertEqual(self.s ^ frozenset(self.otherword), i)
175 try:
176 self.s ^ self.otherword
177 except TypeError:
178 pass
179 else:
180 self.fail("s^t did not screen-out general iterables")
181
182 def test_equality(self):
183 self.assertEqual(self.s, set(self.word))
184 self.assertEqual(self.s, frozenset(self.word))
185 self.assertEqual(self.s == self.word, False)
186 self.assertNotEqual(self.s, set(self.otherword))
187 self.assertNotEqual(self.s, frozenset(self.otherword))
188 self.assertEqual(self.s != self.word, True)
189
190 def test_setOfFrozensets(self):
191 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
192 s = self.thetype(t)
193 self.assertEqual(len(s), 3)
194
195 def test_compare(self):
196 self.assertRaises(TypeError, self.s.__cmp__, self.s)
197
198 def test_sub_and_super(self):
199 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
200 self.assert_(p < q)
201 self.assert_(p <= q)
202 self.assert_(q <= q)
203 self.assert_(q > p)
204 self.assert_(q >= p)
205 self.failIf(q < r)
206 self.failIf(q <= r)
207 self.failIf(q > r)
208 self.failIf(q >= r)
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000209 self.assert_(set('a').issubset('abc'))
210 self.assert_(set('abc').issuperset('a'))
211 self.failIf(set('a').issubset('cbs'))
212 self.failIf(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000213
214 def test_pickling(self):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000215 for i in (0, 1, 2):
216 p = pickle.dumps(self.s, i)
217 dup = pickle.loads(p)
218 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
219 if type(self.s) not in (set, frozenset):
220 self.s.x = 10
221 p = pickle.dumps(self.s)
222 dup = pickle.loads(p)
223 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000224
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000225 def test_deepcopy(self):
226 class Tracer:
227 def __init__(self, value):
228 self.value = value
229 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000230 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000231 def __deepcopy__(self, memo=None):
232 return Tracer(self.value + 1)
233 t = Tracer(10)
234 s = self.thetype([t])
235 dup = copy.deepcopy(s)
236 self.assertNotEqual(id(s), id(dup))
237 for elem in dup:
238 newt = elem
239 self.assertNotEqual(id(t), id(newt))
240 self.assertEqual(t.value + 1, newt.value)
241
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000242 def test_gc(self):
243 # Create a nest of cycles to exercise overall ref count check
244 class A:
245 pass
Guido van Rossum805365e2007-05-07 22:24:25 +0000246 s = set(A() for i in range(1000))
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000247 for elem in s:
248 elem.cycle = s
249 elem.sub = elem
250 elem.set = set([elem])
251
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000252 def test_subclass_with_custom_hash(self):
253 # Bug #1257731
254 class H(self.thetype):
255 def __hash__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000257 s=H()
258 f=set()
259 f.add(s)
260 self.assert_(s in f)
261 f.remove(s)
262 f.add(s)
263 f.discard(s)
264
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000265 def test_badcmp(self):
266 s = self.thetype([BadCmp()])
267 # Detect comparison errors during insertion and lookup
268 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
269 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
270 # Detect errors during mutating operations
271 if hasattr(s, 'add'):
272 self.assertRaises(RuntimeError, s.add, BadCmp())
273 self.assertRaises(RuntimeError, s.discard, BadCmp())
274 self.assertRaises(RuntimeError, s.remove, BadCmp())
275
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000276 def test_cyclical_repr(self):
277 w = ReprWrapper()
278 s = self.thetype([w])
279 w.value = s
280 if self.thetype == set:
281 self.assertEqual(repr(s), '{set(...)}')
282 else:
283 name = repr(s).partition('(')[0] # strip class name
Guido van Rossumbdba5cf2007-08-07 22:44:20 +0000284 self.assertEqual(repr(s), '%s({%s(...)})' % (name, name))
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000285
286 def test_cyclical_print(self):
287 w = ReprWrapper()
288 s = self.thetype([w])
289 w.value = s
290 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000291 fo = open(support.TESTFN, "w")
Guido van Rossumd8c19672007-02-09 21:54:58 +0000292 fo.write(str(s))
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000293 fo.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000294 fo = open(support.TESTFN, "r")
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000295 self.assertEqual(fo.read(), repr(s))
296 finally:
297 fo.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000298 support.unlink(support.TESTFN)
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000299
Thomas Wouterscf297e42007-02-23 15:07:44 +0000300 def test_do_not_rehash_dict_keys(self):
301 n = 10
Guido van Rossum805365e2007-05-07 22:24:25 +0000302 d = dict.fromkeys(map(HashCountingInt, range(n)))
Thomas Wouterscf297e42007-02-23 15:07:44 +0000303 self.assertEqual(sum(elem.hash_count for elem in d), n)
304 s = self.thetype(d)
305 self.assertEqual(sum(elem.hash_count for elem in d), n)
306 s.difference(d)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000307 self.assertEqual(sum(elem.hash_count for elem in d), n)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000308 if hasattr(s, 'symmetric_difference_update'):
309 s.symmetric_difference_update(d)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000310 self.assertEqual(sum(elem.hash_count for elem in d), n)
311 d2 = dict.fromkeys(set(d))
312 self.assertEqual(sum(elem.hash_count for elem in d), n)
313 d3 = dict.fromkeys(frozenset(d))
314 self.assertEqual(sum(elem.hash_count for elem in d), n)
315 d3 = dict.fromkeys(frozenset(d), 123)
316 self.assertEqual(sum(elem.hash_count for elem in d), n)
317 self.assertEqual(d3, dict.fromkeys(d, 123))
Thomas Wouterscf297e42007-02-23 15:07:44 +0000318
Raymond Hettingera690a992003-11-16 16:17:49 +0000319class TestSet(TestJointOps):
320 thetype = set
321
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000322 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000323 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000324 s.__init__(self.word)
325 self.assertEqual(s, set(self.word))
326 s.__init__(self.otherword)
327 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000328 self.assertRaises(TypeError, s.__init__, s, 2);
329 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000330
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000331 def test_constructor_identity(self):
332 s = self.thetype(range(3))
333 t = self.thetype(s)
334 self.assertNotEqual(id(s), id(t))
335
Guido van Rossum86e58e22006-08-28 15:27:34 +0000336 def test_set_literal(self):
337 s = set([1,2,3])
338 t = {1,2,3}
339 self.assertEqual(s, t)
340
Raymond Hettingera690a992003-11-16 16:17:49 +0000341 def test_hash(self):
342 self.assertRaises(TypeError, hash, self.s)
343
344 def test_clear(self):
345 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000346 self.assertEqual(self.s, set())
347 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000348
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000349 def test_copy(self):
350 dup = self.s.copy()
351 self.assertEqual(self.s, dup)
352 self.assertNotEqual(id(self.s), id(dup))
353
Raymond Hettingera690a992003-11-16 16:17:49 +0000354 def test_add(self):
355 self.s.add('Q')
356 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000357 dup = self.s.copy()
358 self.s.add('Q')
359 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000360 self.assertRaises(TypeError, self.s.add, [])
361
362 def test_remove(self):
363 self.s.remove('a')
364 self.assert_('a' not in self.s)
365 self.assertRaises(KeyError, self.s.remove, 'Q')
366 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000367 s = self.thetype([frozenset(self.word)])
368 self.assert_(self.thetype(self.word) in s)
369 s.remove(self.thetype(self.word))
370 self.assert_(self.thetype(self.word) not in s)
371 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000372
Thomas Wouters89f507f2006-12-13 04:49:30 +0000373 def test_remove_keyerror_unpacking(self):
374 # bug: www.python.org/sf/1576657
375 for v1 in ['Q', (1,)]:
376 try:
377 self.s.remove(v1)
Guido van Rossumb940e112007-01-10 16:19:56 +0000378 except KeyError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000379 v2 = e.args[0]
380 self.assertEqual(v1, v2)
381 else:
382 self.fail()
383
Raymond Hettingera690a992003-11-16 16:17:49 +0000384 def test_discard(self):
385 self.s.discard('a')
386 self.assert_('a' not in self.s)
387 self.s.discard('Q')
388 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000389 s = self.thetype([frozenset(self.word)])
390 self.assert_(self.thetype(self.word) in s)
391 s.discard(self.thetype(self.word))
392 self.assert_(self.thetype(self.word) not in s)
393 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000394
395 def test_pop(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000396 for i in range(len(self.s)):
Raymond Hettingera690a992003-11-16 16:17:49 +0000397 elem = self.s.pop()
398 self.assert_(elem not in self.s)
399 self.assertRaises(KeyError, self.s.pop)
400
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000401 def test_update(self):
402 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000403 self.assertEqual(retval, None)
404 for c in (self.word + self.otherword):
405 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000406 self.assertRaises(PassThru, self.s.update, check_pass_thru())
407 self.assertRaises(TypeError, self.s.update, [[]])
408 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000409 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000410 s = self.thetype('abcba')
411 self.assertEqual(s.update(C(p)), None)
412 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000413
414 def test_ior(self):
415 self.s |= set(self.otherword)
416 for c in (self.word + self.otherword):
417 self.assert_(c in self.s)
418
419 def test_intersection_update(self):
420 retval = self.s.intersection_update(self.otherword)
421 self.assertEqual(retval, None)
422 for c in (self.word + self.otherword):
423 if c in self.otherword and c in self.word:
424 self.assert_(c in self.s)
425 else:
426 self.assert_(c not in self.s)
427 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
428 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000429 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000430 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000431 s = self.thetype('abcba')
432 self.assertEqual(s.intersection_update(C(p)), None)
433 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000434
435 def test_iand(self):
436 self.s &= set(self.otherword)
437 for c in (self.word + self.otherword):
438 if c in self.otherword and c in self.word:
439 self.assert_(c in self.s)
440 else:
441 self.assert_(c not in self.s)
442
443 def test_difference_update(self):
444 retval = self.s.difference_update(self.otherword)
445 self.assertEqual(retval, None)
446 for c in (self.word + self.otherword):
447 if c in self.word and c not in self.otherword:
448 self.assert_(c in self.s)
449 else:
450 self.assert_(c not in self.s)
451 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
452 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000453 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
454 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000455 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000456 s = self.thetype('abcba')
457 self.assertEqual(s.difference_update(C(p)), None)
458 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000459
460 def test_isub(self):
461 self.s -= set(self.otherword)
462 for c in (self.word + self.otherword):
463 if c in self.word and c not in self.otherword:
464 self.assert_(c in self.s)
465 else:
466 self.assert_(c not in self.s)
467
468 def test_symmetric_difference_update(self):
469 retval = self.s.symmetric_difference_update(self.otherword)
470 self.assertEqual(retval, None)
471 for c in (self.word + self.otherword):
472 if (c in self.word) ^ (c in self.otherword):
473 self.assert_(c in self.s)
474 else:
475 self.assert_(c not in self.s)
476 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
477 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000478 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000479 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000480 s = self.thetype('abcba')
481 self.assertEqual(s.symmetric_difference_update(C(p)), None)
482 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000483
484 def test_ixor(self):
485 self.s ^= set(self.otherword)
486 for c in (self.word + self.otherword):
487 if (c in self.word) ^ (c in self.otherword):
488 self.assert_(c in self.s)
489 else:
490 self.assert_(c not in self.s)
491
Raymond Hettingerc991db22005-08-11 07:58:45 +0000492 def test_inplace_on_self(self):
493 t = self.s.copy()
494 t |= t
495 self.assertEqual(t, self.s)
496 t &= t
497 self.assertEqual(t, self.s)
498 t -= t
499 self.assertEqual(t, self.thetype())
500 t = self.s.copy()
501 t ^= t
502 self.assertEqual(t, self.thetype())
503
Raymond Hettinger691d8052004-05-30 07:26:47 +0000504 def test_weakref(self):
505 s = self.thetype('gallahad')
506 p = proxy(s)
507 self.assertEqual(str(p), str(s))
508 s = None
509 self.assertRaises(ReferenceError, str, p)
510
Guido van Rossum10ab4ae2007-08-23 23:57:24 +0000511 def test_rich_compare(self):
512 class TestRichSetCompare:
513 def __gt__(self, some_set):
514 self.gt_called = True
515 return False
516 def __lt__(self, some_set):
517 self.lt_called = True
518 return False
519 def __ge__(self, some_set):
520 self.ge_called = True
521 return False
522 def __le__(self, some_set):
523 self.le_called = True
524 return False
525
526 # This first tries the bulitin rich set comparison, which doesn't know
527 # how to handle the custom object. Upon returning NotImplemented, the
528 # corresponding comparison on the right object is invoked.
529 myset = {1, 2, 3}
530
531 myobj = TestRichSetCompare()
532 myset < myobj
533 self.assert_(myobj.gt_called)
534
535 myobj = TestRichSetCompare()
536 myset > myobj
537 self.assert_(myobj.lt_called)
538
539 myobj = TestRichSetCompare()
540 myset <= myobj
541 self.assert_(myobj.ge_called)
542
543 myobj = TestRichSetCompare()
544 myset >= myobj
545 self.assert_(myobj.le_called)
546
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000547 # C API test only available in a debug build
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000548 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000549 def test_c_api(self):
550 self.assertEqual(set('abc').test_c_api(), True)
551
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000552class SetSubclass(set):
553 pass
554
555class TestSetSubclass(TestSet):
556 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000557
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000558class SetSubclassWithKeywordArgs(set):
559 def __init__(self, iterable=[], newarg=None):
560 set.__init__(self, iterable)
561
562class TestSetSubclassWithKeywordArgs(TestSet):
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000563
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000564 def test_keywords_in_subclass(self):
565 'SF bug #1486663 -- this used to erroneously raise a TypeError'
566 SetSubclassWithKeywordArgs(newarg=1)
567
Raymond Hettingera690a992003-11-16 16:17:49 +0000568class TestFrozenSet(TestJointOps):
569 thetype = frozenset
570
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000571 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000572 s = self.thetype(self.word)
573 s.__init__(self.otherword)
574 self.assertEqual(s, set(self.word))
575
Raymond Hettingerd7946662005-08-01 21:39:29 +0000576 def test_singleton_empty_frozenset(self):
577 f = frozenset()
578 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
579 frozenset(), frozenset([]), frozenset(()), frozenset(''),
Guido van Rossum805365e2007-05-07 22:24:25 +0000580 frozenset(range(0)), frozenset(frozenset()),
Raymond Hettingerd7946662005-08-01 21:39:29 +0000581 frozenset(f), f]
582 # All of the empty frozensets should have just one id()
583 self.assertEqual(len(set(map(id, efs))), 1)
584
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000585 def test_constructor_identity(self):
586 s = self.thetype(range(3))
587 t = self.thetype(s)
588 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000589
Raymond Hettingera690a992003-11-16 16:17:49 +0000590 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000591 self.assertEqual(hash(self.thetype('abcdeb')),
592 hash(self.thetype('ebecda')))
593
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000594 # make sure that all permutations give the same hash value
595 n = 100
Guido van Rossum805365e2007-05-07 22:24:25 +0000596 seq = [randrange(n) for i in range(n)]
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000597 results = set()
Guido van Rossum805365e2007-05-07 22:24:25 +0000598 for i in range(200):
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000599 shuffle(seq)
600 results.add(hash(self.thetype(seq)))
601 self.assertEqual(len(results), 1)
602
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000603 def test_copy(self):
604 dup = self.s.copy()
605 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000606
607 def test_frozen_as_dictkey(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000608 seq = list(range(10)) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000609 key1 = self.thetype(seq)
610 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000611 self.assertEqual(key1, key2)
612 self.assertNotEqual(id(key1), id(key2))
613 d = {}
614 d[key1] = 42
615 self.assertEqual(d[key2], 42)
616
617 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000618 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000619 self.assertEqual(hash(f), hash(f))
620
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000621 def test_hash_effectiveness(self):
622 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000623 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000624 addhashvalue = hashvalues.add
625 elemmasks = [(i+1, 1<<i) for i in range(n)]
Guido van Rossum805365e2007-05-07 22:24:25 +0000626 for i in range(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000627 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
628 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000629
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000630class FrozenSetSubclass(frozenset):
631 pass
632
633class TestFrozenSetSubclass(TestFrozenSet):
634 thetype = FrozenSetSubclass
635
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000636 def test_constructor_identity(self):
637 s = self.thetype(range(3))
638 t = self.thetype(s)
639 self.assertNotEqual(id(s), id(t))
640
641 def test_copy(self):
642 dup = self.s.copy()
643 self.assertNotEqual(id(self.s), id(dup))
644
645 def test_nested_empty_constructor(self):
646 s = self.thetype()
647 t = self.thetype(s)
648 self.assertEqual(s, t)
649
Raymond Hettingerd7946662005-08-01 21:39:29 +0000650 def test_singleton_empty_frozenset(self):
651 Frozenset = self.thetype
652 f = frozenset()
653 F = Frozenset()
654 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
655 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
Guido van Rossum805365e2007-05-07 22:24:25 +0000656 Frozenset(range(0)), Frozenset(Frozenset()),
Raymond Hettingerd7946662005-08-01 21:39:29 +0000657 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
658 # All empty frozenset subclass instances should have different ids
659 self.assertEqual(len(set(map(id, efs))), len(efs))
660
Raymond Hettingera690a992003-11-16 16:17:49 +0000661# Tests taken from test_sets.py =============================================
662
663empty_set = set()
664
665#==============================================================================
666
667class TestBasicOps(unittest.TestCase):
668
669 def test_repr(self):
670 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000671 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000672
Raymond Hettingereae05de2004-07-09 04:51:24 +0000673 def test_print(self):
674 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000675 fo = open(support.TESTFN, "w")
Guido van Rossumd8c19672007-02-09 21:54:58 +0000676 fo.write(str(self.set))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000677 fo.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000678 fo = open(support.TESTFN, "r")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000679 self.assertEqual(fo.read(), repr(self.set))
680 finally:
681 fo.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000682 support.unlink(support.TESTFN)
Raymond Hettingereae05de2004-07-09 04:51:24 +0000683
Raymond Hettingera690a992003-11-16 16:17:49 +0000684 def test_length(self):
685 self.assertEqual(len(self.set), self.length)
686
687 def test_self_equality(self):
688 self.assertEqual(self.set, self.set)
689
690 def test_equivalent_equality(self):
691 self.assertEqual(self.set, self.dup)
692
693 def test_copy(self):
694 self.assertEqual(self.set.copy(), self.dup)
695
696 def test_self_union(self):
697 result = self.set | self.set
698 self.assertEqual(result, self.dup)
699
700 def test_empty_union(self):
701 result = self.set | empty_set
702 self.assertEqual(result, self.dup)
703
704 def test_union_empty(self):
705 result = empty_set | self.set
706 self.assertEqual(result, self.dup)
707
708 def test_self_intersection(self):
709 result = self.set & self.set
710 self.assertEqual(result, self.dup)
711
712 def test_empty_intersection(self):
713 result = self.set & empty_set
714 self.assertEqual(result, empty_set)
715
716 def test_intersection_empty(self):
717 result = empty_set & self.set
718 self.assertEqual(result, empty_set)
719
Guido van Rossum58da9312007-11-10 23:39:45 +0000720 def test_self_isdisjoint(self):
721 result = self.set.isdisjoint(self.set)
722 self.assertEqual(result, not self.set)
723
724 def test_empty_isdisjoint(self):
725 result = self.set.isdisjoint(empty_set)
726 self.assertEqual(result, True)
727
728 def test_isdisjoint_empty(self):
729 result = empty_set.isdisjoint(self.set)
730 self.assertEqual(result, True)
731
Raymond Hettingera690a992003-11-16 16:17:49 +0000732 def test_self_symmetric_difference(self):
733 result = self.set ^ self.set
734 self.assertEqual(result, empty_set)
735
736 def checkempty_symmetric_difference(self):
737 result = self.set ^ empty_set
738 self.assertEqual(result, self.set)
739
740 def test_self_difference(self):
741 result = self.set - self.set
742 self.assertEqual(result, empty_set)
743
744 def test_empty_difference(self):
745 result = self.set - empty_set
746 self.assertEqual(result, self.dup)
747
748 def test_empty_difference_rev(self):
749 result = empty_set - self.set
750 self.assertEqual(result, empty_set)
751
752 def test_iteration(self):
753 for v in self.set:
754 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000755 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000756 # note: __length_hint__ is an internal undocumented API,
757 # don't rely on it in your own programs
758 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000759
760 def test_pickling(self):
761 p = pickle.dumps(self.set)
762 copy = pickle.loads(p)
763 self.assertEqual(self.set, copy,
764 "%s != %s" % (self.set, copy))
765
766#------------------------------------------------------------------------------
767
768class TestBasicOpsEmpty(TestBasicOps):
769 def setUp(self):
770 self.case = "empty set"
771 self.values = []
772 self.set = set(self.values)
773 self.dup = set(self.values)
774 self.length = 0
Georg Brandlc4996ba2006-08-28 19:37:11 +0000775 self.repr = "set()"
Raymond Hettingera690a992003-11-16 16:17:49 +0000776
777#------------------------------------------------------------------------------
778
779class TestBasicOpsSingleton(TestBasicOps):
780 def setUp(self):
781 self.case = "unit set (number)"
782 self.values = [3]
783 self.set = set(self.values)
784 self.dup = set(self.values)
785 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000786 self.repr = "{3}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000787
788 def test_in(self):
789 self.failUnless(3 in self.set)
790
791 def test_not_in(self):
792 self.failUnless(2 not in self.set)
793
794#------------------------------------------------------------------------------
795
796class TestBasicOpsTuple(TestBasicOps):
797 def setUp(self):
798 self.case = "unit set (tuple)"
799 self.values = [(0, "zero")]
800 self.set = set(self.values)
801 self.dup = set(self.values)
802 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000803 self.repr = "{(0, 'zero')}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000804
805 def test_in(self):
806 self.failUnless((0, "zero") in self.set)
807
808 def test_not_in(self):
809 self.failUnless(9 not in self.set)
810
811#------------------------------------------------------------------------------
812
813class TestBasicOpsTriple(TestBasicOps):
814 def setUp(self):
815 self.case = "triple set"
816 self.values = [0, "zero", operator.add]
817 self.set = set(self.values)
818 self.dup = set(self.values)
819 self.length = 3
820 self.repr = None
821
Christian Heimes0ded5b52007-12-10 15:50:56 +0000822#------------------------------------------------------------------------------
823
824class TestBasicOpsString(TestBasicOps):
825 def setUp(self):
826 self.case = "string set"
827 self.values = ["a", "b", "c"]
828 self.set = set(self.values)
829 self.dup = set(self.values)
830 self.length = 3
831 self.repr = "{'a', 'c', 'b'}"
832
833#------------------------------------------------------------------------------
834
835class TestBasicOpsBytes(TestBasicOps):
836 def setUp(self):
837 self.case = "string set"
838 self.values = [b"a", b"b", b"c"]
839 self.set = set(self.values)
840 self.dup = set(self.values)
841 self.length = 3
842 self.repr = "{b'a', b'c', b'b'}"
843
844#------------------------------------------------------------------------------
845
846class TestBasicOpsMixedStringBytes(TestBasicOps):
847 def setUp(self):
848 self.warning_filters = warnings.filters[:]
849 warnings.simplefilter('ignore', BytesWarning)
850 self.case = "string and bytes set"
851 self.values = ["a", "b", b"a", b"b"]
852 self.set = set(self.values)
853 self.dup = set(self.values)
854 self.length = 4
855 self.repr = "{'a', b'a', 'b', b'b'}"
856
857 def tearDown(self):
858 warnings.filters = self.warning_filters
859
Raymond Hettingera690a992003-11-16 16:17:49 +0000860#==============================================================================
861
862def baditer():
863 raise TypeError
864 yield True
865
866def gooditer():
867 yield True
868
869class TestExceptionPropagation(unittest.TestCase):
870 """SF 628246: Set constructor should not trap iterator TypeErrors"""
871
872 def test_instanceWithException(self):
873 self.assertRaises(TypeError, set, baditer())
874
875 def test_instancesWithoutException(self):
876 # All of these iterables should load without exception.
877 set([1,2,3])
878 set((1,2,3))
879 set({'one':1, 'two':2, 'three':3})
Guido van Rossum805365e2007-05-07 22:24:25 +0000880 set(range(3))
Raymond Hettingera690a992003-11-16 16:17:49 +0000881 set('abc')
882 set(gooditer())
883
Neal Norwitzfcf44352005-11-27 20:37:43 +0000884 def test_changingSizeWhileIterating(self):
885 s = set([1,2,3])
886 try:
887 for i in s:
888 s.update([4])
889 except RuntimeError:
890 pass
891 else:
892 self.fail("no exception when changing size during iteration")
893
Raymond Hettingera690a992003-11-16 16:17:49 +0000894#==============================================================================
895
896class TestSetOfSets(unittest.TestCase):
897 def test_constructor(self):
898 inner = frozenset([1])
899 outer = set([inner])
900 element = outer.pop()
901 self.assertEqual(type(element), frozenset)
902 outer.add(inner) # Rebuild set of sets with .add method
903 outer.remove(inner)
904 self.assertEqual(outer, set()) # Verify that remove worked
905 outer.discard(inner) # Absence of KeyError indicates working fine
906
907#==============================================================================
908
909class TestBinaryOps(unittest.TestCase):
910 def setUp(self):
911 self.set = set((2, 4, 6))
912
913 def test_eq(self): # SF bug 643115
914 self.assertEqual(self.set, set({2:1,4:3,6:5}))
915
916 def test_union_subset(self):
917 result = self.set | set([2])
918 self.assertEqual(result, set((2, 4, 6)))
919
920 def test_union_superset(self):
921 result = self.set | set([2, 4, 6, 8])
922 self.assertEqual(result, set([2, 4, 6, 8]))
923
924 def test_union_overlap(self):
925 result = self.set | set([3, 4, 5])
926 self.assertEqual(result, set([2, 3, 4, 5, 6]))
927
928 def test_union_non_overlap(self):
929 result = self.set | set([8])
930 self.assertEqual(result, set([2, 4, 6, 8]))
931
932 def test_intersection_subset(self):
933 result = self.set & set((2, 4))
934 self.assertEqual(result, set((2, 4)))
935
936 def test_intersection_superset(self):
937 result = self.set & set([2, 4, 6, 8])
938 self.assertEqual(result, set([2, 4, 6]))
939
940 def test_intersection_overlap(self):
941 result = self.set & set([3, 4, 5])
942 self.assertEqual(result, set([4]))
943
944 def test_intersection_non_overlap(self):
945 result = self.set & set([8])
946 self.assertEqual(result, empty_set)
947
Guido van Rossum58da9312007-11-10 23:39:45 +0000948 def test_isdisjoint_subset(self):
949 result = self.set.isdisjoint(set((2, 4)))
950 self.assertEqual(result, False)
951
952 def test_isdisjoint_superset(self):
953 result = self.set.isdisjoint(set([2, 4, 6, 8]))
954 self.assertEqual(result, False)
955
956 def test_isdisjoint_overlap(self):
957 result = self.set.isdisjoint(set([3, 4, 5]))
958 self.assertEqual(result, False)
959
960 def test_isdisjoint_non_overlap(self):
961 result = self.set.isdisjoint(set([8]))
962 self.assertEqual(result, True)
963
Raymond Hettingera690a992003-11-16 16:17:49 +0000964 def test_sym_difference_subset(self):
965 result = self.set ^ set((2, 4))
966 self.assertEqual(result, set([6]))
967
968 def test_sym_difference_superset(self):
969 result = self.set ^ set((2, 4, 6, 8))
970 self.assertEqual(result, set([8]))
971
972 def test_sym_difference_overlap(self):
973 result = self.set ^ set((3, 4, 5))
974 self.assertEqual(result, set([2, 3, 5, 6]))
975
976 def test_sym_difference_non_overlap(self):
977 result = self.set ^ set([8])
978 self.assertEqual(result, set([2, 4, 6, 8]))
979
980 def test_cmp(self):
981 a, b = set('a'), set('b')
982 self.assertRaises(TypeError, cmp, a, b)
983
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000984 # In py3k, this works!
985 self.assertRaises(TypeError, cmp, a, a)
Raymond Hettingera690a992003-11-16 16:17:49 +0000986
987 self.assertRaises(TypeError, cmp, a, 12)
988 self.assertRaises(TypeError, cmp, "abc", a)
989
990#==============================================================================
991
992class TestUpdateOps(unittest.TestCase):
993 def setUp(self):
994 self.set = set((2, 4, 6))
995
996 def test_union_subset(self):
997 self.set |= set([2])
998 self.assertEqual(self.set, set((2, 4, 6)))
999
1000 def test_union_superset(self):
1001 self.set |= set([2, 4, 6, 8])
1002 self.assertEqual(self.set, set([2, 4, 6, 8]))
1003
1004 def test_union_overlap(self):
1005 self.set |= set([3, 4, 5])
1006 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1007
1008 def test_union_non_overlap(self):
1009 self.set |= set([8])
1010 self.assertEqual(self.set, set([2, 4, 6, 8]))
1011
1012 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001013 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +00001014 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1015
1016 def test_intersection_subset(self):
1017 self.set &= set((2, 4))
1018 self.assertEqual(self.set, set((2, 4)))
1019
1020 def test_intersection_superset(self):
1021 self.set &= set([2, 4, 6, 8])
1022 self.assertEqual(self.set, set([2, 4, 6]))
1023
1024 def test_intersection_overlap(self):
1025 self.set &= set([3, 4, 5])
1026 self.assertEqual(self.set, set([4]))
1027
1028 def test_intersection_non_overlap(self):
1029 self.set &= set([8])
1030 self.assertEqual(self.set, empty_set)
1031
1032 def test_intersection_method_call(self):
1033 self.set.intersection_update(set([3, 4, 5]))
1034 self.assertEqual(self.set, set([4]))
1035
1036 def test_sym_difference_subset(self):
1037 self.set ^= set((2, 4))
1038 self.assertEqual(self.set, set([6]))
1039
1040 def test_sym_difference_superset(self):
1041 self.set ^= set((2, 4, 6, 8))
1042 self.assertEqual(self.set, set([8]))
1043
1044 def test_sym_difference_overlap(self):
1045 self.set ^= set((3, 4, 5))
1046 self.assertEqual(self.set, set([2, 3, 5, 6]))
1047
1048 def test_sym_difference_non_overlap(self):
1049 self.set ^= set([8])
1050 self.assertEqual(self.set, set([2, 4, 6, 8]))
1051
1052 def test_sym_difference_method_call(self):
1053 self.set.symmetric_difference_update(set([3, 4, 5]))
1054 self.assertEqual(self.set, set([2, 3, 5, 6]))
1055
1056 def test_difference_subset(self):
1057 self.set -= set((2, 4))
1058 self.assertEqual(self.set, set([6]))
1059
1060 def test_difference_superset(self):
1061 self.set -= set((2, 4, 6, 8))
1062 self.assertEqual(self.set, set([]))
1063
1064 def test_difference_overlap(self):
1065 self.set -= set((3, 4, 5))
1066 self.assertEqual(self.set, set([2, 6]))
1067
1068 def test_difference_non_overlap(self):
1069 self.set -= set([8])
1070 self.assertEqual(self.set, set([2, 4, 6]))
1071
1072 def test_difference_method_call(self):
1073 self.set.difference_update(set([3, 4, 5]))
1074 self.assertEqual(self.set, set([2, 6]))
1075
1076#==============================================================================
1077
1078class TestMutate(unittest.TestCase):
1079 def setUp(self):
1080 self.values = ["a", "b", "c"]
1081 self.set = set(self.values)
1082
1083 def test_add_present(self):
1084 self.set.add("c")
1085 self.assertEqual(self.set, set("abc"))
1086
1087 def test_add_absent(self):
1088 self.set.add("d")
1089 self.assertEqual(self.set, set("abcd"))
1090
1091 def test_add_until_full(self):
1092 tmp = set()
1093 expected_len = 0
1094 for v in self.values:
1095 tmp.add(v)
1096 expected_len += 1
1097 self.assertEqual(len(tmp), expected_len)
1098 self.assertEqual(tmp, self.set)
1099
1100 def test_remove_present(self):
1101 self.set.remove("b")
1102 self.assertEqual(self.set, set("ac"))
1103
1104 def test_remove_absent(self):
1105 try:
1106 self.set.remove("d")
1107 self.fail("Removing missing element should have raised LookupError")
1108 except LookupError:
1109 pass
1110
1111 def test_remove_until_empty(self):
1112 expected_len = len(self.set)
1113 for v in self.values:
1114 self.set.remove(v)
1115 expected_len -= 1
1116 self.assertEqual(len(self.set), expected_len)
1117
1118 def test_discard_present(self):
1119 self.set.discard("c")
1120 self.assertEqual(self.set, set("ab"))
1121
1122 def test_discard_absent(self):
1123 self.set.discard("d")
1124 self.assertEqual(self.set, set("abc"))
1125
1126 def test_clear(self):
1127 self.set.clear()
1128 self.assertEqual(len(self.set), 0)
1129
1130 def test_pop(self):
1131 popped = {}
1132 while self.set:
1133 popped[self.set.pop()] = None
1134 self.assertEqual(len(popped), len(self.values))
1135 for v in self.values:
1136 self.failUnless(v in popped)
1137
1138 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001139 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001140 self.assertEqual(self.set, set(self.values))
1141
1142 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001143 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001144 self.assertEqual(self.set, set(self.values))
1145
1146 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001147 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001148 self.assertEqual(self.set, set(self.values + ["z"]))
1149
1150#==============================================================================
1151
1152class TestSubsets(unittest.TestCase):
1153
1154 case2method = {"<=": "issubset",
1155 ">=": "issuperset",
1156 }
1157
1158 reverse = {"==": "==",
1159 "!=": "!=",
1160 "<": ">",
1161 ">": "<",
1162 "<=": ">=",
1163 ">=": "<=",
1164 }
1165
1166 def test_issubset(self):
1167 x = self.left
1168 y = self.right
1169 for case in "!=", "==", "<", "<=", ">", ">=":
1170 expected = case in self.cases
1171 # Test the binary infix spelling.
1172 result = eval("x" + case + "y", locals())
1173 self.assertEqual(result, expected)
1174 # Test the "friendly" method-name spelling, if one exists.
1175 if case in TestSubsets.case2method:
1176 method = getattr(x, TestSubsets.case2method[case])
1177 result = method(y)
1178 self.assertEqual(result, expected)
1179
1180 # Now do the same for the operands reversed.
1181 rcase = TestSubsets.reverse[case]
1182 result = eval("y" + rcase + "x", locals())
1183 self.assertEqual(result, expected)
1184 if rcase in TestSubsets.case2method:
1185 method = getattr(y, TestSubsets.case2method[rcase])
1186 result = method(x)
1187 self.assertEqual(result, expected)
1188#------------------------------------------------------------------------------
1189
1190class TestSubsetEqualEmpty(TestSubsets):
1191 left = set()
1192 right = set()
1193 name = "both empty"
1194 cases = "==", "<=", ">="
1195
1196#------------------------------------------------------------------------------
1197
1198class TestSubsetEqualNonEmpty(TestSubsets):
1199 left = set([1, 2])
1200 right = set([1, 2])
1201 name = "equal pair"
1202 cases = "==", "<=", ">="
1203
1204#------------------------------------------------------------------------------
1205
1206class TestSubsetEmptyNonEmpty(TestSubsets):
1207 left = set()
1208 right = set([1, 2])
1209 name = "one empty, one non-empty"
1210 cases = "!=", "<", "<="
1211
1212#------------------------------------------------------------------------------
1213
1214class TestSubsetPartial(TestSubsets):
1215 left = set([1])
1216 right = set([1, 2])
1217 name = "one a non-empty proper subset of other"
1218 cases = "!=", "<", "<="
1219
1220#------------------------------------------------------------------------------
1221
1222class TestSubsetNonOverlap(TestSubsets):
1223 left = set([1])
1224 right = set([2])
1225 name = "neither empty, neither contains"
1226 cases = "!="
1227
1228#==============================================================================
1229
1230class TestOnlySetsInBinaryOps(unittest.TestCase):
1231
1232 def test_eq_ne(self):
1233 # Unlike the others, this is testing that == and != *are* allowed.
1234 self.assertEqual(self.other == self.set, False)
1235 self.assertEqual(self.set == self.other, False)
1236 self.assertEqual(self.other != self.set, True)
1237 self.assertEqual(self.set != self.other, True)
1238
1239 def test_ge_gt_le_lt(self):
1240 self.assertRaises(TypeError, lambda: self.set < self.other)
1241 self.assertRaises(TypeError, lambda: self.set <= self.other)
1242 self.assertRaises(TypeError, lambda: self.set > self.other)
1243 self.assertRaises(TypeError, lambda: self.set >= self.other)
1244
1245 self.assertRaises(TypeError, lambda: self.other < self.set)
1246 self.assertRaises(TypeError, lambda: self.other <= self.set)
1247 self.assertRaises(TypeError, lambda: self.other > self.set)
1248 self.assertRaises(TypeError, lambda: self.other >= self.set)
1249
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001250 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001251 try:
1252 self.set |= self.other
1253 except TypeError:
1254 pass
1255 else:
1256 self.fail("expected TypeError")
1257
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001258 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001259 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001260 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001261 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001262 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001263
1264 def test_union(self):
1265 self.assertRaises(TypeError, lambda: self.set | self.other)
1266 self.assertRaises(TypeError, lambda: self.other | self.set)
1267 if self.otherIsIterable:
1268 self.set.union(self.other)
1269 else:
1270 self.assertRaises(TypeError, self.set.union, self.other)
1271
1272 def test_intersection_update_operator(self):
1273 try:
1274 self.set &= self.other
1275 except TypeError:
1276 pass
1277 else:
1278 self.fail("expected TypeError")
1279
1280 def test_intersection_update(self):
1281 if self.otherIsIterable:
1282 self.set.intersection_update(self.other)
1283 else:
1284 self.assertRaises(TypeError,
1285 self.set.intersection_update,
1286 self.other)
1287
1288 def test_intersection(self):
1289 self.assertRaises(TypeError, lambda: self.set & self.other)
1290 self.assertRaises(TypeError, lambda: self.other & self.set)
1291 if self.otherIsIterable:
1292 self.set.intersection(self.other)
1293 else:
1294 self.assertRaises(TypeError, self.set.intersection, self.other)
1295
1296 def test_sym_difference_update_operator(self):
1297 try:
1298 self.set ^= self.other
1299 except TypeError:
1300 pass
1301 else:
1302 self.fail("expected TypeError")
1303
1304 def test_sym_difference_update(self):
1305 if self.otherIsIterable:
1306 self.set.symmetric_difference_update(self.other)
1307 else:
1308 self.assertRaises(TypeError,
1309 self.set.symmetric_difference_update,
1310 self.other)
1311
1312 def test_sym_difference(self):
1313 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1314 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1315 if self.otherIsIterable:
1316 self.set.symmetric_difference(self.other)
1317 else:
1318 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1319
1320 def test_difference_update_operator(self):
1321 try:
1322 self.set -= self.other
1323 except TypeError:
1324 pass
1325 else:
1326 self.fail("expected TypeError")
1327
1328 def test_difference_update(self):
1329 if self.otherIsIterable:
1330 self.set.difference_update(self.other)
1331 else:
1332 self.assertRaises(TypeError,
1333 self.set.difference_update,
1334 self.other)
1335
1336 def test_difference(self):
1337 self.assertRaises(TypeError, lambda: self.set - self.other)
1338 self.assertRaises(TypeError, lambda: self.other - self.set)
1339 if self.otherIsIterable:
1340 self.set.difference(self.other)
1341 else:
1342 self.assertRaises(TypeError, self.set.difference, self.other)
1343
1344#------------------------------------------------------------------------------
1345
1346class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1347 def setUp(self):
1348 self.set = set((1, 2, 3))
1349 self.other = 19
1350 self.otherIsIterable = False
1351
1352#------------------------------------------------------------------------------
1353
1354class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1355 def setUp(self):
1356 self.set = set((1, 2, 3))
1357 self.other = {1:2, 3:4}
1358 self.otherIsIterable = True
1359
1360#------------------------------------------------------------------------------
1361
1362class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1363 def setUp(self):
1364 self.set = set((1, 2, 3))
1365 self.other = operator.add
1366 self.otherIsIterable = False
1367
1368#------------------------------------------------------------------------------
1369
1370class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1371 def setUp(self):
1372 self.set = set((1, 2, 3))
1373 self.other = (2, 4, 6)
1374 self.otherIsIterable = True
1375
1376#------------------------------------------------------------------------------
1377
1378class TestOnlySetsString(TestOnlySetsInBinaryOps):
1379 def setUp(self):
1380 self.set = set((1, 2, 3))
1381 self.other = 'abc'
1382 self.otherIsIterable = True
1383
1384#------------------------------------------------------------------------------
1385
1386class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1387 def setUp(self):
1388 def gen():
Guido van Rossum805365e2007-05-07 22:24:25 +00001389 for i in range(0, 10, 2):
Raymond Hettingera690a992003-11-16 16:17:49 +00001390 yield i
1391 self.set = set((1, 2, 3))
1392 self.other = gen()
1393 self.otherIsIterable = True
1394
1395#==============================================================================
1396
1397class TestCopying(unittest.TestCase):
1398
1399 def test_copy(self):
1400 dup = self.set.copy()
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001401 dup_list = sorted(dup, key=repr)
1402 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001403 self.assertEqual(len(dup_list), len(set_list))
1404 for i in range(len(dup_list)):
1405 self.failUnless(dup_list[i] is set_list[i])
1406
1407 def test_deep_copy(self):
1408 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001409 ##print type(dup), repr(dup)
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001410 dup_list = sorted(dup, key=repr)
1411 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001412 self.assertEqual(len(dup_list), len(set_list))
1413 for i in range(len(dup_list)):
1414 self.assertEqual(dup_list[i], set_list[i])
1415
1416#------------------------------------------------------------------------------
1417
1418class TestCopyingEmpty(TestCopying):
1419 def setUp(self):
1420 self.set = set()
1421
1422#------------------------------------------------------------------------------
1423
1424class TestCopyingSingleton(TestCopying):
1425 def setUp(self):
1426 self.set = set(["hello"])
1427
1428#------------------------------------------------------------------------------
1429
1430class TestCopyingTriple(TestCopying):
1431 def setUp(self):
1432 self.set = set(["zero", 0, None])
1433
1434#------------------------------------------------------------------------------
1435
1436class TestCopyingTuple(TestCopying):
1437 def setUp(self):
1438 self.set = set([(1, 2)])
1439
1440#------------------------------------------------------------------------------
1441
1442class TestCopyingNested(TestCopying):
1443 def setUp(self):
1444 self.set = set([((1, 2), (3, 4))])
1445
1446#==============================================================================
1447
1448class TestIdentities(unittest.TestCase):
1449 def setUp(self):
1450 self.a = set('abracadabra')
1451 self.b = set('alacazam')
1452
1453 def test_binopsVsSubsets(self):
1454 a, b = self.a, self.b
1455 self.assert_(a - b < a)
1456 self.assert_(b - a < b)
1457 self.assert_(a & b < a)
1458 self.assert_(a & b < b)
1459 self.assert_(a | b > a)
1460 self.assert_(a | b > b)
1461 self.assert_(a ^ b < a | b)
1462
1463 def test_commutativity(self):
1464 a, b = self.a, self.b
1465 self.assertEqual(a&b, b&a)
1466 self.assertEqual(a|b, b|a)
1467 self.assertEqual(a^b, b^a)
1468 if a != b:
1469 self.assertNotEqual(a-b, b-a)
1470
1471 def test_summations(self):
1472 # check that sums of parts equal the whole
1473 a, b = self.a, self.b
1474 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1475 self.assertEqual((a&b)|(a^b), a|b)
1476 self.assertEqual(a|(b-a), a|b)
1477 self.assertEqual((a-b)|b, a|b)
1478 self.assertEqual((a-b)|(a&b), a)
1479 self.assertEqual((b-a)|(a&b), b)
1480 self.assertEqual((a-b)|(b-a), a^b)
1481
1482 def test_exclusion(self):
1483 # check that inverse operations show non-overlap
1484 a, b, zero = self.a, self.b, set()
1485 self.assertEqual((a-b)&b, zero)
1486 self.assertEqual((b-a)&a, zero)
1487 self.assertEqual((a&b)&(a^b), zero)
1488
1489# Tests derived from test_itertools.py =======================================
1490
1491def R(seqn):
1492 'Regular generator'
1493 for i in seqn:
1494 yield i
1495
1496class G:
1497 'Sequence using __getitem__'
1498 def __init__(self, seqn):
1499 self.seqn = seqn
1500 def __getitem__(self, i):
1501 return self.seqn[i]
1502
1503class I:
1504 'Sequence using iterator protocol'
1505 def __init__(self, seqn):
1506 self.seqn = seqn
1507 self.i = 0
1508 def __iter__(self):
1509 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001510 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001511 if self.i >= len(self.seqn): raise StopIteration
1512 v = self.seqn[self.i]
1513 self.i += 1
1514 return v
1515
1516class Ig:
1517 'Sequence using iterator protocol defined with a generator'
1518 def __init__(self, seqn):
1519 self.seqn = seqn
1520 self.i = 0
1521 def __iter__(self):
1522 for val in self.seqn:
1523 yield val
1524
1525class X:
1526 'Missing __getitem__ and __iter__'
1527 def __init__(self, seqn):
1528 self.seqn = seqn
1529 self.i = 0
Georg Brandla18af4e2007-04-21 15:47:16 +00001530 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001531 if self.i >= len(self.seqn): raise StopIteration
1532 v = self.seqn[self.i]
1533 self.i += 1
1534 return v
1535
1536class N:
Georg Brandla18af4e2007-04-21 15:47:16 +00001537 'Iterator missing __next__()'
Raymond Hettingera690a992003-11-16 16:17:49 +00001538 def __init__(self, seqn):
1539 self.seqn = seqn
1540 self.i = 0
1541 def __iter__(self):
1542 return self
1543
1544class E:
1545 'Test propagation of exceptions'
1546 def __init__(self, seqn):
1547 self.seqn = seqn
1548 self.i = 0
1549 def __iter__(self):
1550 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001551 def __next__(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001552 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001553
1554class S:
1555 'Test immediate stop'
1556 def __init__(self, seqn):
1557 pass
1558 def __iter__(self):
1559 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001560 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001561 raise StopIteration
1562
Raymond Hettingera6c60372008-03-13 01:26:19 +00001563from itertools import chain
Raymond Hettingera690a992003-11-16 16:17:49 +00001564def L(seqn):
1565 'Test multiple tiers of iterators'
Raymond Hettingera6c60372008-03-13 01:26:19 +00001566 return chain(map(lambda x:x, R(Ig(G(seqn)))))
Raymond Hettingera690a992003-11-16 16:17:49 +00001567
1568class TestVariousIteratorArgs(unittest.TestCase):
1569
1570 def test_constructor(self):
1571 for cons in (set, frozenset):
Guido van Rossum805365e2007-05-07 22:24:25 +00001572 for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
Raymond Hettingera690a992003-11-16 16:17:49 +00001573 for g in (G, I, Ig, S, L, R):
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001574 self.assertEqual(sorted(cons(g(s)), key=repr), sorted(g(s), key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001575 self.assertRaises(TypeError, cons , X(s))
1576 self.assertRaises(TypeError, cons , N(s))
1577 self.assertRaises(ZeroDivisionError, cons , E(s))
1578
1579 def test_inline_methods(self):
1580 s = set('november')
Guido van Rossum805365e2007-05-07 22:24:25 +00001581 for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
Guido van Rossum58da9312007-11-10 23:39:45 +00001582 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001583 for g in (G, I, Ig, L, R):
1584 expected = meth(data)
1585 actual = meth(G(data))
Guido van Rossum58da9312007-11-10 23:39:45 +00001586 if isinstance(expected, bool):
1587 self.assertEqual(actual, expected)
1588 else:
1589 self.assertEqual(sorted(actual, key=repr), sorted(expected, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001590 self.assertRaises(TypeError, meth, X(s))
1591 self.assertRaises(TypeError, meth, N(s))
1592 self.assertRaises(ZeroDivisionError, meth, E(s))
1593
1594 def test_inplace_methods(self):
Guido van Rossum805365e2007-05-07 22:24:25 +00001595 for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001596 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001597 'difference_update', 'symmetric_difference_update'):
1598 for g in (G, I, Ig, S, L, R):
1599 s = set('january')
1600 t = s.copy()
1601 getattr(s, methname)(list(g(data)))
1602 getattr(t, methname)(g(data))
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001603 self.assertEqual(sorted(s, key=repr), sorted(t, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001604
1605 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1606 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1607 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1608
Christian Heimes969fe572008-01-25 11:23:10 +00001609# Application tests (based on David Eppstein's graph recipes ====================================
1610
1611def powerset(U):
1612 """Generates all subsets of a set or sequence U."""
1613 U = iter(U)
1614 try:
1615 x = frozenset([next(U)])
1616 for S in powerset(U):
1617 yield S
1618 yield S | x
1619 except StopIteration:
1620 yield frozenset()
1621
1622def cube(n):
1623 """Graph of n-dimensional hypercube."""
1624 singletons = [frozenset([x]) for x in range(n)]
1625 return dict([(x, frozenset([x^s for s in singletons]))
1626 for x in powerset(range(n))])
1627
1628def linegraph(G):
1629 """Graph, the vertices of which are edges of G,
1630 with two vertices being adjacent iff the corresponding
1631 edges share a vertex."""
1632 L = {}
1633 for x in G:
1634 for y in G[x]:
1635 nx = [frozenset([x,z]) for z in G[x] if z != y]
1636 ny = [frozenset([y,z]) for z in G[y] if z != x]
1637 L[frozenset([x,y])] = frozenset(nx+ny)
1638 return L
1639
1640def faces(G):
1641 'Return a set of faces in G. Where a face is a set of vertices on that face'
1642 # currently limited to triangles,squares, and pentagons
1643 f = set()
1644 for v1, edges in G.items():
1645 for v2 in edges:
1646 for v3 in G[v2]:
1647 if v1 == v3:
1648 continue
1649 if v1 in G[v3]:
1650 f.add(frozenset([v1, v2, v3]))
1651 else:
1652 for v4 in G[v3]:
1653 if v4 == v2:
1654 continue
1655 if v1 in G[v4]:
1656 f.add(frozenset([v1, v2, v3, v4]))
1657 else:
1658 for v5 in G[v4]:
1659 if v5 == v3 or v5 == v2:
1660 continue
1661 if v1 in G[v5]:
1662 f.add(frozenset([v1, v2, v3, v4, v5]))
1663 return f
1664
1665
1666class TestGraphs(unittest.TestCase):
1667
1668 def test_cube(self):
1669
1670 g = cube(3) # vert --> {v1, v2, v3}
1671 vertices1 = set(g)
1672 self.assertEqual(len(vertices1), 8) # eight vertices
1673 for edge in g.values():
1674 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1675 vertices2 = set(v for edges in g.values() for v in edges)
1676 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1677
1678 cubefaces = faces(g)
1679 self.assertEqual(len(cubefaces), 6) # six faces
1680 for face in cubefaces:
1681 self.assertEqual(len(face), 4) # each face is a square
1682
1683 def test_cuboctahedron(self):
1684
1685 # http://en.wikipedia.org/wiki/Cuboctahedron
1686 # 8 triangular faces and 6 square faces
1687 # 12 indentical vertices each connecting a triangle and square
1688
1689 g = cube(3)
1690 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1691 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1692
1693 vertices = set(cuboctahedron)
1694 for edges in cuboctahedron.values():
1695 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1696 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1697 self.assertEqual(vertices, othervertices) # edge vertices in original set
1698
1699 cubofaces = faces(cuboctahedron)
1700 facesizes = collections.defaultdict(int)
1701 for face in cubofaces:
1702 facesizes[len(face)] += 1
1703 self.assertEqual(facesizes[3], 8) # eight triangular faces
1704 self.assertEqual(facesizes[4], 6) # six square faces
1705
1706 for vertex in cuboctahedron:
1707 edge = vertex # Cuboctahedron vertices are edges in Cube
1708 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1709 for cubevert in edge:
1710 self.assert_(cubevert in g)
1711
1712
Raymond Hettingera690a992003-11-16 16:17:49 +00001713#==============================================================================
1714
1715def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001716 test_classes = (
1717 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001718 TestSetSubclass,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001719 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001720 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001721 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001722 TestSetOfSets,
1723 TestExceptionPropagation,
1724 TestBasicOpsEmpty,
1725 TestBasicOpsSingleton,
1726 TestBasicOpsTuple,
1727 TestBasicOpsTriple,
Christian Heimes0ded5b52007-12-10 15:50:56 +00001728 TestBasicOpsString,
1729 TestBasicOpsBytes,
1730 TestBasicOpsMixedStringBytes,
Raymond Hettingera690a992003-11-16 16:17:49 +00001731 TestBinaryOps,
1732 TestUpdateOps,
1733 TestMutate,
1734 TestSubsetEqualEmpty,
1735 TestSubsetEqualNonEmpty,
1736 TestSubsetEmptyNonEmpty,
1737 TestSubsetPartial,
1738 TestSubsetNonOverlap,
1739 TestOnlySetsNumeric,
1740 TestOnlySetsDict,
1741 TestOnlySetsOperator,
1742 TestOnlySetsTuple,
1743 TestOnlySetsString,
1744 TestOnlySetsGenerator,
1745 TestCopyingEmpty,
1746 TestCopyingSingleton,
1747 TestCopyingTriple,
1748 TestCopyingTuple,
1749 TestCopyingNested,
1750 TestIdentities,
1751 TestVariousIteratorArgs,
Christian Heimes969fe572008-01-25 11:23:10 +00001752 TestGraphs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001753 )
1754
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001755 support.run_unittest(*test_classes)
Raymond Hettingera690a992003-11-16 16:17:49 +00001756
1757 # verify reference counting
1758 if verbose and hasattr(sys, "gettotalrefcount"):
1759 import gc
1760 counts = [None] * 5
Guido van Rossum805365e2007-05-07 22:24:25 +00001761 for i in range(len(counts)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001762 support.run_unittest(*test_classes)
Raymond Hettingera690a992003-11-16 16:17:49 +00001763 gc.collect()
1764 counts[i] = sys.gettotalrefcount()
Guido van Rossumd8c19672007-02-09 21:54:58 +00001765 print(counts)
Raymond Hettingera690a992003-11-16 16:17:49 +00001766
1767if __name__ == "__main__":
1768 test_main(verbose=True)