blob: 07319fc20d1ce1c80c23cd73ca4a2cf9adaf39d8 [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 Hettinger7d99f092008-11-16 11:44:54 +000074 self.assertEqual(type(u), self.basetype)
Raymond Hettingera690a992003-11-16 16:17:49 +000075 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'))
Georg Brandlc28e1fa2008-06-10 19:20:26 +000082 self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
Raymond Hettingera690a992003-11-16 16:17:49 +000083
84 def test_or(self):
85 i = self.s.union(self.otherword)
86 self.assertEqual(self.s | set(self.otherword), i)
87 self.assertEqual(self.s | frozenset(self.otherword), i)
88 try:
89 self.s | self.otherword
90 except TypeError:
91 pass
92 else:
93 self.fail("s|t did not screen-out general iterables")
94
95 def test_intersection(self):
96 i = self.s.intersection(self.otherword)
97 for c in self.letters:
98 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000099 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000100 self.assertEqual(type(i), self.basetype)
Raymond Hettingera690a992003-11-16 16:17:49 +0000101 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Guido van Rossum75a902d2007-10-19 22:06:24 +0000102 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000103 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
104 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
105 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
106 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000107 self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +0000108 s = self.thetype('abcba')
109 z = s.intersection()
110 if self.thetype == frozenset():
111 self.assertEqual(id(s), id(z))
112 else:
113 self.assertNotEqual(id(s), id(z))
Raymond Hettingera690a992003-11-16 16:17:49 +0000114
Guido van Rossum58da9312007-11-10 23:39:45 +0000115 def test_isdisjoint(self):
116 def f(s1, s2):
117 'Pure python equivalent of isdisjoint()'
118 return not set(s1).intersection(s2)
119 for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
120 s1 = self.thetype(larg)
121 for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
122 for C in set, frozenset, dict.fromkeys, str, list, tuple:
123 s2 = C(rarg)
124 actual = s1.isdisjoint(s2)
125 expected = f(s1, s2)
126 self.assertEqual(actual, expected)
127 self.assert_(actual is True or actual is False)
128
Raymond Hettingera690a992003-11-16 16:17:49 +0000129 def test_and(self):
130 i = self.s.intersection(self.otherword)
131 self.assertEqual(self.s & set(self.otherword), i)
132 self.assertEqual(self.s & frozenset(self.otherword), i)
133 try:
134 self.s & self.otherword
135 except TypeError:
136 pass
137 else:
138 self.fail("s&t did not screen-out general iterables")
139
140 def test_difference(self):
141 i = self.s.difference(self.otherword)
142 for c in self.letters:
143 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000144 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000145 self.assertEqual(type(i), self.basetype)
Raymond Hettingera690a992003-11-16 16:17:49 +0000146 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
147 self.assertRaises(TypeError, self.s.difference, [[]])
Guido van Rossum75a902d2007-10-19 22:06:24 +0000148 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000149 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
150 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
151 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
152 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +0000153 self.assertEqual(self.thetype('abcba').difference(), set('abc'))
154 self.assertEqual(self.thetype('abcba').difference(C('a'), C('b')), set('c'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000155
156 def test_sub(self):
157 i = self.s.difference(self.otherword)
158 self.assertEqual(self.s - set(self.otherword), i)
159 self.assertEqual(self.s - frozenset(self.otherword), i)
160 try:
161 self.s - self.otherword
162 except TypeError:
163 pass
164 else:
165 self.fail("s-t did not screen-out general iterables")
166
167 def test_symmetric_difference(self):
168 i = self.s.symmetric_difference(self.otherword)
169 for c in self.letters:
170 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000171 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000172 self.assertEqual(type(i), self.basetype)
Raymond Hettingera690a992003-11-16 16:17:49 +0000173 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
174 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Guido van Rossum75a902d2007-10-19 22:06:24 +0000175 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000176 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
177 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
178 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
179 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000180
181 def test_xor(self):
182 i = self.s.symmetric_difference(self.otherword)
183 self.assertEqual(self.s ^ set(self.otherword), i)
184 self.assertEqual(self.s ^ frozenset(self.otherword), i)
185 try:
186 self.s ^ self.otherword
187 except TypeError:
188 pass
189 else:
190 self.fail("s^t did not screen-out general iterables")
191
192 def test_equality(self):
193 self.assertEqual(self.s, set(self.word))
194 self.assertEqual(self.s, frozenset(self.word))
195 self.assertEqual(self.s == self.word, False)
196 self.assertNotEqual(self.s, set(self.otherword))
197 self.assertNotEqual(self.s, frozenset(self.otherword))
198 self.assertEqual(self.s != self.word, True)
199
200 def test_setOfFrozensets(self):
201 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
202 s = self.thetype(t)
203 self.assertEqual(len(s), 3)
204
Raymond Hettingera690a992003-11-16 16:17:49 +0000205 def test_sub_and_super(self):
206 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
207 self.assert_(p < q)
208 self.assert_(p <= q)
209 self.assert_(q <= q)
210 self.assert_(q > p)
211 self.assert_(q >= p)
212 self.failIf(q < r)
213 self.failIf(q <= r)
214 self.failIf(q > r)
215 self.failIf(q >= r)
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000216 self.assert_(set('a').issubset('abc'))
217 self.assert_(set('abc').issuperset('a'))
218 self.failIf(set('a').issubset('cbs'))
219 self.failIf(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000220
221 def test_pickling(self):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000222 for i in (0, 1, 2):
223 p = pickle.dumps(self.s, i)
224 dup = pickle.loads(p)
225 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
226 if type(self.s) not in (set, frozenset):
227 self.s.x = 10
228 p = pickle.dumps(self.s)
229 dup = pickle.loads(p)
230 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000231
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000232 def test_deepcopy(self):
233 class Tracer:
234 def __init__(self, value):
235 self.value = value
236 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000237 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000238 def __deepcopy__(self, memo=None):
239 return Tracer(self.value + 1)
240 t = Tracer(10)
241 s = self.thetype([t])
242 dup = copy.deepcopy(s)
243 self.assertNotEqual(id(s), id(dup))
244 for elem in dup:
245 newt = elem
246 self.assertNotEqual(id(t), id(newt))
247 self.assertEqual(t.value + 1, newt.value)
248
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000249 def test_gc(self):
250 # Create a nest of cycles to exercise overall ref count check
251 class A:
252 pass
Guido van Rossum805365e2007-05-07 22:24:25 +0000253 s = set(A() for i in range(1000))
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000254 for elem in s:
255 elem.cycle = s
256 elem.sub = elem
257 elem.set = set([elem])
258
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000259 def test_subclass_with_custom_hash(self):
260 # Bug #1257731
261 class H(self.thetype):
262 def __hash__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000263 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000264 s=H()
265 f=set()
266 f.add(s)
267 self.assert_(s in f)
268 f.remove(s)
269 f.add(s)
270 f.discard(s)
271
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000272 def test_badcmp(self):
273 s = self.thetype([BadCmp()])
274 # Detect comparison errors during insertion and lookup
275 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
276 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
277 # Detect errors during mutating operations
278 if hasattr(s, 'add'):
279 self.assertRaises(RuntimeError, s.add, BadCmp())
280 self.assertRaises(RuntimeError, s.discard, BadCmp())
281 self.assertRaises(RuntimeError, s.remove, BadCmp())
282
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000283 def test_cyclical_repr(self):
284 w = ReprWrapper()
285 s = self.thetype([w])
286 w.value = s
287 if self.thetype == set:
288 self.assertEqual(repr(s), '{set(...)}')
289 else:
290 name = repr(s).partition('(')[0] # strip class name
Guido van Rossumbdba5cf2007-08-07 22:44:20 +0000291 self.assertEqual(repr(s), '%s({%s(...)})' % (name, name))
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000292
293 def test_cyclical_print(self):
294 w = ReprWrapper()
295 s = self.thetype([w])
296 w.value = s
Thomas Heller0d755b42008-07-15 17:14:09 +0000297 fo = open(support.TESTFN, "w")
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000298 try:
Guido van Rossumd8c19672007-02-09 21:54:58 +0000299 fo.write(str(s))
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000300 fo.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000301 fo = open(support.TESTFN, "r")
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000302 self.assertEqual(fo.read(), repr(s))
303 finally:
304 fo.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000305 support.unlink(support.TESTFN)
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000306
Thomas Wouterscf297e42007-02-23 15:07:44 +0000307 def test_do_not_rehash_dict_keys(self):
308 n = 10
Guido van Rossum805365e2007-05-07 22:24:25 +0000309 d = dict.fromkeys(map(HashCountingInt, range(n)))
Thomas Wouterscf297e42007-02-23 15:07:44 +0000310 self.assertEqual(sum(elem.hash_count for elem in d), n)
311 s = self.thetype(d)
312 self.assertEqual(sum(elem.hash_count for elem in d), n)
313 s.difference(d)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000314 self.assertEqual(sum(elem.hash_count for elem in d), n)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000315 if hasattr(s, 'symmetric_difference_update'):
316 s.symmetric_difference_update(d)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000317 self.assertEqual(sum(elem.hash_count for elem in d), n)
318 d2 = dict.fromkeys(set(d))
319 self.assertEqual(sum(elem.hash_count for elem in d), n)
320 d3 = dict.fromkeys(frozenset(d))
321 self.assertEqual(sum(elem.hash_count for elem in d), n)
322 d3 = dict.fromkeys(frozenset(d), 123)
323 self.assertEqual(sum(elem.hash_count for elem in d), n)
324 self.assertEqual(d3, dict.fromkeys(d, 123))
Thomas Wouterscf297e42007-02-23 15:07:44 +0000325
Raymond Hettingera690a992003-11-16 16:17:49 +0000326class TestSet(TestJointOps):
327 thetype = set
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000328 basetype = set
Raymond Hettingera690a992003-11-16 16:17:49 +0000329
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000330 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000331 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000332 s.__init__(self.word)
333 self.assertEqual(s, set(self.word))
334 s.__init__(self.otherword)
335 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000336 self.assertRaises(TypeError, s.__init__, s, 2);
337 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000338
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000339 def test_constructor_identity(self):
340 s = self.thetype(range(3))
341 t = self.thetype(s)
342 self.assertNotEqual(id(s), id(t))
343
Guido van Rossum86e58e22006-08-28 15:27:34 +0000344 def test_set_literal(self):
345 s = set([1,2,3])
346 t = {1,2,3}
347 self.assertEqual(s, t)
348
Raymond Hettingera690a992003-11-16 16:17:49 +0000349 def test_hash(self):
350 self.assertRaises(TypeError, hash, self.s)
351
352 def test_clear(self):
353 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000354 self.assertEqual(self.s, set())
355 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000356
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000357 def test_copy(self):
358 dup = self.s.copy()
359 self.assertEqual(self.s, dup)
360 self.assertNotEqual(id(self.s), id(dup))
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000361 self.assertEqual(type(dup), self.basetype)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000362
Raymond Hettingera690a992003-11-16 16:17:49 +0000363 def test_add(self):
364 self.s.add('Q')
365 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000366 dup = self.s.copy()
367 self.s.add('Q')
368 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000369 self.assertRaises(TypeError, self.s.add, [])
370
371 def test_remove(self):
372 self.s.remove('a')
373 self.assert_('a' not in self.s)
374 self.assertRaises(KeyError, self.s.remove, 'Q')
375 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000376 s = self.thetype([frozenset(self.word)])
377 self.assert_(self.thetype(self.word) in s)
378 s.remove(self.thetype(self.word))
379 self.assert_(self.thetype(self.word) not in s)
380 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000381
Thomas Wouters89f507f2006-12-13 04:49:30 +0000382 def test_remove_keyerror_unpacking(self):
383 # bug: www.python.org/sf/1576657
384 for v1 in ['Q', (1,)]:
385 try:
386 self.s.remove(v1)
Guido van Rossumb940e112007-01-10 16:19:56 +0000387 except KeyError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000388 v2 = e.args[0]
389 self.assertEqual(v1, v2)
390 else:
391 self.fail()
392
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000393 def test_remove_keyerror_set(self):
394 key = self.thetype([3, 4])
395 try:
396 self.s.remove(key)
397 except KeyError as e:
398 self.assert_(e.args[0] is key,
399 "KeyError should be {0}, not {1}".format(key,
400 e.args[0]))
401 else:
402 self.fail()
403
Raymond Hettingera690a992003-11-16 16:17:49 +0000404 def test_discard(self):
405 self.s.discard('a')
406 self.assert_('a' not in self.s)
407 self.s.discard('Q')
408 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000409 s = self.thetype([frozenset(self.word)])
410 self.assert_(self.thetype(self.word) in s)
411 s.discard(self.thetype(self.word))
412 self.assert_(self.thetype(self.word) not in s)
413 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000414
415 def test_pop(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000416 for i in range(len(self.s)):
Raymond Hettingera690a992003-11-16 16:17:49 +0000417 elem = self.s.pop()
418 self.assert_(elem not in self.s)
419 self.assertRaises(KeyError, self.s.pop)
420
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000421 def test_update(self):
422 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000423 self.assertEqual(retval, None)
424 for c in (self.word + self.otherword):
425 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000426 self.assertRaises(PassThru, self.s.update, check_pass_thru())
427 self.assertRaises(TypeError, self.s.update, [[]])
428 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000429 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000430 s = self.thetype('abcba')
431 self.assertEqual(s.update(C(p)), None)
432 self.assertEqual(s, set(q))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000433 for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
434 q = 'ahi'
435 for C in set, frozenset, dict.fromkeys, str, list, tuple:
436 s = self.thetype('abcba')
437 self.assertEqual(s.update(C(p), C(q)), None)
438 self.assertEqual(s, set(s) | set(p) | set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000439
440 def test_ior(self):
441 self.s |= set(self.otherword)
442 for c in (self.word + self.otherword):
443 self.assert_(c in self.s)
444
445 def test_intersection_update(self):
446 retval = self.s.intersection_update(self.otherword)
447 self.assertEqual(retval, None)
448 for c in (self.word + self.otherword):
449 if c in self.otherword and c in self.word:
450 self.assert_(c in self.s)
451 else:
452 self.assert_(c not in self.s)
453 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
454 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000455 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000456 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000457 s = self.thetype('abcba')
458 self.assertEqual(s.intersection_update(C(p)), None)
459 self.assertEqual(s, set(q))
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000460 ss = 'abcba'
461 s = self.thetype(ss)
462 t = 'cbc'
463 self.assertEqual(s.intersection_update(C(p), C(t)), None)
464 self.assertEqual(s, set('abcba')&set(p)&set(t))
Raymond Hettingera690a992003-11-16 16:17:49 +0000465
466 def test_iand(self):
467 self.s &= set(self.otherword)
468 for c in (self.word + self.otherword):
469 if c in self.otherword and c in self.word:
470 self.assert_(c in self.s)
471 else:
472 self.assert_(c not in self.s)
473
474 def test_difference_update(self):
475 retval = self.s.difference_update(self.otherword)
476 self.assertEqual(retval, None)
477 for c in (self.word + self.otherword):
478 if c in self.word and c not in self.otherword:
479 self.assert_(c in self.s)
480 else:
481 self.assert_(c not in self.s)
482 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
483 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000484 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
485 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000486 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000487 s = self.thetype('abcba')
488 self.assertEqual(s.difference_update(C(p)), None)
489 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000490
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +0000491 s = self.thetype('abcdefghih')
492 s.difference_update()
493 self.assertEqual(s, self.thetype('abcdefghih'))
494
495 s = self.thetype('abcdefghih')
496 s.difference_update(C('aba'))
497 self.assertEqual(s, self.thetype('cdefghih'))
498
499 s = self.thetype('abcdefghih')
500 s.difference_update(C('cdc'), C('aba'))
501 self.assertEqual(s, self.thetype('efghih'))
502
Raymond Hettingera690a992003-11-16 16:17:49 +0000503 def test_isub(self):
504 self.s -= set(self.otherword)
505 for c in (self.word + self.otherword):
506 if c in self.word and c not in self.otherword:
507 self.assert_(c in self.s)
508 else:
509 self.assert_(c not in self.s)
510
511 def test_symmetric_difference_update(self):
512 retval = self.s.symmetric_difference_update(self.otherword)
513 self.assertEqual(retval, None)
514 for c in (self.word + self.otherword):
515 if (c in self.word) ^ (c in self.otherword):
516 self.assert_(c in self.s)
517 else:
518 self.assert_(c not in self.s)
519 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
520 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000521 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
Guido van Rossum75a902d2007-10-19 22:06:24 +0000522 for C in set, frozenset, dict.fromkeys, str, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000523 s = self.thetype('abcba')
524 self.assertEqual(s.symmetric_difference_update(C(p)), None)
525 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000526
527 def test_ixor(self):
528 self.s ^= set(self.otherword)
529 for c in (self.word + self.otherword):
530 if (c in self.word) ^ (c in self.otherword):
531 self.assert_(c in self.s)
532 else:
533 self.assert_(c not in self.s)
534
Raymond Hettingerc991db22005-08-11 07:58:45 +0000535 def test_inplace_on_self(self):
536 t = self.s.copy()
537 t |= t
538 self.assertEqual(t, self.s)
539 t &= t
540 self.assertEqual(t, self.s)
541 t -= t
542 self.assertEqual(t, self.thetype())
543 t = self.s.copy()
544 t ^= t
545 self.assertEqual(t, self.thetype())
546
Raymond Hettinger691d8052004-05-30 07:26:47 +0000547 def test_weakref(self):
548 s = self.thetype('gallahad')
549 p = proxy(s)
550 self.assertEqual(str(p), str(s))
551 s = None
552 self.assertRaises(ReferenceError, str, p)
553
Guido van Rossum10ab4ae2007-08-23 23:57:24 +0000554 def test_rich_compare(self):
555 class TestRichSetCompare:
556 def __gt__(self, some_set):
557 self.gt_called = True
558 return False
559 def __lt__(self, some_set):
560 self.lt_called = True
561 return False
562 def __ge__(self, some_set):
563 self.ge_called = True
564 return False
565 def __le__(self, some_set):
566 self.le_called = True
567 return False
568
569 # This first tries the bulitin rich set comparison, which doesn't know
570 # how to handle the custom object. Upon returning NotImplemented, the
571 # corresponding comparison on the right object is invoked.
572 myset = {1, 2, 3}
573
574 myobj = TestRichSetCompare()
575 myset < myobj
576 self.assert_(myobj.gt_called)
577
578 myobj = TestRichSetCompare()
579 myset > myobj
580 self.assert_(myobj.lt_called)
581
582 myobj = TestRichSetCompare()
583 myset <= myobj
584 self.assert_(myobj.ge_called)
585
586 myobj = TestRichSetCompare()
587 myset >= myobj
588 self.assert_(myobj.le_called)
589
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000590 # C API test only available in a debug build
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000591 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000592 def test_c_api(self):
593 self.assertEqual(set('abc').test_c_api(), True)
594
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000595class SetSubclass(set):
596 pass
597
598class TestSetSubclass(TestSet):
599 thetype = SetSubclass
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000600 basetype = set
Raymond Hettingera690a992003-11-16 16:17:49 +0000601
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000602class SetSubclassWithKeywordArgs(set):
603 def __init__(self, iterable=[], newarg=None):
604 set.__init__(self, iterable)
605
606class TestSetSubclassWithKeywordArgs(TestSet):
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000607
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000608 def test_keywords_in_subclass(self):
609 'SF bug #1486663 -- this used to erroneously raise a TypeError'
610 SetSubclassWithKeywordArgs(newarg=1)
611
Raymond Hettingera690a992003-11-16 16:17:49 +0000612class TestFrozenSet(TestJointOps):
613 thetype = frozenset
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000614 basetype = frozenset
Raymond Hettingera690a992003-11-16 16:17:49 +0000615
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000616 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000617 s = self.thetype(self.word)
618 s.__init__(self.otherword)
619 self.assertEqual(s, set(self.word))
620
Raymond Hettingerd7946662005-08-01 21:39:29 +0000621 def test_singleton_empty_frozenset(self):
622 f = frozenset()
623 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
624 frozenset(), frozenset([]), frozenset(()), frozenset(''),
Guido van Rossum805365e2007-05-07 22:24:25 +0000625 frozenset(range(0)), frozenset(frozenset()),
Raymond Hettingerd7946662005-08-01 21:39:29 +0000626 frozenset(f), f]
627 # All of the empty frozensets should have just one id()
628 self.assertEqual(len(set(map(id, efs))), 1)
629
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000630 def test_constructor_identity(self):
631 s = self.thetype(range(3))
632 t = self.thetype(s)
633 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000634
Raymond Hettingera690a992003-11-16 16:17:49 +0000635 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000636 self.assertEqual(hash(self.thetype('abcdeb')),
637 hash(self.thetype('ebecda')))
638
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000639 # make sure that all permutations give the same hash value
640 n = 100
Guido van Rossum805365e2007-05-07 22:24:25 +0000641 seq = [randrange(n) for i in range(n)]
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000642 results = set()
Guido van Rossum805365e2007-05-07 22:24:25 +0000643 for i in range(200):
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000644 shuffle(seq)
645 results.add(hash(self.thetype(seq)))
646 self.assertEqual(len(results), 1)
647
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000648 def test_copy(self):
649 dup = self.s.copy()
650 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000651
652 def test_frozen_as_dictkey(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000653 seq = list(range(10)) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000654 key1 = self.thetype(seq)
655 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000656 self.assertEqual(key1, key2)
657 self.assertNotEqual(id(key1), id(key2))
658 d = {}
659 d[key1] = 42
660 self.assertEqual(d[key2], 42)
661
662 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000663 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000664 self.assertEqual(hash(f), hash(f))
665
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000666 def test_hash_effectiveness(self):
667 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000668 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000669 addhashvalue = hashvalues.add
670 elemmasks = [(i+1, 1<<i) for i in range(n)]
Guido van Rossum805365e2007-05-07 22:24:25 +0000671 for i in range(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000672 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
673 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000674
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000675class FrozenSetSubclass(frozenset):
676 pass
677
678class TestFrozenSetSubclass(TestFrozenSet):
679 thetype = FrozenSetSubclass
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000680 basetype = frozenset
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000681
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000682 def test_constructor_identity(self):
683 s = self.thetype(range(3))
684 t = self.thetype(s)
685 self.assertNotEqual(id(s), id(t))
686
687 def test_copy(self):
688 dup = self.s.copy()
689 self.assertNotEqual(id(self.s), id(dup))
690
691 def test_nested_empty_constructor(self):
692 s = self.thetype()
693 t = self.thetype(s)
694 self.assertEqual(s, t)
695
Raymond Hettingerd7946662005-08-01 21:39:29 +0000696 def test_singleton_empty_frozenset(self):
697 Frozenset = self.thetype
698 f = frozenset()
699 F = Frozenset()
700 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
701 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
Guido van Rossum805365e2007-05-07 22:24:25 +0000702 Frozenset(range(0)), Frozenset(Frozenset()),
Raymond Hettingerd7946662005-08-01 21:39:29 +0000703 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
704 # All empty frozenset subclass instances should have different ids
705 self.assertEqual(len(set(map(id, efs))), len(efs))
706
Raymond Hettingera690a992003-11-16 16:17:49 +0000707# Tests taken from test_sets.py =============================================
708
709empty_set = set()
710
711#==============================================================================
712
713class TestBasicOps(unittest.TestCase):
714
715 def test_repr(self):
716 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000717 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000718
Raymond Hettingereae05de2004-07-09 04:51:24 +0000719 def test_print(self):
720 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000721 fo = open(support.TESTFN, "w")
Guido van Rossumd8c19672007-02-09 21:54:58 +0000722 fo.write(str(self.set))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000723 fo.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000724 fo = open(support.TESTFN, "r")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000725 self.assertEqual(fo.read(), repr(self.set))
726 finally:
727 fo.close()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000728 support.unlink(support.TESTFN)
Raymond Hettingereae05de2004-07-09 04:51:24 +0000729
Raymond Hettingera690a992003-11-16 16:17:49 +0000730 def test_length(self):
731 self.assertEqual(len(self.set), self.length)
732
733 def test_self_equality(self):
734 self.assertEqual(self.set, self.set)
735
736 def test_equivalent_equality(self):
737 self.assertEqual(self.set, self.dup)
738
739 def test_copy(self):
740 self.assertEqual(self.set.copy(), self.dup)
741
742 def test_self_union(self):
743 result = self.set | self.set
744 self.assertEqual(result, self.dup)
745
746 def test_empty_union(self):
747 result = self.set | empty_set
748 self.assertEqual(result, self.dup)
749
750 def test_union_empty(self):
751 result = empty_set | self.set
752 self.assertEqual(result, self.dup)
753
754 def test_self_intersection(self):
755 result = self.set & self.set
756 self.assertEqual(result, self.dup)
757
758 def test_empty_intersection(self):
759 result = self.set & empty_set
760 self.assertEqual(result, empty_set)
761
762 def test_intersection_empty(self):
763 result = empty_set & self.set
764 self.assertEqual(result, empty_set)
765
Guido van Rossum58da9312007-11-10 23:39:45 +0000766 def test_self_isdisjoint(self):
767 result = self.set.isdisjoint(self.set)
768 self.assertEqual(result, not self.set)
769
770 def test_empty_isdisjoint(self):
771 result = self.set.isdisjoint(empty_set)
772 self.assertEqual(result, True)
773
774 def test_isdisjoint_empty(self):
775 result = empty_set.isdisjoint(self.set)
776 self.assertEqual(result, True)
777
Raymond Hettingera690a992003-11-16 16:17:49 +0000778 def test_self_symmetric_difference(self):
779 result = self.set ^ self.set
780 self.assertEqual(result, empty_set)
781
782 def checkempty_symmetric_difference(self):
783 result = self.set ^ empty_set
784 self.assertEqual(result, self.set)
785
786 def test_self_difference(self):
787 result = self.set - self.set
788 self.assertEqual(result, empty_set)
789
790 def test_empty_difference(self):
791 result = self.set - empty_set
792 self.assertEqual(result, self.dup)
793
794 def test_empty_difference_rev(self):
795 result = empty_set - self.set
796 self.assertEqual(result, empty_set)
797
798 def test_iteration(self):
799 for v in self.set:
800 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000801 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000802 # note: __length_hint__ is an internal undocumented API,
803 # don't rely on it in your own programs
804 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000805
806 def test_pickling(self):
807 p = pickle.dumps(self.set)
808 copy = pickle.loads(p)
809 self.assertEqual(self.set, copy,
810 "%s != %s" % (self.set, copy))
811
812#------------------------------------------------------------------------------
813
814class TestBasicOpsEmpty(TestBasicOps):
815 def setUp(self):
816 self.case = "empty set"
817 self.values = []
818 self.set = set(self.values)
819 self.dup = set(self.values)
820 self.length = 0
Georg Brandlc4996ba2006-08-28 19:37:11 +0000821 self.repr = "set()"
Raymond Hettingera690a992003-11-16 16:17:49 +0000822
823#------------------------------------------------------------------------------
824
825class TestBasicOpsSingleton(TestBasicOps):
826 def setUp(self):
827 self.case = "unit set (number)"
828 self.values = [3]
829 self.set = set(self.values)
830 self.dup = set(self.values)
831 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000832 self.repr = "{3}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000833
834 def test_in(self):
835 self.failUnless(3 in self.set)
836
837 def test_not_in(self):
838 self.failUnless(2 not in self.set)
839
840#------------------------------------------------------------------------------
841
842class TestBasicOpsTuple(TestBasicOps):
843 def setUp(self):
844 self.case = "unit set (tuple)"
845 self.values = [(0, "zero")]
846 self.set = set(self.values)
847 self.dup = set(self.values)
848 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000849 self.repr = "{(0, 'zero')}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000850
851 def test_in(self):
852 self.failUnless((0, "zero") in self.set)
853
854 def test_not_in(self):
855 self.failUnless(9 not in self.set)
856
857#------------------------------------------------------------------------------
858
859class TestBasicOpsTriple(TestBasicOps):
860 def setUp(self):
861 self.case = "triple set"
862 self.values = [0, "zero", operator.add]
863 self.set = set(self.values)
864 self.dup = set(self.values)
865 self.length = 3
866 self.repr = None
867
Christian Heimes0ded5b52007-12-10 15:50:56 +0000868#------------------------------------------------------------------------------
869
870class TestBasicOpsString(TestBasicOps):
871 def setUp(self):
872 self.case = "string set"
873 self.values = ["a", "b", "c"]
874 self.set = set(self.values)
875 self.dup = set(self.values)
876 self.length = 3
877 self.repr = "{'a', 'c', 'b'}"
878
879#------------------------------------------------------------------------------
880
881class TestBasicOpsBytes(TestBasicOps):
882 def setUp(self):
883 self.case = "string set"
884 self.values = [b"a", b"b", b"c"]
885 self.set = set(self.values)
886 self.dup = set(self.values)
887 self.length = 3
888 self.repr = "{b'a', b'c', b'b'}"
889
890#------------------------------------------------------------------------------
891
892class TestBasicOpsMixedStringBytes(TestBasicOps):
893 def setUp(self):
894 self.warning_filters = warnings.filters[:]
895 warnings.simplefilter('ignore', BytesWarning)
896 self.case = "string and bytes set"
897 self.values = ["a", "b", b"a", b"b"]
898 self.set = set(self.values)
899 self.dup = set(self.values)
900 self.length = 4
901 self.repr = "{'a', b'a', 'b', b'b'}"
902
903 def tearDown(self):
904 warnings.filters = self.warning_filters
905
Raymond Hettingera690a992003-11-16 16:17:49 +0000906#==============================================================================
907
908def baditer():
909 raise TypeError
910 yield True
911
912def gooditer():
913 yield True
914
915class TestExceptionPropagation(unittest.TestCase):
916 """SF 628246: Set constructor should not trap iterator TypeErrors"""
917
918 def test_instanceWithException(self):
919 self.assertRaises(TypeError, set, baditer())
920
921 def test_instancesWithoutException(self):
922 # All of these iterables should load without exception.
923 set([1,2,3])
924 set((1,2,3))
925 set({'one':1, 'two':2, 'three':3})
Guido van Rossum805365e2007-05-07 22:24:25 +0000926 set(range(3))
Raymond Hettingera690a992003-11-16 16:17:49 +0000927 set('abc')
928 set(gooditer())
929
Neal Norwitzfcf44352005-11-27 20:37:43 +0000930 def test_changingSizeWhileIterating(self):
931 s = set([1,2,3])
932 try:
933 for i in s:
934 s.update([4])
935 except RuntimeError:
936 pass
937 else:
938 self.fail("no exception when changing size during iteration")
939
Raymond Hettingera690a992003-11-16 16:17:49 +0000940#==============================================================================
941
942class TestSetOfSets(unittest.TestCase):
943 def test_constructor(self):
944 inner = frozenset([1])
945 outer = set([inner])
946 element = outer.pop()
947 self.assertEqual(type(element), frozenset)
948 outer.add(inner) # Rebuild set of sets with .add method
949 outer.remove(inner)
950 self.assertEqual(outer, set()) # Verify that remove worked
951 outer.discard(inner) # Absence of KeyError indicates working fine
952
953#==============================================================================
954
955class TestBinaryOps(unittest.TestCase):
956 def setUp(self):
957 self.set = set((2, 4, 6))
958
959 def test_eq(self): # SF bug 643115
960 self.assertEqual(self.set, set({2:1,4:3,6:5}))
961
962 def test_union_subset(self):
963 result = self.set | set([2])
964 self.assertEqual(result, set((2, 4, 6)))
965
966 def test_union_superset(self):
967 result = self.set | set([2, 4, 6, 8])
968 self.assertEqual(result, set([2, 4, 6, 8]))
969
970 def test_union_overlap(self):
971 result = self.set | set([3, 4, 5])
972 self.assertEqual(result, set([2, 3, 4, 5, 6]))
973
974 def test_union_non_overlap(self):
975 result = self.set | set([8])
976 self.assertEqual(result, set([2, 4, 6, 8]))
977
978 def test_intersection_subset(self):
979 result = self.set & set((2, 4))
980 self.assertEqual(result, set((2, 4)))
981
982 def test_intersection_superset(self):
983 result = self.set & set([2, 4, 6, 8])
984 self.assertEqual(result, set([2, 4, 6]))
985
986 def test_intersection_overlap(self):
987 result = self.set & set([3, 4, 5])
988 self.assertEqual(result, set([4]))
989
990 def test_intersection_non_overlap(self):
991 result = self.set & set([8])
992 self.assertEqual(result, empty_set)
993
Guido van Rossum58da9312007-11-10 23:39:45 +0000994 def test_isdisjoint_subset(self):
995 result = self.set.isdisjoint(set((2, 4)))
996 self.assertEqual(result, False)
997
998 def test_isdisjoint_superset(self):
999 result = self.set.isdisjoint(set([2, 4, 6, 8]))
1000 self.assertEqual(result, False)
1001
1002 def test_isdisjoint_overlap(self):
1003 result = self.set.isdisjoint(set([3, 4, 5]))
1004 self.assertEqual(result, False)
1005
1006 def test_isdisjoint_non_overlap(self):
1007 result = self.set.isdisjoint(set([8]))
1008 self.assertEqual(result, True)
1009
Raymond Hettingera690a992003-11-16 16:17:49 +00001010 def test_sym_difference_subset(self):
1011 result = self.set ^ set((2, 4))
1012 self.assertEqual(result, set([6]))
1013
1014 def test_sym_difference_superset(self):
1015 result = self.set ^ set((2, 4, 6, 8))
1016 self.assertEqual(result, set([8]))
1017
1018 def test_sym_difference_overlap(self):
1019 result = self.set ^ set((3, 4, 5))
1020 self.assertEqual(result, set([2, 3, 5, 6]))
1021
1022 def test_sym_difference_non_overlap(self):
1023 result = self.set ^ set([8])
1024 self.assertEqual(result, set([2, 4, 6, 8]))
1025
1026 def test_cmp(self):
1027 a, b = set('a'), set('b')
1028 self.assertRaises(TypeError, cmp, a, b)
1029
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001030 # In py3k, this works!
1031 self.assertRaises(TypeError, cmp, a, a)
Raymond Hettingera690a992003-11-16 16:17:49 +00001032
1033 self.assertRaises(TypeError, cmp, a, 12)
1034 self.assertRaises(TypeError, cmp, "abc", a)
1035
1036#==============================================================================
1037
1038class TestUpdateOps(unittest.TestCase):
1039 def setUp(self):
1040 self.set = set((2, 4, 6))
1041
1042 def test_union_subset(self):
1043 self.set |= set([2])
1044 self.assertEqual(self.set, set((2, 4, 6)))
1045
1046 def test_union_superset(self):
1047 self.set |= set([2, 4, 6, 8])
1048 self.assertEqual(self.set, set([2, 4, 6, 8]))
1049
1050 def test_union_overlap(self):
1051 self.set |= set([3, 4, 5])
1052 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1053
1054 def test_union_non_overlap(self):
1055 self.set |= set([8])
1056 self.assertEqual(self.set, set([2, 4, 6, 8]))
1057
1058 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001059 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +00001060 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
1061
1062 def test_intersection_subset(self):
1063 self.set &= set((2, 4))
1064 self.assertEqual(self.set, set((2, 4)))
1065
1066 def test_intersection_superset(self):
1067 self.set &= set([2, 4, 6, 8])
1068 self.assertEqual(self.set, set([2, 4, 6]))
1069
1070 def test_intersection_overlap(self):
1071 self.set &= set([3, 4, 5])
1072 self.assertEqual(self.set, set([4]))
1073
1074 def test_intersection_non_overlap(self):
1075 self.set &= set([8])
1076 self.assertEqual(self.set, empty_set)
1077
1078 def test_intersection_method_call(self):
1079 self.set.intersection_update(set([3, 4, 5]))
1080 self.assertEqual(self.set, set([4]))
1081
1082 def test_sym_difference_subset(self):
1083 self.set ^= set((2, 4))
1084 self.assertEqual(self.set, set([6]))
1085
1086 def test_sym_difference_superset(self):
1087 self.set ^= set((2, 4, 6, 8))
1088 self.assertEqual(self.set, set([8]))
1089
1090 def test_sym_difference_overlap(self):
1091 self.set ^= set((3, 4, 5))
1092 self.assertEqual(self.set, set([2, 3, 5, 6]))
1093
1094 def test_sym_difference_non_overlap(self):
1095 self.set ^= set([8])
1096 self.assertEqual(self.set, set([2, 4, 6, 8]))
1097
1098 def test_sym_difference_method_call(self):
1099 self.set.symmetric_difference_update(set([3, 4, 5]))
1100 self.assertEqual(self.set, set([2, 3, 5, 6]))
1101
1102 def test_difference_subset(self):
1103 self.set -= set((2, 4))
1104 self.assertEqual(self.set, set([6]))
1105
1106 def test_difference_superset(self):
1107 self.set -= set((2, 4, 6, 8))
1108 self.assertEqual(self.set, set([]))
1109
1110 def test_difference_overlap(self):
1111 self.set -= set((3, 4, 5))
1112 self.assertEqual(self.set, set([2, 6]))
1113
1114 def test_difference_non_overlap(self):
1115 self.set -= set([8])
1116 self.assertEqual(self.set, set([2, 4, 6]))
1117
1118 def test_difference_method_call(self):
1119 self.set.difference_update(set([3, 4, 5]))
1120 self.assertEqual(self.set, set([2, 6]))
1121
1122#==============================================================================
1123
1124class TestMutate(unittest.TestCase):
1125 def setUp(self):
1126 self.values = ["a", "b", "c"]
1127 self.set = set(self.values)
1128
1129 def test_add_present(self):
1130 self.set.add("c")
1131 self.assertEqual(self.set, set("abc"))
1132
1133 def test_add_absent(self):
1134 self.set.add("d")
1135 self.assertEqual(self.set, set("abcd"))
1136
1137 def test_add_until_full(self):
1138 tmp = set()
1139 expected_len = 0
1140 for v in self.values:
1141 tmp.add(v)
1142 expected_len += 1
1143 self.assertEqual(len(tmp), expected_len)
1144 self.assertEqual(tmp, self.set)
1145
1146 def test_remove_present(self):
1147 self.set.remove("b")
1148 self.assertEqual(self.set, set("ac"))
1149
1150 def test_remove_absent(self):
1151 try:
1152 self.set.remove("d")
1153 self.fail("Removing missing element should have raised LookupError")
1154 except LookupError:
1155 pass
1156
1157 def test_remove_until_empty(self):
1158 expected_len = len(self.set)
1159 for v in self.values:
1160 self.set.remove(v)
1161 expected_len -= 1
1162 self.assertEqual(len(self.set), expected_len)
1163
1164 def test_discard_present(self):
1165 self.set.discard("c")
1166 self.assertEqual(self.set, set("ab"))
1167
1168 def test_discard_absent(self):
1169 self.set.discard("d")
1170 self.assertEqual(self.set, set("abc"))
1171
1172 def test_clear(self):
1173 self.set.clear()
1174 self.assertEqual(len(self.set), 0)
1175
1176 def test_pop(self):
1177 popped = {}
1178 while self.set:
1179 popped[self.set.pop()] = None
1180 self.assertEqual(len(popped), len(self.values))
1181 for v in self.values:
1182 self.failUnless(v in popped)
1183
1184 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001185 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001186 self.assertEqual(self.set, set(self.values))
1187
1188 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001189 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001190 self.assertEqual(self.set, set(self.values))
1191
1192 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001193 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001194 self.assertEqual(self.set, set(self.values + ["z"]))
1195
1196#==============================================================================
1197
1198class TestSubsets(unittest.TestCase):
1199
1200 case2method = {"<=": "issubset",
1201 ">=": "issuperset",
1202 }
1203
1204 reverse = {"==": "==",
1205 "!=": "!=",
1206 "<": ">",
1207 ">": "<",
1208 "<=": ">=",
1209 ">=": "<=",
1210 }
1211
1212 def test_issubset(self):
1213 x = self.left
1214 y = self.right
1215 for case in "!=", "==", "<", "<=", ">", ">=":
1216 expected = case in self.cases
1217 # Test the binary infix spelling.
1218 result = eval("x" + case + "y", locals())
1219 self.assertEqual(result, expected)
1220 # Test the "friendly" method-name spelling, if one exists.
1221 if case in TestSubsets.case2method:
1222 method = getattr(x, TestSubsets.case2method[case])
1223 result = method(y)
1224 self.assertEqual(result, expected)
1225
1226 # Now do the same for the operands reversed.
1227 rcase = TestSubsets.reverse[case]
1228 result = eval("y" + rcase + "x", locals())
1229 self.assertEqual(result, expected)
1230 if rcase in TestSubsets.case2method:
1231 method = getattr(y, TestSubsets.case2method[rcase])
1232 result = method(x)
1233 self.assertEqual(result, expected)
1234#------------------------------------------------------------------------------
1235
1236class TestSubsetEqualEmpty(TestSubsets):
1237 left = set()
1238 right = set()
1239 name = "both empty"
1240 cases = "==", "<=", ">="
1241
1242#------------------------------------------------------------------------------
1243
1244class TestSubsetEqualNonEmpty(TestSubsets):
1245 left = set([1, 2])
1246 right = set([1, 2])
1247 name = "equal pair"
1248 cases = "==", "<=", ">="
1249
1250#------------------------------------------------------------------------------
1251
1252class TestSubsetEmptyNonEmpty(TestSubsets):
1253 left = set()
1254 right = set([1, 2])
1255 name = "one empty, one non-empty"
1256 cases = "!=", "<", "<="
1257
1258#------------------------------------------------------------------------------
1259
1260class TestSubsetPartial(TestSubsets):
1261 left = set([1])
1262 right = set([1, 2])
1263 name = "one a non-empty proper subset of other"
1264 cases = "!=", "<", "<="
1265
1266#------------------------------------------------------------------------------
1267
1268class TestSubsetNonOverlap(TestSubsets):
1269 left = set([1])
1270 right = set([2])
1271 name = "neither empty, neither contains"
1272 cases = "!="
1273
1274#==============================================================================
1275
1276class TestOnlySetsInBinaryOps(unittest.TestCase):
1277
1278 def test_eq_ne(self):
1279 # Unlike the others, this is testing that == and != *are* allowed.
1280 self.assertEqual(self.other == self.set, False)
1281 self.assertEqual(self.set == self.other, False)
1282 self.assertEqual(self.other != self.set, True)
1283 self.assertEqual(self.set != self.other, True)
1284
1285 def test_ge_gt_le_lt(self):
1286 self.assertRaises(TypeError, lambda: self.set < self.other)
1287 self.assertRaises(TypeError, lambda: self.set <= self.other)
1288 self.assertRaises(TypeError, lambda: self.set > self.other)
1289 self.assertRaises(TypeError, lambda: self.set >= self.other)
1290
1291 self.assertRaises(TypeError, lambda: self.other < self.set)
1292 self.assertRaises(TypeError, lambda: self.other <= self.set)
1293 self.assertRaises(TypeError, lambda: self.other > self.set)
1294 self.assertRaises(TypeError, lambda: self.other >= self.set)
1295
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001296 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001297 try:
1298 self.set |= self.other
1299 except TypeError:
1300 pass
1301 else:
1302 self.fail("expected TypeError")
1303
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001304 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001305 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001306 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001307 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001308 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001309
1310 def test_union(self):
1311 self.assertRaises(TypeError, lambda: self.set | self.other)
1312 self.assertRaises(TypeError, lambda: self.other | self.set)
1313 if self.otherIsIterable:
1314 self.set.union(self.other)
1315 else:
1316 self.assertRaises(TypeError, self.set.union, self.other)
1317
1318 def test_intersection_update_operator(self):
1319 try:
1320 self.set &= self.other
1321 except TypeError:
1322 pass
1323 else:
1324 self.fail("expected TypeError")
1325
1326 def test_intersection_update(self):
1327 if self.otherIsIterable:
1328 self.set.intersection_update(self.other)
1329 else:
1330 self.assertRaises(TypeError,
1331 self.set.intersection_update,
1332 self.other)
1333
1334 def test_intersection(self):
1335 self.assertRaises(TypeError, lambda: self.set & self.other)
1336 self.assertRaises(TypeError, lambda: self.other & self.set)
1337 if self.otherIsIterable:
1338 self.set.intersection(self.other)
1339 else:
1340 self.assertRaises(TypeError, self.set.intersection, self.other)
1341
1342 def test_sym_difference_update_operator(self):
1343 try:
1344 self.set ^= self.other
1345 except TypeError:
1346 pass
1347 else:
1348 self.fail("expected TypeError")
1349
1350 def test_sym_difference_update(self):
1351 if self.otherIsIterable:
1352 self.set.symmetric_difference_update(self.other)
1353 else:
1354 self.assertRaises(TypeError,
1355 self.set.symmetric_difference_update,
1356 self.other)
1357
1358 def test_sym_difference(self):
1359 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1360 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1361 if self.otherIsIterable:
1362 self.set.symmetric_difference(self.other)
1363 else:
1364 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1365
1366 def test_difference_update_operator(self):
1367 try:
1368 self.set -= self.other
1369 except TypeError:
1370 pass
1371 else:
1372 self.fail("expected TypeError")
1373
1374 def test_difference_update(self):
1375 if self.otherIsIterable:
1376 self.set.difference_update(self.other)
1377 else:
1378 self.assertRaises(TypeError,
1379 self.set.difference_update,
1380 self.other)
1381
1382 def test_difference(self):
1383 self.assertRaises(TypeError, lambda: self.set - self.other)
1384 self.assertRaises(TypeError, lambda: self.other - self.set)
1385 if self.otherIsIterable:
1386 self.set.difference(self.other)
1387 else:
1388 self.assertRaises(TypeError, self.set.difference, self.other)
1389
1390#------------------------------------------------------------------------------
1391
1392class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1393 def setUp(self):
1394 self.set = set((1, 2, 3))
1395 self.other = 19
1396 self.otherIsIterable = False
1397
1398#------------------------------------------------------------------------------
1399
1400class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1401 def setUp(self):
1402 self.set = set((1, 2, 3))
1403 self.other = {1:2, 3:4}
1404 self.otherIsIterable = True
1405
1406#------------------------------------------------------------------------------
1407
1408class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1409 def setUp(self):
1410 self.set = set((1, 2, 3))
1411 self.other = operator.add
1412 self.otherIsIterable = False
1413
1414#------------------------------------------------------------------------------
1415
1416class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1417 def setUp(self):
1418 self.set = set((1, 2, 3))
1419 self.other = (2, 4, 6)
1420 self.otherIsIterable = True
1421
1422#------------------------------------------------------------------------------
1423
1424class TestOnlySetsString(TestOnlySetsInBinaryOps):
1425 def setUp(self):
1426 self.set = set((1, 2, 3))
1427 self.other = 'abc'
1428 self.otherIsIterable = True
1429
1430#------------------------------------------------------------------------------
1431
1432class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1433 def setUp(self):
1434 def gen():
Guido van Rossum805365e2007-05-07 22:24:25 +00001435 for i in range(0, 10, 2):
Raymond Hettingera690a992003-11-16 16:17:49 +00001436 yield i
1437 self.set = set((1, 2, 3))
1438 self.other = gen()
1439 self.otherIsIterable = True
1440
1441#==============================================================================
1442
1443class TestCopying(unittest.TestCase):
1444
1445 def test_copy(self):
1446 dup = self.set.copy()
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001447 dup_list = sorted(dup, key=repr)
1448 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001449 self.assertEqual(len(dup_list), len(set_list))
1450 for i in range(len(dup_list)):
1451 self.failUnless(dup_list[i] is set_list[i])
1452
1453 def test_deep_copy(self):
1454 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001455 ##print type(dup), repr(dup)
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001456 dup_list = sorted(dup, key=repr)
1457 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001458 self.assertEqual(len(dup_list), len(set_list))
1459 for i in range(len(dup_list)):
1460 self.assertEqual(dup_list[i], set_list[i])
1461
1462#------------------------------------------------------------------------------
1463
1464class TestCopyingEmpty(TestCopying):
1465 def setUp(self):
1466 self.set = set()
1467
1468#------------------------------------------------------------------------------
1469
1470class TestCopyingSingleton(TestCopying):
1471 def setUp(self):
1472 self.set = set(["hello"])
1473
1474#------------------------------------------------------------------------------
1475
1476class TestCopyingTriple(TestCopying):
1477 def setUp(self):
1478 self.set = set(["zero", 0, None])
1479
1480#------------------------------------------------------------------------------
1481
1482class TestCopyingTuple(TestCopying):
1483 def setUp(self):
1484 self.set = set([(1, 2)])
1485
1486#------------------------------------------------------------------------------
1487
1488class TestCopyingNested(TestCopying):
1489 def setUp(self):
1490 self.set = set([((1, 2), (3, 4))])
1491
1492#==============================================================================
1493
1494class TestIdentities(unittest.TestCase):
1495 def setUp(self):
1496 self.a = set('abracadabra')
1497 self.b = set('alacazam')
1498
1499 def test_binopsVsSubsets(self):
1500 a, b = self.a, self.b
1501 self.assert_(a - b < a)
1502 self.assert_(b - a < b)
1503 self.assert_(a & b < a)
1504 self.assert_(a & b < b)
1505 self.assert_(a | b > a)
1506 self.assert_(a | b > b)
1507 self.assert_(a ^ b < a | b)
1508
1509 def test_commutativity(self):
1510 a, b = self.a, self.b
1511 self.assertEqual(a&b, b&a)
1512 self.assertEqual(a|b, b|a)
1513 self.assertEqual(a^b, b^a)
1514 if a != b:
1515 self.assertNotEqual(a-b, b-a)
1516
1517 def test_summations(self):
1518 # check that sums of parts equal the whole
1519 a, b = self.a, self.b
1520 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1521 self.assertEqual((a&b)|(a^b), a|b)
1522 self.assertEqual(a|(b-a), a|b)
1523 self.assertEqual((a-b)|b, a|b)
1524 self.assertEqual((a-b)|(a&b), a)
1525 self.assertEqual((b-a)|(a&b), b)
1526 self.assertEqual((a-b)|(b-a), a^b)
1527
1528 def test_exclusion(self):
1529 # check that inverse operations show non-overlap
1530 a, b, zero = self.a, self.b, set()
1531 self.assertEqual((a-b)&b, zero)
1532 self.assertEqual((b-a)&a, zero)
1533 self.assertEqual((a&b)&(a^b), zero)
1534
1535# Tests derived from test_itertools.py =======================================
1536
1537def R(seqn):
1538 'Regular generator'
1539 for i in seqn:
1540 yield i
1541
1542class G:
1543 'Sequence using __getitem__'
1544 def __init__(self, seqn):
1545 self.seqn = seqn
1546 def __getitem__(self, i):
1547 return self.seqn[i]
1548
1549class I:
1550 'Sequence using iterator protocol'
1551 def __init__(self, seqn):
1552 self.seqn = seqn
1553 self.i = 0
1554 def __iter__(self):
1555 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001556 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001557 if self.i >= len(self.seqn): raise StopIteration
1558 v = self.seqn[self.i]
1559 self.i += 1
1560 return v
1561
1562class Ig:
1563 'Sequence using iterator protocol defined with a generator'
1564 def __init__(self, seqn):
1565 self.seqn = seqn
1566 self.i = 0
1567 def __iter__(self):
1568 for val in self.seqn:
1569 yield val
1570
1571class X:
1572 'Missing __getitem__ and __iter__'
1573 def __init__(self, seqn):
1574 self.seqn = seqn
1575 self.i = 0
Georg Brandla18af4e2007-04-21 15:47:16 +00001576 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001577 if self.i >= len(self.seqn): raise StopIteration
1578 v = self.seqn[self.i]
1579 self.i += 1
1580 return v
1581
1582class N:
Georg Brandla18af4e2007-04-21 15:47:16 +00001583 'Iterator missing __next__()'
Raymond Hettingera690a992003-11-16 16:17:49 +00001584 def __init__(self, seqn):
1585 self.seqn = seqn
1586 self.i = 0
1587 def __iter__(self):
1588 return self
1589
1590class E:
1591 'Test propagation of exceptions'
1592 def __init__(self, seqn):
1593 self.seqn = seqn
1594 self.i = 0
1595 def __iter__(self):
1596 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001597 def __next__(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001598 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001599
1600class S:
1601 'Test immediate stop'
1602 def __init__(self, seqn):
1603 pass
1604 def __iter__(self):
1605 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001606 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001607 raise StopIteration
1608
Raymond Hettingera6c60372008-03-13 01:26:19 +00001609from itertools import chain
Raymond Hettingera690a992003-11-16 16:17:49 +00001610def L(seqn):
1611 'Test multiple tiers of iterators'
Raymond Hettingera6c60372008-03-13 01:26:19 +00001612 return chain(map(lambda x:x, R(Ig(G(seqn)))))
Raymond Hettingera690a992003-11-16 16:17:49 +00001613
1614class TestVariousIteratorArgs(unittest.TestCase):
1615
1616 def test_constructor(self):
1617 for cons in (set, frozenset):
Guido van Rossum805365e2007-05-07 22:24:25 +00001618 for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
Raymond Hettingera690a992003-11-16 16:17:49 +00001619 for g in (G, I, Ig, S, L, R):
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001620 self.assertEqual(sorted(cons(g(s)), key=repr), sorted(g(s), key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001621 self.assertRaises(TypeError, cons , X(s))
1622 self.assertRaises(TypeError, cons , N(s))
1623 self.assertRaises(ZeroDivisionError, cons , E(s))
1624
1625 def test_inline_methods(self):
1626 s = set('november')
Guido van Rossum805365e2007-05-07 22:24:25 +00001627 for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
Guido van Rossum58da9312007-11-10 23:39:45 +00001628 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001629 for g in (G, I, Ig, L, R):
1630 expected = meth(data)
1631 actual = meth(G(data))
Guido van Rossum58da9312007-11-10 23:39:45 +00001632 if isinstance(expected, bool):
1633 self.assertEqual(actual, expected)
1634 else:
1635 self.assertEqual(sorted(actual, key=repr), sorted(expected, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001636 self.assertRaises(TypeError, meth, X(s))
1637 self.assertRaises(TypeError, meth, N(s))
1638 self.assertRaises(ZeroDivisionError, meth, E(s))
1639
1640 def test_inplace_methods(self):
Guido van Rossum805365e2007-05-07 22:24:25 +00001641 for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001642 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001643 'difference_update', 'symmetric_difference_update'):
1644 for g in (G, I, Ig, S, L, R):
1645 s = set('january')
1646 t = s.copy()
1647 getattr(s, methname)(list(g(data)))
1648 getattr(t, methname)(g(data))
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001649 self.assertEqual(sorted(s, key=repr), sorted(t, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001650
1651 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1652 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1653 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1654
Christian Heimes969fe572008-01-25 11:23:10 +00001655# Application tests (based on David Eppstein's graph recipes ====================================
1656
1657def powerset(U):
1658 """Generates all subsets of a set or sequence U."""
1659 U = iter(U)
1660 try:
1661 x = frozenset([next(U)])
1662 for S in powerset(U):
1663 yield S
1664 yield S | x
1665 except StopIteration:
1666 yield frozenset()
1667
1668def cube(n):
1669 """Graph of n-dimensional hypercube."""
1670 singletons = [frozenset([x]) for x in range(n)]
1671 return dict([(x, frozenset([x^s for s in singletons]))
1672 for x in powerset(range(n))])
1673
1674def linegraph(G):
1675 """Graph, the vertices of which are edges of G,
1676 with two vertices being adjacent iff the corresponding
1677 edges share a vertex."""
1678 L = {}
1679 for x in G:
1680 for y in G[x]:
1681 nx = [frozenset([x,z]) for z in G[x] if z != y]
1682 ny = [frozenset([y,z]) for z in G[y] if z != x]
1683 L[frozenset([x,y])] = frozenset(nx+ny)
1684 return L
1685
1686def faces(G):
1687 'Return a set of faces in G. Where a face is a set of vertices on that face'
1688 # currently limited to triangles,squares, and pentagons
1689 f = set()
1690 for v1, edges in G.items():
1691 for v2 in edges:
1692 for v3 in G[v2]:
1693 if v1 == v3:
1694 continue
1695 if v1 in G[v3]:
1696 f.add(frozenset([v1, v2, v3]))
1697 else:
1698 for v4 in G[v3]:
1699 if v4 == v2:
1700 continue
1701 if v1 in G[v4]:
1702 f.add(frozenset([v1, v2, v3, v4]))
1703 else:
1704 for v5 in G[v4]:
1705 if v5 == v3 or v5 == v2:
1706 continue
1707 if v1 in G[v5]:
1708 f.add(frozenset([v1, v2, v3, v4, v5]))
1709 return f
1710
1711
1712class TestGraphs(unittest.TestCase):
1713
1714 def test_cube(self):
1715
1716 g = cube(3) # vert --> {v1, v2, v3}
1717 vertices1 = set(g)
1718 self.assertEqual(len(vertices1), 8) # eight vertices
1719 for edge in g.values():
1720 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1721 vertices2 = set(v for edges in g.values() for v in edges)
1722 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1723
1724 cubefaces = faces(g)
1725 self.assertEqual(len(cubefaces), 6) # six faces
1726 for face in cubefaces:
1727 self.assertEqual(len(face), 4) # each face is a square
1728
1729 def test_cuboctahedron(self):
1730
1731 # http://en.wikipedia.org/wiki/Cuboctahedron
1732 # 8 triangular faces and 6 square faces
1733 # 12 indentical vertices each connecting a triangle and square
1734
1735 g = cube(3)
1736 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1737 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1738
1739 vertices = set(cuboctahedron)
1740 for edges in cuboctahedron.values():
1741 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1742 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1743 self.assertEqual(vertices, othervertices) # edge vertices in original set
1744
1745 cubofaces = faces(cuboctahedron)
1746 facesizes = collections.defaultdict(int)
1747 for face in cubofaces:
1748 facesizes[len(face)] += 1
1749 self.assertEqual(facesizes[3], 8) # eight triangular faces
1750 self.assertEqual(facesizes[4], 6) # six square faces
1751
1752 for vertex in cuboctahedron:
1753 edge = vertex # Cuboctahedron vertices are edges in Cube
1754 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1755 for cubevert in edge:
1756 self.assert_(cubevert in g)
1757
1758
Raymond Hettingera690a992003-11-16 16:17:49 +00001759#==============================================================================
1760
1761def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001762 test_classes = (
1763 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001764 TestSetSubclass,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001765 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001766 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001767 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001768 TestSetOfSets,
1769 TestExceptionPropagation,
1770 TestBasicOpsEmpty,
1771 TestBasicOpsSingleton,
1772 TestBasicOpsTuple,
1773 TestBasicOpsTriple,
Christian Heimes0ded5b52007-12-10 15:50:56 +00001774 TestBasicOpsString,
1775 TestBasicOpsBytes,
1776 TestBasicOpsMixedStringBytes,
Raymond Hettingera690a992003-11-16 16:17:49 +00001777 TestBinaryOps,
1778 TestUpdateOps,
1779 TestMutate,
1780 TestSubsetEqualEmpty,
1781 TestSubsetEqualNonEmpty,
1782 TestSubsetEmptyNonEmpty,
1783 TestSubsetPartial,
1784 TestSubsetNonOverlap,
1785 TestOnlySetsNumeric,
1786 TestOnlySetsDict,
1787 TestOnlySetsOperator,
1788 TestOnlySetsTuple,
1789 TestOnlySetsString,
1790 TestOnlySetsGenerator,
1791 TestCopyingEmpty,
1792 TestCopyingSingleton,
1793 TestCopyingTriple,
1794 TestCopyingTuple,
1795 TestCopyingNested,
1796 TestIdentities,
1797 TestVariousIteratorArgs,
Christian Heimes969fe572008-01-25 11:23:10 +00001798 TestGraphs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001799 )
1800
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001801 support.run_unittest(*test_classes)
Raymond Hettingera690a992003-11-16 16:17:49 +00001802
1803 # verify reference counting
1804 if verbose and hasattr(sys, "gettotalrefcount"):
1805 import gc
1806 counts = [None] * 5
Guido van Rossum805365e2007-05-07 22:24:25 +00001807 for i in range(len(counts)):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001808 support.run_unittest(*test_classes)
Raymond Hettingera690a992003-11-16 16:17:49 +00001809 gc.collect()
1810 counts[i] = sys.gettotalrefcount()
Guido van Rossumd8c19672007-02-09 21:54:58 +00001811 print(counts)
Raymond Hettingera690a992003-11-16 16:17:49 +00001812
1813if __name__ == "__main__":
1814 test_main(verbose=True)