blob: df72fb2da634c61844c6515b93cf61217d98df93 [file] [log] [blame]
Raymond Hettingera690a992003-11-16 16:17:49 +00001import unittest
2from test import test_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
Raymond Hettingera690a992003-11-16 16:17:49 +000010
11class PassThru(Exception):
12 pass
13
14def check_pass_thru():
15 raise PassThru
16 yield 1
17
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000018class BadCmp:
19 def __hash__(self):
20 return 1
Guido van Rossum47b9ff62006-08-24 00:41:19 +000021 def __eq__(self, other):
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000022 raise RuntimeError
23
Thomas Wouters902d6eb2007-01-09 23:18:33 +000024class ReprWrapper:
25 'Used to test self-referential repr() calls'
26 def __repr__(self):
27 return repr(self.value)
28
Thomas Wouterscf297e42007-02-23 15:07:44 +000029class HashCountingInt(int):
30 'int-like object that counts the number of times __hash__ is called'
31 def __init__(self, *args):
32 self.hash_count = 0
33 def __hash__(self):
34 self.hash_count += 1
35 return int.__hash__(self)
36
Raymond Hettingera690a992003-11-16 16:17:49 +000037class TestJointOps(unittest.TestCase):
38 # Tests common to both set and frozenset
39
40 def setUp(self):
41 self.word = word = 'simsalabim'
42 self.otherword = 'madagascar'
43 self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
44 self.s = self.thetype(word)
45 self.d = dict.fromkeys(word)
46
Raymond Hettinger6429a472004-09-28 01:51:35 +000047 def test_new_or_init(self):
48 self.assertRaises(TypeError, self.thetype, [], 2)
49
Raymond Hettingera690a992003-11-16 16:17:49 +000050 def test_uniquification(self):
Raymond Hettinger64958a12003-12-17 20:43:33 +000051 actual = sorted(self.s)
52 expected = sorted(self.d)
Raymond Hettingera690a992003-11-16 16:17:49 +000053 self.assertEqual(actual, expected)
54 self.assertRaises(PassThru, self.thetype, check_pass_thru())
55 self.assertRaises(TypeError, self.thetype, [[]])
56
57 def test_len(self):
58 self.assertEqual(len(self.s), len(self.d))
59
60 def test_contains(self):
61 for c in self.letters:
62 self.assertEqual(c in self.s, c in self.d)
63 self.assertRaises(TypeError, self.s.__contains__, [[]])
Raymond Hettinger19c2d772003-11-21 18:36:54 +000064 s = self.thetype([frozenset(self.letters)])
65 self.assert_(self.thetype(self.letters) in s)
Raymond Hettingera690a992003-11-16 16:17:49 +000066
Raymond Hettingera690a992003-11-16 16:17:49 +000067 def test_union(self):
68 u = self.s.union(self.otherword)
69 for c in self.letters:
70 self.assertEqual(c in u, c in self.d or c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000071 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000072 self.assertEqual(type(u), self.thetype)
73 self.assertRaises(PassThru, self.s.union, check_pass_thru())
74 self.assertRaises(TypeError, self.s.union, [[]])
Walter Dörwald5de48bd2007-06-11 21:38:39 +000075 for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000076 self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
77 self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
78 self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
79 self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +000080
81 def test_or(self):
82 i = self.s.union(self.otherword)
83 self.assertEqual(self.s | set(self.otherword), i)
84 self.assertEqual(self.s | frozenset(self.otherword), i)
85 try:
86 self.s | self.otherword
87 except TypeError:
88 pass
89 else:
90 self.fail("s|t did not screen-out general iterables")
91
92 def test_intersection(self):
93 i = self.s.intersection(self.otherword)
94 for c in self.letters:
95 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000096 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000097 self.assertEqual(type(i), self.thetype)
98 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Walter Dörwald5de48bd2007-06-11 21:38:39 +000099 for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000100 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
101 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
102 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
103 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Raymond Hettingera690a992003-11-16 16:17:49 +0000104
105 def test_and(self):
106 i = self.s.intersection(self.otherword)
107 self.assertEqual(self.s & set(self.otherword), i)
108 self.assertEqual(self.s & frozenset(self.otherword), i)
109 try:
110 self.s & self.otherword
111 except TypeError:
112 pass
113 else:
114 self.fail("s&t did not screen-out general iterables")
115
116 def test_difference(self):
117 i = self.s.difference(self.otherword)
118 for c in self.letters:
119 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000120 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000121 self.assertEqual(type(i), self.thetype)
122 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
123 self.assertRaises(TypeError, self.s.difference, [[]])
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000124 for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000125 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
126 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
127 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
128 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000129
130 def test_sub(self):
131 i = self.s.difference(self.otherword)
132 self.assertEqual(self.s - set(self.otherword), i)
133 self.assertEqual(self.s - frozenset(self.otherword), i)
134 try:
135 self.s - self.otherword
136 except TypeError:
137 pass
138 else:
139 self.fail("s-t did not screen-out general iterables")
140
141 def test_symmetric_difference(self):
142 i = self.s.symmetric_difference(self.otherword)
143 for c in self.letters:
144 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000145 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000146 self.assertEqual(type(i), self.thetype)
147 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
148 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000149 for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000150 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
151 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
152 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
153 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000154
155 def test_xor(self):
156 i = self.s.symmetric_difference(self.otherword)
157 self.assertEqual(self.s ^ set(self.otherword), i)
158 self.assertEqual(self.s ^ frozenset(self.otherword), i)
159 try:
160 self.s ^ self.otherword
161 except TypeError:
162 pass
163 else:
164 self.fail("s^t did not screen-out general iterables")
165
166 def test_equality(self):
167 self.assertEqual(self.s, set(self.word))
168 self.assertEqual(self.s, frozenset(self.word))
169 self.assertEqual(self.s == self.word, False)
170 self.assertNotEqual(self.s, set(self.otherword))
171 self.assertNotEqual(self.s, frozenset(self.otherword))
172 self.assertEqual(self.s != self.word, True)
173
174 def test_setOfFrozensets(self):
175 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
176 s = self.thetype(t)
177 self.assertEqual(len(s), 3)
178
179 def test_compare(self):
180 self.assertRaises(TypeError, self.s.__cmp__, self.s)
181
182 def test_sub_and_super(self):
183 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
184 self.assert_(p < q)
185 self.assert_(p <= q)
186 self.assert_(q <= q)
187 self.assert_(q > p)
188 self.assert_(q >= p)
189 self.failIf(q < r)
190 self.failIf(q <= r)
191 self.failIf(q > r)
192 self.failIf(q >= r)
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000193 self.assert_(set('a').issubset('abc'))
194 self.assert_(set('abc').issuperset('a'))
195 self.failIf(set('a').issubset('cbs'))
196 self.failIf(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000197
198 def test_pickling(self):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000199 for i in (0, 1, 2):
200 p = pickle.dumps(self.s, i)
201 dup = pickle.loads(p)
202 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
203 if type(self.s) not in (set, frozenset):
204 self.s.x = 10
205 p = pickle.dumps(self.s)
206 dup = pickle.loads(p)
207 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000208
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000209 def test_deepcopy(self):
210 class Tracer:
211 def __init__(self, value):
212 self.value = value
213 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000214 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000215 def __deepcopy__(self, memo=None):
216 return Tracer(self.value + 1)
217 t = Tracer(10)
218 s = self.thetype([t])
219 dup = copy.deepcopy(s)
220 self.assertNotEqual(id(s), id(dup))
221 for elem in dup:
222 newt = elem
223 self.assertNotEqual(id(t), id(newt))
224 self.assertEqual(t.value + 1, newt.value)
225
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000226 def test_gc(self):
227 # Create a nest of cycles to exercise overall ref count check
228 class A:
229 pass
Guido van Rossum805365e2007-05-07 22:24:25 +0000230 s = set(A() for i in range(1000))
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000231 for elem in s:
232 elem.cycle = s
233 elem.sub = elem
234 elem.set = set([elem])
235
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000236 def test_subclass_with_custom_hash(self):
237 # Bug #1257731
238 class H(self.thetype):
239 def __hash__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000240 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000241 s=H()
242 f=set()
243 f.add(s)
244 self.assert_(s in f)
245 f.remove(s)
246 f.add(s)
247 f.discard(s)
248
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000249 def test_badcmp(self):
250 s = self.thetype([BadCmp()])
251 # Detect comparison errors during insertion and lookup
252 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
253 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
254 # Detect errors during mutating operations
255 if hasattr(s, 'add'):
256 self.assertRaises(RuntimeError, s.add, BadCmp())
257 self.assertRaises(RuntimeError, s.discard, BadCmp())
258 self.assertRaises(RuntimeError, s.remove, BadCmp())
259
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000260 def test_cyclical_repr(self):
261 w = ReprWrapper()
262 s = self.thetype([w])
263 w.value = s
264 if self.thetype == set:
265 self.assertEqual(repr(s), '{set(...)}')
266 else:
267 name = repr(s).partition('(')[0] # strip class name
Guido van Rossumbdba5cf2007-08-07 22:44:20 +0000268 self.assertEqual(repr(s), '%s({%s(...)})' % (name, name))
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000269
270 def test_cyclical_print(self):
271 w = ReprWrapper()
272 s = self.thetype([w])
273 w.value = s
274 try:
Guido van Rossum292aa0d2007-05-24 18:00:35 +0000275 fo = open(test_support.TESTFN, "w")
Guido van Rossumd8c19672007-02-09 21:54:58 +0000276 fo.write(str(s))
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000277 fo.close()
Guido van Rossum292aa0d2007-05-24 18:00:35 +0000278 fo = open(test_support.TESTFN, "r")
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000279 self.assertEqual(fo.read(), repr(s))
280 finally:
281 fo.close()
282 os.remove(test_support.TESTFN)
283
Thomas Wouterscf297e42007-02-23 15:07:44 +0000284 def test_do_not_rehash_dict_keys(self):
285 n = 10
Guido van Rossum805365e2007-05-07 22:24:25 +0000286 d = dict.fromkeys(map(HashCountingInt, range(n)))
Thomas Wouterscf297e42007-02-23 15:07:44 +0000287 self.assertEqual(sum(elem.hash_count for elem in d), n)
288 s = self.thetype(d)
289 self.assertEqual(sum(elem.hash_count for elem in d), n)
290 s.difference(d)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000291 self.assertEqual(sum(elem.hash_count for elem in d), n)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000292 if hasattr(s, 'symmetric_difference_update'):
293 s.symmetric_difference_update(d)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000294 self.assertEqual(sum(elem.hash_count for elem in d), n)
295 d2 = dict.fromkeys(set(d))
296 self.assertEqual(sum(elem.hash_count for elem in d), n)
297 d3 = dict.fromkeys(frozenset(d))
298 self.assertEqual(sum(elem.hash_count for elem in d), n)
299 d3 = dict.fromkeys(frozenset(d), 123)
300 self.assertEqual(sum(elem.hash_count for elem in d), n)
301 self.assertEqual(d3, dict.fromkeys(d, 123))
Thomas Wouterscf297e42007-02-23 15:07:44 +0000302
Raymond Hettingera690a992003-11-16 16:17:49 +0000303class TestSet(TestJointOps):
304 thetype = set
305
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000306 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000307 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000308 s.__init__(self.word)
309 self.assertEqual(s, set(self.word))
310 s.__init__(self.otherword)
311 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000312 self.assertRaises(TypeError, s.__init__, s, 2);
313 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000314
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000315 def test_constructor_identity(self):
316 s = self.thetype(range(3))
317 t = self.thetype(s)
318 self.assertNotEqual(id(s), id(t))
319
Guido van Rossum86e58e22006-08-28 15:27:34 +0000320 def test_set_literal(self):
321 s = set([1,2,3])
322 t = {1,2,3}
323 self.assertEqual(s, t)
324
Raymond Hettingera690a992003-11-16 16:17:49 +0000325 def test_hash(self):
326 self.assertRaises(TypeError, hash, self.s)
327
328 def test_clear(self):
329 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000330 self.assertEqual(self.s, set())
331 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000332
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000333 def test_copy(self):
334 dup = self.s.copy()
335 self.assertEqual(self.s, dup)
336 self.assertNotEqual(id(self.s), id(dup))
337
Raymond Hettingera690a992003-11-16 16:17:49 +0000338 def test_add(self):
339 self.s.add('Q')
340 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000341 dup = self.s.copy()
342 self.s.add('Q')
343 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000344 self.assertRaises(TypeError, self.s.add, [])
345
346 def test_remove(self):
347 self.s.remove('a')
348 self.assert_('a' not in self.s)
349 self.assertRaises(KeyError, self.s.remove, 'Q')
350 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000351 s = self.thetype([frozenset(self.word)])
352 self.assert_(self.thetype(self.word) in s)
353 s.remove(self.thetype(self.word))
354 self.assert_(self.thetype(self.word) not in s)
355 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000356
Thomas Wouters89f507f2006-12-13 04:49:30 +0000357 def test_remove_keyerror_unpacking(self):
358 # bug: www.python.org/sf/1576657
359 for v1 in ['Q', (1,)]:
360 try:
361 self.s.remove(v1)
Guido van Rossumb940e112007-01-10 16:19:56 +0000362 except KeyError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000363 v2 = e.args[0]
364 self.assertEqual(v1, v2)
365 else:
366 self.fail()
367
Raymond Hettingera690a992003-11-16 16:17:49 +0000368 def test_discard(self):
369 self.s.discard('a')
370 self.assert_('a' not in self.s)
371 self.s.discard('Q')
372 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000373 s = self.thetype([frozenset(self.word)])
374 self.assert_(self.thetype(self.word) in s)
375 s.discard(self.thetype(self.word))
376 self.assert_(self.thetype(self.word) not in s)
377 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000378
379 def test_pop(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000380 for i in range(len(self.s)):
Raymond Hettingera690a992003-11-16 16:17:49 +0000381 elem = self.s.pop()
382 self.assert_(elem not in self.s)
383 self.assertRaises(KeyError, self.s.pop)
384
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000385 def test_update(self):
386 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000387 self.assertEqual(retval, None)
388 for c in (self.word + self.otherword):
389 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000390 self.assertRaises(PassThru, self.s.update, check_pass_thru())
391 self.assertRaises(TypeError, self.s.update, [[]])
392 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000393 for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000394 s = self.thetype('abcba')
395 self.assertEqual(s.update(C(p)), None)
396 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000397
398 def test_ior(self):
399 self.s |= set(self.otherword)
400 for c in (self.word + self.otherword):
401 self.assert_(c in self.s)
402
403 def test_intersection_update(self):
404 retval = self.s.intersection_update(self.otherword)
405 self.assertEqual(retval, None)
406 for c in (self.word + self.otherword):
407 if c in self.otherword and c in self.word:
408 self.assert_(c in self.s)
409 else:
410 self.assert_(c not in self.s)
411 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
412 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000413 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000414 for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000415 s = self.thetype('abcba')
416 self.assertEqual(s.intersection_update(C(p)), None)
417 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000418
419 def test_iand(self):
420 self.s &= set(self.otherword)
421 for c in (self.word + self.otherword):
422 if c in self.otherword and c in self.word:
423 self.assert_(c in self.s)
424 else:
425 self.assert_(c not in self.s)
426
427 def test_difference_update(self):
428 retval = self.s.difference_update(self.otherword)
429 self.assertEqual(retval, None)
430 for c in (self.word + self.otherword):
431 if c in self.word and c not in self.otherword:
432 self.assert_(c in self.s)
433 else:
434 self.assert_(c not in self.s)
435 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
436 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000437 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
438 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000439 for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000440 s = self.thetype('abcba')
441 self.assertEqual(s.difference_update(C(p)), None)
442 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000443
444 def test_isub(self):
445 self.s -= set(self.otherword)
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
452 def test_symmetric_difference_update(self):
453 retval = self.s.symmetric_difference_update(self.otherword)
454 self.assertEqual(retval, None)
455 for c in (self.word + self.otherword):
456 if (c in self.word) ^ (c in self.otherword):
457 self.assert_(c in self.s)
458 else:
459 self.assert_(c not in self.s)
460 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
461 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000462 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000463 for C in set, frozenset, dict.fromkeys, str, str8, list, tuple:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000464 s = self.thetype('abcba')
465 self.assertEqual(s.symmetric_difference_update(C(p)), None)
466 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000467
468 def test_ixor(self):
469 self.s ^= set(self.otherword)
470 for c in (self.word + self.otherword):
471 if (c in self.word) ^ (c in self.otherword):
472 self.assert_(c in self.s)
473 else:
474 self.assert_(c not in self.s)
475
Raymond Hettingerc991db22005-08-11 07:58:45 +0000476 def test_inplace_on_self(self):
477 t = self.s.copy()
478 t |= t
479 self.assertEqual(t, self.s)
480 t &= t
481 self.assertEqual(t, self.s)
482 t -= t
483 self.assertEqual(t, self.thetype())
484 t = self.s.copy()
485 t ^= t
486 self.assertEqual(t, self.thetype())
487
Raymond Hettinger691d8052004-05-30 07:26:47 +0000488 def test_weakref(self):
489 s = self.thetype('gallahad')
490 p = proxy(s)
491 self.assertEqual(str(p), str(s))
492 s = None
493 self.assertRaises(ReferenceError, str, p)
494
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000495 # C API test only available in a debug build
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000496 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000497 def test_c_api(self):
498 self.assertEqual(set('abc').test_c_api(), True)
499
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000500class SetSubclass(set):
501 pass
502
503class TestSetSubclass(TestSet):
504 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000505
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000506class SetSubclassWithKeywordArgs(set):
507 def __init__(self, iterable=[], newarg=None):
508 set.__init__(self, iterable)
509
510class TestSetSubclassWithKeywordArgs(TestSet):
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000511
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000512 def test_keywords_in_subclass(self):
513 'SF bug #1486663 -- this used to erroneously raise a TypeError'
514 SetSubclassWithKeywordArgs(newarg=1)
515
Raymond Hettingera690a992003-11-16 16:17:49 +0000516class TestFrozenSet(TestJointOps):
517 thetype = frozenset
518
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000519 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000520 s = self.thetype(self.word)
521 s.__init__(self.otherword)
522 self.assertEqual(s, set(self.word))
523
Raymond Hettingerd7946662005-08-01 21:39:29 +0000524 def test_singleton_empty_frozenset(self):
525 f = frozenset()
526 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
527 frozenset(), frozenset([]), frozenset(()), frozenset(''),
Guido van Rossum805365e2007-05-07 22:24:25 +0000528 frozenset(range(0)), frozenset(frozenset()),
Raymond Hettingerd7946662005-08-01 21:39:29 +0000529 frozenset(f), f]
530 # All of the empty frozensets should have just one id()
531 self.assertEqual(len(set(map(id, efs))), 1)
532
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000533 def test_constructor_identity(self):
534 s = self.thetype(range(3))
535 t = self.thetype(s)
536 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000537
Raymond Hettingera690a992003-11-16 16:17:49 +0000538 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000539 self.assertEqual(hash(self.thetype('abcdeb')),
540 hash(self.thetype('ebecda')))
541
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000542 # make sure that all permutations give the same hash value
543 n = 100
Guido van Rossum805365e2007-05-07 22:24:25 +0000544 seq = [randrange(n) for i in range(n)]
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000545 results = set()
Guido van Rossum805365e2007-05-07 22:24:25 +0000546 for i in range(200):
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000547 shuffle(seq)
548 results.add(hash(self.thetype(seq)))
549 self.assertEqual(len(results), 1)
550
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000551 def test_copy(self):
552 dup = self.s.copy()
553 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000554
555 def test_frozen_as_dictkey(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000556 seq = list(range(10)) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000557 key1 = self.thetype(seq)
558 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000559 self.assertEqual(key1, key2)
560 self.assertNotEqual(id(key1), id(key2))
561 d = {}
562 d[key1] = 42
563 self.assertEqual(d[key2], 42)
564
565 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000566 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000567 self.assertEqual(hash(f), hash(f))
568
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000569 def test_hash_effectiveness(self):
570 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000571 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000572 addhashvalue = hashvalues.add
573 elemmasks = [(i+1, 1<<i) for i in range(n)]
Guido van Rossum805365e2007-05-07 22:24:25 +0000574 for i in range(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000575 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
576 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000577
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000578class FrozenSetSubclass(frozenset):
579 pass
580
581class TestFrozenSetSubclass(TestFrozenSet):
582 thetype = FrozenSetSubclass
583
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000584 def test_constructor_identity(self):
585 s = self.thetype(range(3))
586 t = self.thetype(s)
587 self.assertNotEqual(id(s), id(t))
588
589 def test_copy(self):
590 dup = self.s.copy()
591 self.assertNotEqual(id(self.s), id(dup))
592
593 def test_nested_empty_constructor(self):
594 s = self.thetype()
595 t = self.thetype(s)
596 self.assertEqual(s, t)
597
Raymond Hettingerd7946662005-08-01 21:39:29 +0000598 def test_singleton_empty_frozenset(self):
599 Frozenset = self.thetype
600 f = frozenset()
601 F = Frozenset()
602 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
603 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
Guido van Rossum805365e2007-05-07 22:24:25 +0000604 Frozenset(range(0)), Frozenset(Frozenset()),
Raymond Hettingerd7946662005-08-01 21:39:29 +0000605 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
606 # All empty frozenset subclass instances should have different ids
607 self.assertEqual(len(set(map(id, efs))), len(efs))
608
Raymond Hettingera690a992003-11-16 16:17:49 +0000609# Tests taken from test_sets.py =============================================
610
611empty_set = set()
612
613#==============================================================================
614
615class TestBasicOps(unittest.TestCase):
616
617 def test_repr(self):
618 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000619 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000620
Raymond Hettingereae05de2004-07-09 04:51:24 +0000621 def test_print(self):
622 try:
Guido van Rossum292aa0d2007-05-24 18:00:35 +0000623 fo = open(test_support.TESTFN, "w")
Guido van Rossumd8c19672007-02-09 21:54:58 +0000624 fo.write(str(self.set))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000625 fo.close()
Guido van Rossum292aa0d2007-05-24 18:00:35 +0000626 fo = open(test_support.TESTFN, "r")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000627 self.assertEqual(fo.read(), repr(self.set))
628 finally:
629 fo.close()
630 os.remove(test_support.TESTFN)
631
Raymond Hettingera690a992003-11-16 16:17:49 +0000632 def test_length(self):
633 self.assertEqual(len(self.set), self.length)
634
635 def test_self_equality(self):
636 self.assertEqual(self.set, self.set)
637
638 def test_equivalent_equality(self):
639 self.assertEqual(self.set, self.dup)
640
641 def test_copy(self):
642 self.assertEqual(self.set.copy(), self.dup)
643
644 def test_self_union(self):
645 result = self.set | self.set
646 self.assertEqual(result, self.dup)
647
648 def test_empty_union(self):
649 result = self.set | empty_set
650 self.assertEqual(result, self.dup)
651
652 def test_union_empty(self):
653 result = empty_set | self.set
654 self.assertEqual(result, self.dup)
655
656 def test_self_intersection(self):
657 result = self.set & self.set
658 self.assertEqual(result, self.dup)
659
660 def test_empty_intersection(self):
661 result = self.set & empty_set
662 self.assertEqual(result, empty_set)
663
664 def test_intersection_empty(self):
665 result = empty_set & self.set
666 self.assertEqual(result, empty_set)
667
668 def test_self_symmetric_difference(self):
669 result = self.set ^ self.set
670 self.assertEqual(result, empty_set)
671
672 def checkempty_symmetric_difference(self):
673 result = self.set ^ empty_set
674 self.assertEqual(result, self.set)
675
676 def test_self_difference(self):
677 result = self.set - self.set
678 self.assertEqual(result, empty_set)
679
680 def test_empty_difference(self):
681 result = self.set - empty_set
682 self.assertEqual(result, self.dup)
683
684 def test_empty_difference_rev(self):
685 result = empty_set - self.set
686 self.assertEqual(result, empty_set)
687
688 def test_iteration(self):
689 for v in self.set:
690 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000691 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000692 # note: __length_hint__ is an internal undocumented API,
693 # don't rely on it in your own programs
694 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000695
696 def test_pickling(self):
697 p = pickle.dumps(self.set)
698 copy = pickle.loads(p)
699 self.assertEqual(self.set, copy,
700 "%s != %s" % (self.set, copy))
701
702#------------------------------------------------------------------------------
703
704class TestBasicOpsEmpty(TestBasicOps):
705 def setUp(self):
706 self.case = "empty set"
707 self.values = []
708 self.set = set(self.values)
709 self.dup = set(self.values)
710 self.length = 0
Georg Brandlc4996ba2006-08-28 19:37:11 +0000711 self.repr = "set()"
Raymond Hettingera690a992003-11-16 16:17:49 +0000712
713#------------------------------------------------------------------------------
714
715class TestBasicOpsSingleton(TestBasicOps):
716 def setUp(self):
717 self.case = "unit set (number)"
718 self.values = [3]
719 self.set = set(self.values)
720 self.dup = set(self.values)
721 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000722 self.repr = "{3}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000723
724 def test_in(self):
725 self.failUnless(3 in self.set)
726
727 def test_not_in(self):
728 self.failUnless(2 not in self.set)
729
730#------------------------------------------------------------------------------
731
732class TestBasicOpsTuple(TestBasicOps):
733 def setUp(self):
734 self.case = "unit set (tuple)"
735 self.values = [(0, "zero")]
736 self.set = set(self.values)
737 self.dup = set(self.values)
738 self.length = 1
Guido van Rossum86e58e22006-08-28 15:27:34 +0000739 self.repr = "{(0, 'zero')}"
Raymond Hettingera690a992003-11-16 16:17:49 +0000740
741 def test_in(self):
742 self.failUnless((0, "zero") in self.set)
743
744 def test_not_in(self):
745 self.failUnless(9 not in self.set)
746
747#------------------------------------------------------------------------------
748
749class TestBasicOpsTriple(TestBasicOps):
750 def setUp(self):
751 self.case = "triple set"
752 self.values = [0, "zero", operator.add]
753 self.set = set(self.values)
754 self.dup = set(self.values)
755 self.length = 3
756 self.repr = None
757
758#==============================================================================
759
760def baditer():
761 raise TypeError
762 yield True
763
764def gooditer():
765 yield True
766
767class TestExceptionPropagation(unittest.TestCase):
768 """SF 628246: Set constructor should not trap iterator TypeErrors"""
769
770 def test_instanceWithException(self):
771 self.assertRaises(TypeError, set, baditer())
772
773 def test_instancesWithoutException(self):
774 # All of these iterables should load without exception.
775 set([1,2,3])
776 set((1,2,3))
777 set({'one':1, 'two':2, 'three':3})
Guido van Rossum805365e2007-05-07 22:24:25 +0000778 set(range(3))
Raymond Hettingera690a992003-11-16 16:17:49 +0000779 set('abc')
780 set(gooditer())
781
Neal Norwitzfcf44352005-11-27 20:37:43 +0000782 def test_changingSizeWhileIterating(self):
783 s = set([1,2,3])
784 try:
785 for i in s:
786 s.update([4])
787 except RuntimeError:
788 pass
789 else:
790 self.fail("no exception when changing size during iteration")
791
Raymond Hettingera690a992003-11-16 16:17:49 +0000792#==============================================================================
793
794class TestSetOfSets(unittest.TestCase):
795 def test_constructor(self):
796 inner = frozenset([1])
797 outer = set([inner])
798 element = outer.pop()
799 self.assertEqual(type(element), frozenset)
800 outer.add(inner) # Rebuild set of sets with .add method
801 outer.remove(inner)
802 self.assertEqual(outer, set()) # Verify that remove worked
803 outer.discard(inner) # Absence of KeyError indicates working fine
804
805#==============================================================================
806
807class TestBinaryOps(unittest.TestCase):
808 def setUp(self):
809 self.set = set((2, 4, 6))
810
811 def test_eq(self): # SF bug 643115
812 self.assertEqual(self.set, set({2:1,4:3,6:5}))
813
814 def test_union_subset(self):
815 result = self.set | set([2])
816 self.assertEqual(result, set((2, 4, 6)))
817
818 def test_union_superset(self):
819 result = self.set | set([2, 4, 6, 8])
820 self.assertEqual(result, set([2, 4, 6, 8]))
821
822 def test_union_overlap(self):
823 result = self.set | set([3, 4, 5])
824 self.assertEqual(result, set([2, 3, 4, 5, 6]))
825
826 def test_union_non_overlap(self):
827 result = self.set | set([8])
828 self.assertEqual(result, set([2, 4, 6, 8]))
829
830 def test_intersection_subset(self):
831 result = self.set & set((2, 4))
832 self.assertEqual(result, set((2, 4)))
833
834 def test_intersection_superset(self):
835 result = self.set & set([2, 4, 6, 8])
836 self.assertEqual(result, set([2, 4, 6]))
837
838 def test_intersection_overlap(self):
839 result = self.set & set([3, 4, 5])
840 self.assertEqual(result, set([4]))
841
842 def test_intersection_non_overlap(self):
843 result = self.set & set([8])
844 self.assertEqual(result, empty_set)
845
846 def test_sym_difference_subset(self):
847 result = self.set ^ set((2, 4))
848 self.assertEqual(result, set([6]))
849
850 def test_sym_difference_superset(self):
851 result = self.set ^ set((2, 4, 6, 8))
852 self.assertEqual(result, set([8]))
853
854 def test_sym_difference_overlap(self):
855 result = self.set ^ set((3, 4, 5))
856 self.assertEqual(result, set([2, 3, 5, 6]))
857
858 def test_sym_difference_non_overlap(self):
859 result = self.set ^ set([8])
860 self.assertEqual(result, set([2, 4, 6, 8]))
861
862 def test_cmp(self):
863 a, b = set('a'), set('b')
864 self.assertRaises(TypeError, cmp, a, b)
865
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000866 # In py3k, this works!
867 self.assertRaises(TypeError, cmp, a, a)
Raymond Hettingera690a992003-11-16 16:17:49 +0000868
869 self.assertRaises(TypeError, cmp, a, 12)
870 self.assertRaises(TypeError, cmp, "abc", a)
871
872#==============================================================================
873
874class TestUpdateOps(unittest.TestCase):
875 def setUp(self):
876 self.set = set((2, 4, 6))
877
878 def test_union_subset(self):
879 self.set |= set([2])
880 self.assertEqual(self.set, set((2, 4, 6)))
881
882 def test_union_superset(self):
883 self.set |= set([2, 4, 6, 8])
884 self.assertEqual(self.set, set([2, 4, 6, 8]))
885
886 def test_union_overlap(self):
887 self.set |= set([3, 4, 5])
888 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
889
890 def test_union_non_overlap(self):
891 self.set |= set([8])
892 self.assertEqual(self.set, set([2, 4, 6, 8]))
893
894 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000895 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +0000896 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
897
898 def test_intersection_subset(self):
899 self.set &= set((2, 4))
900 self.assertEqual(self.set, set((2, 4)))
901
902 def test_intersection_superset(self):
903 self.set &= set([2, 4, 6, 8])
904 self.assertEqual(self.set, set([2, 4, 6]))
905
906 def test_intersection_overlap(self):
907 self.set &= set([3, 4, 5])
908 self.assertEqual(self.set, set([4]))
909
910 def test_intersection_non_overlap(self):
911 self.set &= set([8])
912 self.assertEqual(self.set, empty_set)
913
914 def test_intersection_method_call(self):
915 self.set.intersection_update(set([3, 4, 5]))
916 self.assertEqual(self.set, set([4]))
917
918 def test_sym_difference_subset(self):
919 self.set ^= set((2, 4))
920 self.assertEqual(self.set, set([6]))
921
922 def test_sym_difference_superset(self):
923 self.set ^= set((2, 4, 6, 8))
924 self.assertEqual(self.set, set([8]))
925
926 def test_sym_difference_overlap(self):
927 self.set ^= set((3, 4, 5))
928 self.assertEqual(self.set, set([2, 3, 5, 6]))
929
930 def test_sym_difference_non_overlap(self):
931 self.set ^= set([8])
932 self.assertEqual(self.set, set([2, 4, 6, 8]))
933
934 def test_sym_difference_method_call(self):
935 self.set.symmetric_difference_update(set([3, 4, 5]))
936 self.assertEqual(self.set, set([2, 3, 5, 6]))
937
938 def test_difference_subset(self):
939 self.set -= set((2, 4))
940 self.assertEqual(self.set, set([6]))
941
942 def test_difference_superset(self):
943 self.set -= set((2, 4, 6, 8))
944 self.assertEqual(self.set, set([]))
945
946 def test_difference_overlap(self):
947 self.set -= set((3, 4, 5))
948 self.assertEqual(self.set, set([2, 6]))
949
950 def test_difference_non_overlap(self):
951 self.set -= set([8])
952 self.assertEqual(self.set, set([2, 4, 6]))
953
954 def test_difference_method_call(self):
955 self.set.difference_update(set([3, 4, 5]))
956 self.assertEqual(self.set, set([2, 6]))
957
958#==============================================================================
959
960class TestMutate(unittest.TestCase):
961 def setUp(self):
962 self.values = ["a", "b", "c"]
963 self.set = set(self.values)
964
965 def test_add_present(self):
966 self.set.add("c")
967 self.assertEqual(self.set, set("abc"))
968
969 def test_add_absent(self):
970 self.set.add("d")
971 self.assertEqual(self.set, set("abcd"))
972
973 def test_add_until_full(self):
974 tmp = set()
975 expected_len = 0
976 for v in self.values:
977 tmp.add(v)
978 expected_len += 1
979 self.assertEqual(len(tmp), expected_len)
980 self.assertEqual(tmp, self.set)
981
982 def test_remove_present(self):
983 self.set.remove("b")
984 self.assertEqual(self.set, set("ac"))
985
986 def test_remove_absent(self):
987 try:
988 self.set.remove("d")
989 self.fail("Removing missing element should have raised LookupError")
990 except LookupError:
991 pass
992
993 def test_remove_until_empty(self):
994 expected_len = len(self.set)
995 for v in self.values:
996 self.set.remove(v)
997 expected_len -= 1
998 self.assertEqual(len(self.set), expected_len)
999
1000 def test_discard_present(self):
1001 self.set.discard("c")
1002 self.assertEqual(self.set, set("ab"))
1003
1004 def test_discard_absent(self):
1005 self.set.discard("d")
1006 self.assertEqual(self.set, set("abc"))
1007
1008 def test_clear(self):
1009 self.set.clear()
1010 self.assertEqual(len(self.set), 0)
1011
1012 def test_pop(self):
1013 popped = {}
1014 while self.set:
1015 popped[self.set.pop()] = None
1016 self.assertEqual(len(popped), len(self.values))
1017 for v in self.values:
1018 self.failUnless(v in popped)
1019
1020 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001021 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001022 self.assertEqual(self.set, set(self.values))
1023
1024 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001025 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001026 self.assertEqual(self.set, set(self.values))
1027
1028 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001029 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001030 self.assertEqual(self.set, set(self.values + ["z"]))
1031
1032#==============================================================================
1033
1034class TestSubsets(unittest.TestCase):
1035
1036 case2method = {"<=": "issubset",
1037 ">=": "issuperset",
1038 }
1039
1040 reverse = {"==": "==",
1041 "!=": "!=",
1042 "<": ">",
1043 ">": "<",
1044 "<=": ">=",
1045 ">=": "<=",
1046 }
1047
1048 def test_issubset(self):
1049 x = self.left
1050 y = self.right
1051 for case in "!=", "==", "<", "<=", ">", ">=":
1052 expected = case in self.cases
1053 # Test the binary infix spelling.
1054 result = eval("x" + case + "y", locals())
1055 self.assertEqual(result, expected)
1056 # Test the "friendly" method-name spelling, if one exists.
1057 if case in TestSubsets.case2method:
1058 method = getattr(x, TestSubsets.case2method[case])
1059 result = method(y)
1060 self.assertEqual(result, expected)
1061
1062 # Now do the same for the operands reversed.
1063 rcase = TestSubsets.reverse[case]
1064 result = eval("y" + rcase + "x", locals())
1065 self.assertEqual(result, expected)
1066 if rcase in TestSubsets.case2method:
1067 method = getattr(y, TestSubsets.case2method[rcase])
1068 result = method(x)
1069 self.assertEqual(result, expected)
1070#------------------------------------------------------------------------------
1071
1072class TestSubsetEqualEmpty(TestSubsets):
1073 left = set()
1074 right = set()
1075 name = "both empty"
1076 cases = "==", "<=", ">="
1077
1078#------------------------------------------------------------------------------
1079
1080class TestSubsetEqualNonEmpty(TestSubsets):
1081 left = set([1, 2])
1082 right = set([1, 2])
1083 name = "equal pair"
1084 cases = "==", "<=", ">="
1085
1086#------------------------------------------------------------------------------
1087
1088class TestSubsetEmptyNonEmpty(TestSubsets):
1089 left = set()
1090 right = set([1, 2])
1091 name = "one empty, one non-empty"
1092 cases = "!=", "<", "<="
1093
1094#------------------------------------------------------------------------------
1095
1096class TestSubsetPartial(TestSubsets):
1097 left = set([1])
1098 right = set([1, 2])
1099 name = "one a non-empty proper subset of other"
1100 cases = "!=", "<", "<="
1101
1102#------------------------------------------------------------------------------
1103
1104class TestSubsetNonOverlap(TestSubsets):
1105 left = set([1])
1106 right = set([2])
1107 name = "neither empty, neither contains"
1108 cases = "!="
1109
1110#==============================================================================
1111
1112class TestOnlySetsInBinaryOps(unittest.TestCase):
1113
1114 def test_eq_ne(self):
1115 # Unlike the others, this is testing that == and != *are* allowed.
1116 self.assertEqual(self.other == self.set, False)
1117 self.assertEqual(self.set == self.other, False)
1118 self.assertEqual(self.other != self.set, True)
1119 self.assertEqual(self.set != self.other, True)
1120
1121 def test_ge_gt_le_lt(self):
1122 self.assertRaises(TypeError, lambda: self.set < self.other)
1123 self.assertRaises(TypeError, lambda: self.set <= self.other)
1124 self.assertRaises(TypeError, lambda: self.set > self.other)
1125 self.assertRaises(TypeError, lambda: self.set >= self.other)
1126
1127 self.assertRaises(TypeError, lambda: self.other < self.set)
1128 self.assertRaises(TypeError, lambda: self.other <= self.set)
1129 self.assertRaises(TypeError, lambda: self.other > self.set)
1130 self.assertRaises(TypeError, lambda: self.other >= self.set)
1131
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001132 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001133 try:
1134 self.set |= self.other
1135 except TypeError:
1136 pass
1137 else:
1138 self.fail("expected TypeError")
1139
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001140 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001141 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001142 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001143 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001144 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001145
1146 def test_union(self):
1147 self.assertRaises(TypeError, lambda: self.set | self.other)
1148 self.assertRaises(TypeError, lambda: self.other | self.set)
1149 if self.otherIsIterable:
1150 self.set.union(self.other)
1151 else:
1152 self.assertRaises(TypeError, self.set.union, self.other)
1153
1154 def test_intersection_update_operator(self):
1155 try:
1156 self.set &= self.other
1157 except TypeError:
1158 pass
1159 else:
1160 self.fail("expected TypeError")
1161
1162 def test_intersection_update(self):
1163 if self.otherIsIterable:
1164 self.set.intersection_update(self.other)
1165 else:
1166 self.assertRaises(TypeError,
1167 self.set.intersection_update,
1168 self.other)
1169
1170 def test_intersection(self):
1171 self.assertRaises(TypeError, lambda: self.set & self.other)
1172 self.assertRaises(TypeError, lambda: self.other & self.set)
1173 if self.otherIsIterable:
1174 self.set.intersection(self.other)
1175 else:
1176 self.assertRaises(TypeError, self.set.intersection, self.other)
1177
1178 def test_sym_difference_update_operator(self):
1179 try:
1180 self.set ^= self.other
1181 except TypeError:
1182 pass
1183 else:
1184 self.fail("expected TypeError")
1185
1186 def test_sym_difference_update(self):
1187 if self.otherIsIterable:
1188 self.set.symmetric_difference_update(self.other)
1189 else:
1190 self.assertRaises(TypeError,
1191 self.set.symmetric_difference_update,
1192 self.other)
1193
1194 def test_sym_difference(self):
1195 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1196 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1197 if self.otherIsIterable:
1198 self.set.symmetric_difference(self.other)
1199 else:
1200 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1201
1202 def test_difference_update_operator(self):
1203 try:
1204 self.set -= self.other
1205 except TypeError:
1206 pass
1207 else:
1208 self.fail("expected TypeError")
1209
1210 def test_difference_update(self):
1211 if self.otherIsIterable:
1212 self.set.difference_update(self.other)
1213 else:
1214 self.assertRaises(TypeError,
1215 self.set.difference_update,
1216 self.other)
1217
1218 def test_difference(self):
1219 self.assertRaises(TypeError, lambda: self.set - self.other)
1220 self.assertRaises(TypeError, lambda: self.other - self.set)
1221 if self.otherIsIterable:
1222 self.set.difference(self.other)
1223 else:
1224 self.assertRaises(TypeError, self.set.difference, self.other)
1225
1226#------------------------------------------------------------------------------
1227
1228class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1229 def setUp(self):
1230 self.set = set((1, 2, 3))
1231 self.other = 19
1232 self.otherIsIterable = False
1233
1234#------------------------------------------------------------------------------
1235
1236class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1237 def setUp(self):
1238 self.set = set((1, 2, 3))
1239 self.other = {1:2, 3:4}
1240 self.otherIsIterable = True
1241
1242#------------------------------------------------------------------------------
1243
1244class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1245 def setUp(self):
1246 self.set = set((1, 2, 3))
1247 self.other = operator.add
1248 self.otherIsIterable = False
1249
1250#------------------------------------------------------------------------------
1251
1252class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1253 def setUp(self):
1254 self.set = set((1, 2, 3))
1255 self.other = (2, 4, 6)
1256 self.otherIsIterable = True
1257
1258#------------------------------------------------------------------------------
1259
1260class TestOnlySetsString(TestOnlySetsInBinaryOps):
1261 def setUp(self):
1262 self.set = set((1, 2, 3))
1263 self.other = 'abc'
1264 self.otherIsIterable = True
1265
1266#------------------------------------------------------------------------------
1267
1268class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1269 def setUp(self):
1270 def gen():
Guido van Rossum805365e2007-05-07 22:24:25 +00001271 for i in range(0, 10, 2):
Raymond Hettingera690a992003-11-16 16:17:49 +00001272 yield i
1273 self.set = set((1, 2, 3))
1274 self.other = gen()
1275 self.otherIsIterable = True
1276
1277#==============================================================================
1278
1279class TestCopying(unittest.TestCase):
1280
1281 def test_copy(self):
1282 dup = self.set.copy()
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001283 dup_list = sorted(dup, key=repr)
1284 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001285 self.assertEqual(len(dup_list), len(set_list))
1286 for i in range(len(dup_list)):
1287 self.failUnless(dup_list[i] is set_list[i])
1288
1289 def test_deep_copy(self):
1290 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001291 ##print type(dup), repr(dup)
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001292 dup_list = sorted(dup, key=repr)
1293 set_list = sorted(self.set, key=repr)
Raymond Hettingera690a992003-11-16 16:17:49 +00001294 self.assertEqual(len(dup_list), len(set_list))
1295 for i in range(len(dup_list)):
1296 self.assertEqual(dup_list[i], set_list[i])
1297
1298#------------------------------------------------------------------------------
1299
1300class TestCopyingEmpty(TestCopying):
1301 def setUp(self):
1302 self.set = set()
1303
1304#------------------------------------------------------------------------------
1305
1306class TestCopyingSingleton(TestCopying):
1307 def setUp(self):
1308 self.set = set(["hello"])
1309
1310#------------------------------------------------------------------------------
1311
1312class TestCopyingTriple(TestCopying):
1313 def setUp(self):
1314 self.set = set(["zero", 0, None])
1315
1316#------------------------------------------------------------------------------
1317
1318class TestCopyingTuple(TestCopying):
1319 def setUp(self):
1320 self.set = set([(1, 2)])
1321
1322#------------------------------------------------------------------------------
1323
1324class TestCopyingNested(TestCopying):
1325 def setUp(self):
1326 self.set = set([((1, 2), (3, 4))])
1327
1328#==============================================================================
1329
1330class TestIdentities(unittest.TestCase):
1331 def setUp(self):
1332 self.a = set('abracadabra')
1333 self.b = set('alacazam')
1334
1335 def test_binopsVsSubsets(self):
1336 a, b = self.a, self.b
1337 self.assert_(a - b < a)
1338 self.assert_(b - a < b)
1339 self.assert_(a & b < a)
1340 self.assert_(a & b < b)
1341 self.assert_(a | b > a)
1342 self.assert_(a | b > b)
1343 self.assert_(a ^ b < a | b)
1344
1345 def test_commutativity(self):
1346 a, b = self.a, self.b
1347 self.assertEqual(a&b, b&a)
1348 self.assertEqual(a|b, b|a)
1349 self.assertEqual(a^b, b^a)
1350 if a != b:
1351 self.assertNotEqual(a-b, b-a)
1352
1353 def test_summations(self):
1354 # check that sums of parts equal the whole
1355 a, b = self.a, self.b
1356 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1357 self.assertEqual((a&b)|(a^b), a|b)
1358 self.assertEqual(a|(b-a), a|b)
1359 self.assertEqual((a-b)|b, a|b)
1360 self.assertEqual((a-b)|(a&b), a)
1361 self.assertEqual((b-a)|(a&b), b)
1362 self.assertEqual((a-b)|(b-a), a^b)
1363
1364 def test_exclusion(self):
1365 # check that inverse operations show non-overlap
1366 a, b, zero = self.a, self.b, set()
1367 self.assertEqual((a-b)&b, zero)
1368 self.assertEqual((b-a)&a, zero)
1369 self.assertEqual((a&b)&(a^b), zero)
1370
1371# Tests derived from test_itertools.py =======================================
1372
1373def R(seqn):
1374 'Regular generator'
1375 for i in seqn:
1376 yield i
1377
1378class G:
1379 'Sequence using __getitem__'
1380 def __init__(self, seqn):
1381 self.seqn = seqn
1382 def __getitem__(self, i):
1383 return self.seqn[i]
1384
1385class I:
1386 'Sequence using iterator protocol'
1387 def __init__(self, seqn):
1388 self.seqn = seqn
1389 self.i = 0
1390 def __iter__(self):
1391 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001392 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001393 if self.i >= len(self.seqn): raise StopIteration
1394 v = self.seqn[self.i]
1395 self.i += 1
1396 return v
1397
1398class Ig:
1399 'Sequence using iterator protocol defined with a generator'
1400 def __init__(self, seqn):
1401 self.seqn = seqn
1402 self.i = 0
1403 def __iter__(self):
1404 for val in self.seqn:
1405 yield val
1406
1407class X:
1408 'Missing __getitem__ and __iter__'
1409 def __init__(self, seqn):
1410 self.seqn = seqn
1411 self.i = 0
Georg Brandla18af4e2007-04-21 15:47:16 +00001412 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001413 if self.i >= len(self.seqn): raise StopIteration
1414 v = self.seqn[self.i]
1415 self.i += 1
1416 return v
1417
1418class N:
Georg Brandla18af4e2007-04-21 15:47:16 +00001419 'Iterator missing __next__()'
Raymond Hettingera690a992003-11-16 16:17:49 +00001420 def __init__(self, seqn):
1421 self.seqn = seqn
1422 self.i = 0
1423 def __iter__(self):
1424 return self
1425
1426class E:
1427 'Test propagation of exceptions'
1428 def __init__(self, seqn):
1429 self.seqn = seqn
1430 self.i = 0
1431 def __iter__(self):
1432 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001433 def __next__(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001434 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001435
1436class S:
1437 'Test immediate stop'
1438 def __init__(self, seqn):
1439 pass
1440 def __iter__(self):
1441 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00001442 def __next__(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001443 raise StopIteration
1444
1445from itertools import chain, imap
1446def L(seqn):
1447 'Test multiple tiers of iterators'
1448 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1449
1450class TestVariousIteratorArgs(unittest.TestCase):
1451
1452 def test_constructor(self):
1453 for cons in (set, frozenset):
Guido van Rossum805365e2007-05-07 22:24:25 +00001454 for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
Raymond Hettingera690a992003-11-16 16:17:49 +00001455 for g in (G, I, Ig, S, L, R):
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001456 self.assertEqual(sorted(cons(g(s)), key=repr), sorted(g(s), key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001457 self.assertRaises(TypeError, cons , X(s))
1458 self.assertRaises(TypeError, cons , N(s))
1459 self.assertRaises(ZeroDivisionError, cons , E(s))
1460
1461 def test_inline_methods(self):
1462 s = set('november')
Guido van Rossum805365e2007-05-07 22:24:25 +00001463 for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
Raymond Hettingera690a992003-11-16 16:17:49 +00001464 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference):
1465 for g in (G, I, Ig, L, R):
1466 expected = meth(data)
1467 actual = meth(G(data))
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001468 self.assertEqual(sorted(actual, key=repr), sorted(expected, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001469 self.assertRaises(TypeError, meth, X(s))
1470 self.assertRaises(TypeError, meth, N(s))
1471 self.assertRaises(ZeroDivisionError, meth, E(s))
1472
1473 def test_inplace_methods(self):
Guido van Rossum805365e2007-05-07 22:24:25 +00001474 for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001475 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001476 'difference_update', 'symmetric_difference_update'):
1477 for g in (G, I, Ig, S, L, R):
1478 s = set('january')
1479 t = s.copy()
1480 getattr(s, methname)(list(g(data)))
1481 getattr(t, methname)(g(data))
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001482 self.assertEqual(sorted(s, key=repr), sorted(t, key=repr))
Raymond Hettingera690a992003-11-16 16:17:49 +00001483
1484 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1485 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1486 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1487
1488#==============================================================================
1489
1490def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001491 test_classes = (
1492 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001493 TestSetSubclass,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001494 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001495 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001496 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001497 TestSetOfSets,
1498 TestExceptionPropagation,
1499 TestBasicOpsEmpty,
1500 TestBasicOpsSingleton,
1501 TestBasicOpsTuple,
1502 TestBasicOpsTriple,
1503 TestBinaryOps,
1504 TestUpdateOps,
1505 TestMutate,
1506 TestSubsetEqualEmpty,
1507 TestSubsetEqualNonEmpty,
1508 TestSubsetEmptyNonEmpty,
1509 TestSubsetPartial,
1510 TestSubsetNonOverlap,
1511 TestOnlySetsNumeric,
1512 TestOnlySetsDict,
1513 TestOnlySetsOperator,
1514 TestOnlySetsTuple,
1515 TestOnlySetsString,
1516 TestOnlySetsGenerator,
1517 TestCopyingEmpty,
1518 TestCopyingSingleton,
1519 TestCopyingTriple,
1520 TestCopyingTuple,
1521 TestCopyingNested,
1522 TestIdentities,
1523 TestVariousIteratorArgs,
1524 )
1525
1526 test_support.run_unittest(*test_classes)
1527
1528 # verify reference counting
1529 if verbose and hasattr(sys, "gettotalrefcount"):
1530 import gc
1531 counts = [None] * 5
Guido van Rossum805365e2007-05-07 22:24:25 +00001532 for i in range(len(counts)):
Raymond Hettingera690a992003-11-16 16:17:49 +00001533 test_support.run_unittest(*test_classes)
1534 gc.collect()
1535 counts[i] = sys.gettotalrefcount()
Guido van Rossumd8c19672007-02-09 21:54:58 +00001536 print(counts)
Raymond Hettingera690a992003-11-16 16:17:49 +00001537
1538if __name__ == "__main__":
1539 test_main(verbose=True)