Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | import unittest |
2 | from test import test_support | |
3 | from weakref import proxy | |
4 | import operator | |
5 | import copy | |
6 | import pickle | |
7 | import os | |
8 | ||
9 | class PassThru(Exception): | |
10 | pass | |
11 | ||
12 | def check_pass_thru(): | |
13 | raise PassThru | |
14 | yield 1 | |
15 | ||
16 | class TestJointOps(unittest.TestCase): | |
17 | # Tests common to both set and frozenset | |
18 | ||
19 | def setUp(self): | |
20 | self.word = word = 'simsalabim' | |
21 | self.otherword = 'madagascar' | |
22 | self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' | |
23 | self.s = self.thetype(word) | |
24 | self.d = dict.fromkeys(word) | |
25 | ||
26 | def test_new_or_init(self): | |
27 | self.assertRaises(TypeError, self.thetype, [], 2) | |
28 | ||
29 | def test_uniquification(self): | |
30 | actual = sorted(self.s) | |
31 | expected = sorted(self.d) | |
32 | self.assertEqual(actual, expected) | |
33 | self.assertRaises(PassThru, self.thetype, check_pass_thru()) | |
34 | self.assertRaises(TypeError, self.thetype, [[]]) | |
35 | ||
36 | def test_len(self): | |
37 | self.assertEqual(len(self.s), len(self.d)) | |
38 | ||
39 | def test_contains(self): | |
40 | for c in self.letters: | |
41 | self.assertEqual(c in self.s, c in self.d) | |
42 | self.assertRaises(TypeError, self.s.__contains__, [[]]) | |
43 | s = self.thetype([frozenset(self.letters)]) | |
44 | self.assert_(self.thetype(self.letters) in s) | |
45 | ||
46 | def test_union(self): | |
47 | u = self.s.union(self.otherword) | |
48 | for c in self.letters: | |
49 | self.assertEqual(c in u, c in self.d or c in self.otherword) | |
50 | self.assertEqual(self.s, self.thetype(self.word)) | |
51 | self.assertEqual(type(u), self.thetype) | |
52 | self.assertRaises(PassThru, self.s.union, check_pass_thru()) | |
53 | self.assertRaises(TypeError, self.s.union, [[]]) | |
54 | for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: | |
55 | self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd')) | |
56 | self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg')) | |
57 | self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc')) | |
58 | self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef')) | |
59 | ||
60 | def test_or(self): | |
61 | i = self.s.union(self.otherword) | |
62 | self.assertEqual(self.s | set(self.otherword), i) | |
63 | self.assertEqual(self.s | frozenset(self.otherword), i) | |
64 | try: | |
65 | self.s | self.otherword | |
66 | except TypeError: | |
67 | pass | |
68 | else: | |
69 | self.fail("s|t did not screen-out general iterables") | |
70 | ||
71 | def test_intersection(self): | |
72 | i = self.s.intersection(self.otherword) | |
73 | for c in self.letters: | |
74 | self.assertEqual(c in i, c in self.d and c in self.otherword) | |
75 | self.assertEqual(self.s, self.thetype(self.word)) | |
76 | self.assertEqual(type(i), self.thetype) | |
77 | self.assertRaises(PassThru, self.s.intersection, check_pass_thru()) | |
78 | for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: | |
79 | self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc')) | |
80 | self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set('')) | |
81 | self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc')) | |
82 | self.assertEqual(self.thetype('abcba').intersection(C('ef')), set('')) | |
83 | ||
84 | def test_and(self): | |
85 | i = self.s.intersection(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_difference(self): | |
96 | i = self.s.difference(self.otherword) | |
97 | for c in self.letters: | |
98 | self.assertEqual(c in i, c in self.d and c not in self.otherword) | |
99 | self.assertEqual(self.s, self.thetype(self.word)) | |
100 | self.assertEqual(type(i), self.thetype) | |
101 | self.assertRaises(PassThru, self.s.difference, check_pass_thru()) | |
102 | self.assertRaises(TypeError, self.s.difference, [[]]) | |
103 | for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: | |
104 | self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab')) | |
105 | self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc')) | |
106 | self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a')) | |
107 | self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc')) | |
108 | ||
109 | def test_sub(self): | |
110 | i = self.s.difference(self.otherword) | |
111 | self.assertEqual(self.s - set(self.otherword), i) | |
112 | self.assertEqual(self.s - frozenset(self.otherword), i) | |
113 | try: | |
114 | self.s - self.otherword | |
115 | except TypeError: | |
116 | pass | |
117 | else: | |
118 | self.fail("s-t did not screen-out general iterables") | |
119 | ||
120 | def test_symmetric_difference(self): | |
121 | i = self.s.symmetric_difference(self.otherword) | |
122 | for c in self.letters: | |
123 | self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword)) | |
124 | self.assertEqual(self.s, self.thetype(self.word)) | |
125 | self.assertEqual(type(i), self.thetype) | |
126 | self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru()) | |
127 | self.assertRaises(TypeError, self.s.symmetric_difference, [[]]) | |
128 | for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: | |
129 | self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd')) | |
130 | self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg')) | |
131 | self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a')) | |
132 | self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef')) | |
133 | ||
134 | def test_xor(self): | |
135 | i = self.s.symmetric_difference(self.otherword) | |
136 | self.assertEqual(self.s ^ set(self.otherword), i) | |
137 | self.assertEqual(self.s ^ frozenset(self.otherword), i) | |
138 | try: | |
139 | self.s ^ self.otherword | |
140 | except TypeError: | |
141 | pass | |
142 | else: | |
143 | self.fail("s^t did not screen-out general iterables") | |
144 | ||
145 | def test_equality(self): | |
146 | self.assertEqual(self.s, set(self.word)) | |
147 | self.assertEqual(self.s, frozenset(self.word)) | |
148 | self.assertEqual(self.s == self.word, False) | |
149 | self.assertNotEqual(self.s, set(self.otherword)) | |
150 | self.assertNotEqual(self.s, frozenset(self.otherword)) | |
151 | self.assertEqual(self.s != self.word, True) | |
152 | ||
153 | def test_setOfFrozensets(self): | |
154 | t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba']) | |
155 | s = self.thetype(t) | |
156 | self.assertEqual(len(s), 3) | |
157 | ||
158 | def test_compare(self): | |
159 | self.assertRaises(TypeError, self.s.__cmp__, self.s) | |
160 | ||
161 | def test_sub_and_super(self): | |
162 | p, q, r = map(self.thetype, ['ab', 'abcde', 'def']) | |
163 | self.assert_(p < q) | |
164 | self.assert_(p <= q) | |
165 | self.assert_(q <= q) | |
166 | self.assert_(q > p) | |
167 | self.assert_(q >= p) | |
168 | self.failIf(q < r) | |
169 | self.failIf(q <= r) | |
170 | self.failIf(q > r) | |
171 | self.failIf(q >= r) | |
172 | self.assert_(set('a').issubset('abc')) | |
173 | self.assert_(set('abc').issuperset('a')) | |
174 | self.failIf(set('a').issubset('cbs')) | |
175 | self.failIf(set('cbs').issuperset('a')) | |
176 | ||
177 | def test_pickling(self): | |
178 | for i in (0, 1, 2): | |
179 | p = pickle.dumps(self.s, i) | |
180 | dup = pickle.loads(p) | |
181 | self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup)) | |
182 | if type(self.s) not in (set, frozenset): | |
183 | self.s.x = 10 | |
184 | p = pickle.dumps(self.s) | |
185 | dup = pickle.loads(p) | |
186 | self.assertEqual(self.s.x, dup.x) | |
187 | ||
188 | def test_deepcopy(self): | |
189 | class Tracer: | |
190 | def __init__(self, value): | |
191 | self.value = value | |
192 | def __hash__(self): | |
193 | return self.value | |
194 | def __deepcopy__(self, memo=None): | |
195 | return Tracer(self.value + 1) | |
196 | t = Tracer(10) | |
197 | s = self.thetype([t]) | |
198 | dup = copy.deepcopy(s) | |
199 | self.assertNotEqual(id(s), id(dup)) | |
200 | for elem in dup: | |
201 | newt = elem | |
202 | self.assertNotEqual(id(t), id(newt)) | |
203 | self.assertEqual(t.value + 1, newt.value) | |
204 | ||
205 | def test_gc(self): | |
206 | # Create a nest of cycles to exercise overall ref count check | |
207 | class A: | |
208 | pass | |
209 | s = set(A() for i in xrange(1000)) | |
210 | for elem in s: | |
211 | elem.cycle = s | |
212 | elem.sub = elem | |
213 | elem.set = set([elem]) | |
214 | ||
215 | def test_subclass_with_custom_hash(self): | |
216 | # Bug #1257731 | |
217 | class H(self.thetype): | |
218 | def __hash__(self): | |
219 | return id(self) | |
220 | s=H() | |
221 | f=set() | |
222 | f.add(s) | |
223 | self.assert_(s in f) | |
224 | f.remove(s) | |
225 | f.add(s) | |
226 | f.discard(s) | |
227 | ||
228 | class TestSet(TestJointOps): | |
229 | thetype = set | |
230 | ||
231 | def test_init(self): | |
232 | s = self.thetype() | |
233 | s.__init__(self.word) | |
234 | self.assertEqual(s, set(self.word)) | |
235 | s.__init__(self.otherword) | |
236 | self.assertEqual(s, set(self.otherword)) | |
237 | self.assertRaises(TypeError, s.__init__, s, 2); | |
238 | self.assertRaises(TypeError, s.__init__, 1); | |
239 | ||
240 | def test_constructor_identity(self): | |
241 | s = self.thetype(range(3)) | |
242 | t = self.thetype(s) | |
243 | self.assertNotEqual(id(s), id(t)) | |
244 | ||
245 | def test_hash(self): | |
246 | self.assertRaises(TypeError, hash, self.s) | |
247 | ||
248 | def test_clear(self): | |
249 | self.s.clear() | |
250 | self.assertEqual(self.s, set()) | |
251 | self.assertEqual(len(self.s), 0) | |
252 | ||
253 | def test_copy(self): | |
254 | dup = self.s.copy() | |
255 | self.assertEqual(self.s, dup) | |
256 | self.assertNotEqual(id(self.s), id(dup)) | |
257 | ||
258 | def test_add(self): | |
259 | self.s.add('Q') | |
260 | self.assert_('Q' in self.s) | |
261 | dup = self.s.copy() | |
262 | self.s.add('Q') | |
263 | self.assertEqual(self.s, dup) | |
264 | self.assertRaises(TypeError, self.s.add, []) | |
265 | ||
266 | def test_remove(self): | |
267 | self.s.remove('a') | |
268 | self.assert_('a' not in self.s) | |
269 | self.assertRaises(KeyError, self.s.remove, 'Q') | |
270 | self.assertRaises(TypeError, self.s.remove, []) | |
271 | s = self.thetype([frozenset(self.word)]) | |
272 | self.assert_(self.thetype(self.word) in s) | |
273 | s.remove(self.thetype(self.word)) | |
274 | self.assert_(self.thetype(self.word) not in s) | |
275 | self.assertRaises(KeyError, self.s.remove, self.thetype(self.word)) | |
276 | ||
277 | def test_discard(self): | |
278 | self.s.discard('a') | |
279 | self.assert_('a' not in self.s) | |
280 | self.s.discard('Q') | |
281 | self.assertRaises(TypeError, self.s.discard, []) | |
282 | s = self.thetype([frozenset(self.word)]) | |
283 | self.assert_(self.thetype(self.word) in s) | |
284 | s.discard(self.thetype(self.word)) | |
285 | self.assert_(self.thetype(self.word) not in s) | |
286 | s.discard(self.thetype(self.word)) | |
287 | ||
288 | def test_pop(self): | |
289 | for i in xrange(len(self.s)): | |
290 | elem = self.s.pop() | |
291 | self.assert_(elem not in self.s) | |
292 | self.assertRaises(KeyError, self.s.pop) | |
293 | ||
294 | def test_update(self): | |
295 | retval = self.s.update(self.otherword) | |
296 | self.assertEqual(retval, None) | |
297 | for c in (self.word + self.otherword): | |
298 | self.assert_(c in self.s) | |
299 | self.assertRaises(PassThru, self.s.update, check_pass_thru()) | |
300 | self.assertRaises(TypeError, self.s.update, [[]]) | |
301 | for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')): | |
302 | for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: | |
303 | s = self.thetype('abcba') | |
304 | self.assertEqual(s.update(C(p)), None) | |
305 | self.assertEqual(s, set(q)) | |
306 | ||
307 | def test_ior(self): | |
308 | self.s |= set(self.otherword) | |
309 | for c in (self.word + self.otherword): | |
310 | self.assert_(c in self.s) | |
311 | ||
312 | def test_intersection_update(self): | |
313 | retval = self.s.intersection_update(self.otherword) | |
314 | self.assertEqual(retval, None) | |
315 | for c in (self.word + self.otherword): | |
316 | if c in self.otherword and c in self.word: | |
317 | self.assert_(c in self.s) | |
318 | else: | |
319 | self.assert_(c not in self.s) | |
320 | self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru()) | |
321 | self.assertRaises(TypeError, self.s.intersection_update, [[]]) | |
322 | for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')): | |
323 | for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: | |
324 | s = self.thetype('abcba') | |
325 | self.assertEqual(s.intersection_update(C(p)), None) | |
326 | self.assertEqual(s, set(q)) | |
327 | ||
328 | def test_iand(self): | |
329 | self.s &= set(self.otherword) | |
330 | for c in (self.word + self.otherword): | |
331 | if c in self.otherword and c in self.word: | |
332 | self.assert_(c in self.s) | |
333 | else: | |
334 | self.assert_(c not in self.s) | |
335 | ||
336 | def test_difference_update(self): | |
337 | retval = self.s.difference_update(self.otherword) | |
338 | self.assertEqual(retval, None) | |
339 | for c in (self.word + self.otherword): | |
340 | if c in self.word and c not in self.otherword: | |
341 | self.assert_(c in self.s) | |
342 | else: | |
343 | self.assert_(c not in self.s) | |
344 | self.assertRaises(PassThru, self.s.difference_update, check_pass_thru()) | |
345 | self.assertRaises(TypeError, self.s.difference_update, [[]]) | |
346 | self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]]) | |
347 | for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')): | |
348 | for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: | |
349 | s = self.thetype('abcba') | |
350 | self.assertEqual(s.difference_update(C(p)), None) | |
351 | self.assertEqual(s, set(q)) | |
352 | ||
353 | def test_isub(self): | |
354 | self.s -= set(self.otherword) | |
355 | for c in (self.word + self.otherword): | |
356 | if c in self.word and c not in self.otherword: | |
357 | self.assert_(c in self.s) | |
358 | else: | |
359 | self.assert_(c not in self.s) | |
360 | ||
361 | def test_symmetric_difference_update(self): | |
362 | retval = self.s.symmetric_difference_update(self.otherword) | |
363 | self.assertEqual(retval, None) | |
364 | for c in (self.word + self.otherword): | |
365 | if (c in self.word) ^ (c in self.otherword): | |
366 | self.assert_(c in self.s) | |
367 | else: | |
368 | self.assert_(c not in self.s) | |
369 | self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru()) | |
370 | self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]]) | |
371 | for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')): | |
372 | for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: | |
373 | s = self.thetype('abcba') | |
374 | self.assertEqual(s.symmetric_difference_update(C(p)), None) | |
375 | self.assertEqual(s, set(q)) | |
376 | ||
377 | def test_ixor(self): | |
378 | self.s ^= set(self.otherword) | |
379 | for c in (self.word + self.otherword): | |
380 | if (c in self.word) ^ (c in self.otherword): | |
381 | self.assert_(c in self.s) | |
382 | else: | |
383 | self.assert_(c not in self.s) | |
384 | ||
385 | def test_inplace_on_self(self): | |
386 | t = self.s.copy() | |
387 | t |= t | |
388 | self.assertEqual(t, self.s) | |
389 | t &= t | |
390 | self.assertEqual(t, self.s) | |
391 | t -= t | |
392 | self.assertEqual(t, self.thetype()) | |
393 | t = self.s.copy() | |
394 | t ^= t | |
395 | self.assertEqual(t, self.thetype()) | |
396 | ||
397 | def test_weakref(self): | |
398 | s = self.thetype('gallahad') | |
399 | p = proxy(s) | |
400 | self.assertEqual(str(p), str(s)) | |
401 | s = None | |
402 | self.assertRaises(ReferenceError, str, p) | |
403 | ||
404 | class SetSubclass(set): | |
405 | pass | |
406 | ||
407 | class TestSetSubclass(TestSet): | |
408 | thetype = SetSubclass | |
409 | ||
410 | class TestFrozenSet(TestJointOps): | |
411 | thetype = frozenset | |
412 | ||
413 | def test_init(self): | |
414 | s = self.thetype(self.word) | |
415 | s.__init__(self.otherword) | |
416 | self.assertEqual(s, set(self.word)) | |
417 | ||
418 | def test_constructor_identity(self): | |
419 | s = self.thetype(range(3)) | |
420 | t = self.thetype(s) | |
421 | self.assertEqual(id(s), id(t)) | |
422 | ||
423 | def test_hash(self): | |
424 | self.assertEqual(hash(self.thetype('abcdeb')), | |
425 | hash(self.thetype('ebecda'))) | |
426 | ||
427 | def test_copy(self): | |
428 | dup = self.s.copy() | |
429 | self.assertEqual(id(self.s), id(dup)) | |
430 | ||
431 | def test_frozen_as_dictkey(self): | |
432 | seq = range(10) + list('abcdefg') + ['apple'] | |
433 | key1 = self.thetype(seq) | |
434 | key2 = self.thetype(reversed(seq)) | |
435 | self.assertEqual(key1, key2) | |
436 | self.assertNotEqual(id(key1), id(key2)) | |
437 | d = {} | |
438 | d[key1] = 42 | |
439 | self.assertEqual(d[key2], 42) | |
440 | ||
441 | def test_hash_caching(self): | |
442 | f = self.thetype('abcdcda') | |
443 | self.assertEqual(hash(f), hash(f)) | |
444 | ||
445 | def test_hash_effectiveness(self): | |
446 | n = 13 | |
447 | hashvalues = set() | |
448 | addhashvalue = hashvalues.add | |
449 | elemmasks = [(i+1, 1<<i) for i in range(n)] | |
450 | for i in xrange(2**n): | |
451 | addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i]))) | |
452 | self.assertEqual(len(hashvalues), 2**n) | |
453 | ||
454 | class FrozenSetSubclass(frozenset): | |
455 | pass | |
456 | ||
457 | class TestFrozenSetSubclass(TestFrozenSet): | |
458 | thetype = FrozenSetSubclass | |
459 | ||
460 | def test_constructor_identity(self): | |
461 | s = self.thetype(range(3)) | |
462 | t = self.thetype(s) | |
463 | self.assertNotEqual(id(s), id(t)) | |
464 | ||
465 | def test_copy(self): | |
466 | dup = self.s.copy() | |
467 | self.assertNotEqual(id(self.s), id(dup)) | |
468 | ||
469 | def test_nested_empty_constructor(self): | |
470 | s = self.thetype() | |
471 | t = self.thetype(s) | |
472 | self.assertEqual(s, t) | |
473 | ||
474 | # Tests taken from test_sets.py ============================================= | |
475 | ||
476 | empty_set = set() | |
477 | ||
478 | #============================================================================== | |
479 | ||
480 | class TestBasicOps(unittest.TestCase): | |
481 | ||
482 | def test_repr(self): | |
483 | if self.repr is not None: | |
484 | self.assertEqual(repr(self.set), self.repr) | |
485 | ||
486 | def test_print(self): | |
487 | try: | |
488 | fo = open(test_support.TESTFN, "wb") | |
489 | print >> fo, self.set, | |
490 | fo.close() | |
491 | fo = open(test_support.TESTFN, "rb") | |
492 | self.assertEqual(fo.read(), repr(self.set)) | |
493 | finally: | |
494 | fo.close() | |
495 | os.remove(test_support.TESTFN) | |
496 | ||
497 | def test_length(self): | |
498 | self.assertEqual(len(self.set), self.length) | |
499 | ||
500 | def test_self_equality(self): | |
501 | self.assertEqual(self.set, self.set) | |
502 | ||
503 | def test_equivalent_equality(self): | |
504 | self.assertEqual(self.set, self.dup) | |
505 | ||
506 | def test_copy(self): | |
507 | self.assertEqual(self.set.copy(), self.dup) | |
508 | ||
509 | def test_self_union(self): | |
510 | result = self.set | self.set | |
511 | self.assertEqual(result, self.dup) | |
512 | ||
513 | def test_empty_union(self): | |
514 | result = self.set | empty_set | |
515 | self.assertEqual(result, self.dup) | |
516 | ||
517 | def test_union_empty(self): | |
518 | result = empty_set | self.set | |
519 | self.assertEqual(result, self.dup) | |
520 | ||
521 | def test_self_intersection(self): | |
522 | result = self.set & self.set | |
523 | self.assertEqual(result, self.dup) | |
524 | ||
525 | def test_empty_intersection(self): | |
526 | result = self.set & empty_set | |
527 | self.assertEqual(result, empty_set) | |
528 | ||
529 | def test_intersection_empty(self): | |
530 | result = empty_set & self.set | |
531 | self.assertEqual(result, empty_set) | |
532 | ||
533 | def test_self_symmetric_difference(self): | |
534 | result = self.set ^ self.set | |
535 | self.assertEqual(result, empty_set) | |
536 | ||
537 | def checkempty_symmetric_difference(self): | |
538 | result = self.set ^ empty_set | |
539 | self.assertEqual(result, self.set) | |
540 | ||
541 | def test_self_difference(self): | |
542 | result = self.set - self.set | |
543 | self.assertEqual(result, empty_set) | |
544 | ||
545 | def test_empty_difference(self): | |
546 | result = self.set - empty_set | |
547 | self.assertEqual(result, self.dup) | |
548 | ||
549 | def test_empty_difference_rev(self): | |
550 | result = empty_set - self.set | |
551 | self.assertEqual(result, empty_set) | |
552 | ||
553 | def test_iteration(self): | |
554 | for v in self.set: | |
555 | self.assert_(v in self.values) | |
556 | ||
557 | def test_pickling(self): | |
558 | p = pickle.dumps(self.set) | |
559 | copy = pickle.loads(p) | |
560 | self.assertEqual(self.set, copy, | |
561 | "%s != %s" % (self.set, copy)) | |
562 | ||
563 | #------------------------------------------------------------------------------ | |
564 | ||
565 | class TestBasicOpsEmpty(TestBasicOps): | |
566 | def setUp(self): | |
567 | self.case = "empty set" | |
568 | self.values = [] | |
569 | self.set = set(self.values) | |
570 | self.dup = set(self.values) | |
571 | self.length = 0 | |
572 | self.repr = "set([])" | |
573 | ||
574 | #------------------------------------------------------------------------------ | |
575 | ||
576 | class TestBasicOpsSingleton(TestBasicOps): | |
577 | def setUp(self): | |
578 | self.case = "unit set (number)" | |
579 | self.values = [3] | |
580 | self.set = set(self.values) | |
581 | self.dup = set(self.values) | |
582 | self.length = 1 | |
583 | self.repr = "set([3])" | |
584 | ||
585 | def test_in(self): | |
586 | self.failUnless(3 in self.set) | |
587 | ||
588 | def test_not_in(self): | |
589 | self.failUnless(2 not in self.set) | |
590 | ||
591 | #------------------------------------------------------------------------------ | |
592 | ||
593 | class TestBasicOpsTuple(TestBasicOps): | |
594 | def setUp(self): | |
595 | self.case = "unit set (tuple)" | |
596 | self.values = [(0, "zero")] | |
597 | self.set = set(self.values) | |
598 | self.dup = set(self.values) | |
599 | self.length = 1 | |
600 | self.repr = "set([(0, 'zero')])" | |
601 | ||
602 | def test_in(self): | |
603 | self.failUnless((0, "zero") in self.set) | |
604 | ||
605 | def test_not_in(self): | |
606 | self.failUnless(9 not in self.set) | |
607 | ||
608 | #------------------------------------------------------------------------------ | |
609 | ||
610 | class TestBasicOpsTriple(TestBasicOps): | |
611 | def setUp(self): | |
612 | self.case = "triple set" | |
613 | self.values = [0, "zero", operator.add] | |
614 | self.set = set(self.values) | |
615 | self.dup = set(self.values) | |
616 | self.length = 3 | |
617 | self.repr = None | |
618 | ||
619 | #============================================================================== | |
620 | ||
621 | def baditer(): | |
622 | raise TypeError | |
623 | yield True | |
624 | ||
625 | def gooditer(): | |
626 | yield True | |
627 | ||
628 | class TestExceptionPropagation(unittest.TestCase): | |
629 | """SF 628246: Set constructor should not trap iterator TypeErrors""" | |
630 | ||
631 | def test_instanceWithException(self): | |
632 | self.assertRaises(TypeError, set, baditer()) | |
633 | ||
634 | def test_instancesWithoutException(self): | |
635 | # All of these iterables should load without exception. | |
636 | set([1,2,3]) | |
637 | set((1,2,3)) | |
638 | set({'one':1, 'two':2, 'three':3}) | |
639 | set(xrange(3)) | |
640 | set('abc') | |
641 | set(gooditer()) | |
642 | ||
643 | #============================================================================== | |
644 | ||
645 | class TestSetOfSets(unittest.TestCase): | |
646 | def test_constructor(self): | |
647 | inner = frozenset([1]) | |
648 | outer = set([inner]) | |
649 | element = outer.pop() | |
650 | self.assertEqual(type(element), frozenset) | |
651 | outer.add(inner) # Rebuild set of sets with .add method | |
652 | outer.remove(inner) | |
653 | self.assertEqual(outer, set()) # Verify that remove worked | |
654 | outer.discard(inner) # Absence of KeyError indicates working fine | |
655 | ||
656 | #============================================================================== | |
657 | ||
658 | class TestBinaryOps(unittest.TestCase): | |
659 | def setUp(self): | |
660 | self.set = set((2, 4, 6)) | |
661 | ||
662 | def test_eq(self): # SF bug 643115 | |
663 | self.assertEqual(self.set, set({2:1,4:3,6:5})) | |
664 | ||
665 | def test_union_subset(self): | |
666 | result = self.set | set([2]) | |
667 | self.assertEqual(result, set((2, 4, 6))) | |
668 | ||
669 | def test_union_superset(self): | |
670 | result = self.set | set([2, 4, 6, 8]) | |
671 | self.assertEqual(result, set([2, 4, 6, 8])) | |
672 | ||
673 | def test_union_overlap(self): | |
674 | result = self.set | set([3, 4, 5]) | |
675 | self.assertEqual(result, set([2, 3, 4, 5, 6])) | |
676 | ||
677 | def test_union_non_overlap(self): | |
678 | result = self.set | set([8]) | |
679 | self.assertEqual(result, set([2, 4, 6, 8])) | |
680 | ||
681 | def test_intersection_subset(self): | |
682 | result = self.set & set((2, 4)) | |
683 | self.assertEqual(result, set((2, 4))) | |
684 | ||
685 | def test_intersection_superset(self): | |
686 | result = self.set & set([2, 4, 6, 8]) | |
687 | self.assertEqual(result, set([2, 4, 6])) | |
688 | ||
689 | def test_intersection_overlap(self): | |
690 | result = self.set & set([3, 4, 5]) | |
691 | self.assertEqual(result, set([4])) | |
692 | ||
693 | def test_intersection_non_overlap(self): | |
694 | result = self.set & set([8]) | |
695 | self.assertEqual(result, empty_set) | |
696 | ||
697 | def test_sym_difference_subset(self): | |
698 | result = self.set ^ set((2, 4)) | |
699 | self.assertEqual(result, set([6])) | |
700 | ||
701 | def test_sym_difference_superset(self): | |
702 | result = self.set ^ set((2, 4, 6, 8)) | |
703 | self.assertEqual(result, set([8])) | |
704 | ||
705 | def test_sym_difference_overlap(self): | |
706 | result = self.set ^ set((3, 4, 5)) | |
707 | self.assertEqual(result, set([2, 3, 5, 6])) | |
708 | ||
709 | def test_sym_difference_non_overlap(self): | |
710 | result = self.set ^ set([8]) | |
711 | self.assertEqual(result, set([2, 4, 6, 8])) | |
712 | ||
713 | def test_cmp(self): | |
714 | a, b = set('a'), set('b') | |
715 | self.assertRaises(TypeError, cmp, a, b) | |
716 | ||
717 | # You can view this as a buglet: cmp(a, a) does not raise TypeError, | |
718 | # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True, | |
719 | # which Python thinks is good enough to synthesize a cmp() result | |
720 | # without calling __cmp__. | |
721 | self.assertEqual(cmp(a, a), 0) | |
722 | ||
723 | self.assertRaises(TypeError, cmp, a, 12) | |
724 | self.assertRaises(TypeError, cmp, "abc", a) | |
725 | ||
726 | #============================================================================== | |
727 | ||
728 | class TestUpdateOps(unittest.TestCase): | |
729 | def setUp(self): | |
730 | self.set = set((2, 4, 6)) | |
731 | ||
732 | def test_union_subset(self): | |
733 | self.set |= set([2]) | |
734 | self.assertEqual(self.set, set((2, 4, 6))) | |
735 | ||
736 | def test_union_superset(self): | |
737 | self.set |= set([2, 4, 6, 8]) | |
738 | self.assertEqual(self.set, set([2, 4, 6, 8])) | |
739 | ||
740 | def test_union_overlap(self): | |
741 | self.set |= set([3, 4, 5]) | |
742 | self.assertEqual(self.set, set([2, 3, 4, 5, 6])) | |
743 | ||
744 | def test_union_non_overlap(self): | |
745 | self.set |= set([8]) | |
746 | self.assertEqual(self.set, set([2, 4, 6, 8])) | |
747 | ||
748 | def test_union_method_call(self): | |
749 | self.set.update(set([3, 4, 5])) | |
750 | self.assertEqual(self.set, set([2, 3, 4, 5, 6])) | |
751 | ||
752 | def test_intersection_subset(self): | |
753 | self.set &= set((2, 4)) | |
754 | self.assertEqual(self.set, set((2, 4))) | |
755 | ||
756 | def test_intersection_superset(self): | |
757 | self.set &= set([2, 4, 6, 8]) | |
758 | self.assertEqual(self.set, set([2, 4, 6])) | |
759 | ||
760 | def test_intersection_overlap(self): | |
761 | self.set &= set([3, 4, 5]) | |
762 | self.assertEqual(self.set, set([4])) | |
763 | ||
764 | def test_intersection_non_overlap(self): | |
765 | self.set &= set([8]) | |
766 | self.assertEqual(self.set, empty_set) | |
767 | ||
768 | def test_intersection_method_call(self): | |
769 | self.set.intersection_update(set([3, 4, 5])) | |
770 | self.assertEqual(self.set, set([4])) | |
771 | ||
772 | def test_sym_difference_subset(self): | |
773 | self.set ^= set((2, 4)) | |
774 | self.assertEqual(self.set, set([6])) | |
775 | ||
776 | def test_sym_difference_superset(self): | |
777 | self.set ^= set((2, 4, 6, 8)) | |
778 | self.assertEqual(self.set, set([8])) | |
779 | ||
780 | def test_sym_difference_overlap(self): | |
781 | self.set ^= set((3, 4, 5)) | |
782 | self.assertEqual(self.set, set([2, 3, 5, 6])) | |
783 | ||
784 | def test_sym_difference_non_overlap(self): | |
785 | self.set ^= set([8]) | |
786 | self.assertEqual(self.set, set([2, 4, 6, 8])) | |
787 | ||
788 | def test_sym_difference_method_call(self): | |
789 | self.set.symmetric_difference_update(set([3, 4, 5])) | |
790 | self.assertEqual(self.set, set([2, 3, 5, 6])) | |
791 | ||
792 | def test_difference_subset(self): | |
793 | self.set -= set((2, 4)) | |
794 | self.assertEqual(self.set, set([6])) | |
795 | ||
796 | def test_difference_superset(self): | |
797 | self.set -= set((2, 4, 6, 8)) | |
798 | self.assertEqual(self.set, set([])) | |
799 | ||
800 | def test_difference_overlap(self): | |
801 | self.set -= set((3, 4, 5)) | |
802 | self.assertEqual(self.set, set([2, 6])) | |
803 | ||
804 | def test_difference_non_overlap(self): | |
805 | self.set -= set([8]) | |
806 | self.assertEqual(self.set, set([2, 4, 6])) | |
807 | ||
808 | def test_difference_method_call(self): | |
809 | self.set.difference_update(set([3, 4, 5])) | |
810 | self.assertEqual(self.set, set([2, 6])) | |
811 | ||
812 | #============================================================================== | |
813 | ||
814 | class TestMutate(unittest.TestCase): | |
815 | def setUp(self): | |
816 | self.values = ["a", "b", "c"] | |
817 | self.set = set(self.values) | |
818 | ||
819 | def test_add_present(self): | |
820 | self.set.add("c") | |
821 | self.assertEqual(self.set, set("abc")) | |
822 | ||
823 | def test_add_absent(self): | |
824 | self.set.add("d") | |
825 | self.assertEqual(self.set, set("abcd")) | |
826 | ||
827 | def test_add_until_full(self): | |
828 | tmp = set() | |
829 | expected_len = 0 | |
830 | for v in self.values: | |
831 | tmp.add(v) | |
832 | expected_len += 1 | |
833 | self.assertEqual(len(tmp), expected_len) | |
834 | self.assertEqual(tmp, self.set) | |
835 | ||
836 | def test_remove_present(self): | |
837 | self.set.remove("b") | |
838 | self.assertEqual(self.set, set("ac")) | |
839 | ||
840 | def test_remove_absent(self): | |
841 | try: | |
842 | self.set.remove("d") | |
843 | self.fail("Removing missing element should have raised LookupError") | |
844 | except LookupError: | |
845 | pass | |
846 | ||
847 | def test_remove_until_empty(self): | |
848 | expected_len = len(self.set) | |
849 | for v in self.values: | |
850 | self.set.remove(v) | |
851 | expected_len -= 1 | |
852 | self.assertEqual(len(self.set), expected_len) | |
853 | ||
854 | def test_discard_present(self): | |
855 | self.set.discard("c") | |
856 | self.assertEqual(self.set, set("ab")) | |
857 | ||
858 | def test_discard_absent(self): | |
859 | self.set.discard("d") | |
860 | self.assertEqual(self.set, set("abc")) | |
861 | ||
862 | def test_clear(self): | |
863 | self.set.clear() | |
864 | self.assertEqual(len(self.set), 0) | |
865 | ||
866 | def test_pop(self): | |
867 | popped = {} | |
868 | while self.set: | |
869 | popped[self.set.pop()] = None | |
870 | self.assertEqual(len(popped), len(self.values)) | |
871 | for v in self.values: | |
872 | self.failUnless(v in popped) | |
873 | ||
874 | def test_update_empty_tuple(self): | |
875 | self.set.update(()) | |
876 | self.assertEqual(self.set, set(self.values)) | |
877 | ||
878 | def test_update_unit_tuple_overlap(self): | |
879 | self.set.update(("a",)) | |
880 | self.assertEqual(self.set, set(self.values)) | |
881 | ||
882 | def test_update_unit_tuple_non_overlap(self): | |
883 | self.set.update(("a", "z")) | |
884 | self.assertEqual(self.set, set(self.values + ["z"])) | |
885 | ||
886 | #============================================================================== | |
887 | ||
888 | class TestSubsets(unittest.TestCase): | |
889 | ||
890 | case2method = {"<=": "issubset", | |
891 | ">=": "issuperset", | |
892 | } | |
893 | ||
894 | reverse = {"==": "==", | |
895 | "!=": "!=", | |
896 | "<": ">", | |
897 | ">": "<", | |
898 | "<=": ">=", | |
899 | ">=": "<=", | |
900 | } | |
901 | ||
902 | def test_issubset(self): | |
903 | x = self.left | |
904 | y = self.right | |
905 | for case in "!=", "==", "<", "<=", ">", ">=": | |
906 | expected = case in self.cases | |
907 | # Test the binary infix spelling. | |
908 | result = eval("x" + case + "y", locals()) | |
909 | self.assertEqual(result, expected) | |
910 | # Test the "friendly" method-name spelling, if one exists. | |
911 | if case in TestSubsets.case2method: | |
912 | method = getattr(x, TestSubsets.case2method[case]) | |
913 | result = method(y) | |
914 | self.assertEqual(result, expected) | |
915 | ||
916 | # Now do the same for the operands reversed. | |
917 | rcase = TestSubsets.reverse[case] | |
918 | result = eval("y" + rcase + "x", locals()) | |
919 | self.assertEqual(result, expected) | |
920 | if rcase in TestSubsets.case2method: | |
921 | method = getattr(y, TestSubsets.case2method[rcase]) | |
922 | result = method(x) | |
923 | self.assertEqual(result, expected) | |
924 | #------------------------------------------------------------------------------ | |
925 | ||
926 | class TestSubsetEqualEmpty(TestSubsets): | |
927 | left = set() | |
928 | right = set() | |
929 | name = "both empty" | |
930 | cases = "==", "<=", ">=" | |
931 | ||
932 | #------------------------------------------------------------------------------ | |
933 | ||
934 | class TestSubsetEqualNonEmpty(TestSubsets): | |
935 | left = set([1, 2]) | |
936 | right = set([1, 2]) | |
937 | name = "equal pair" | |
938 | cases = "==", "<=", ">=" | |
939 | ||
940 | #------------------------------------------------------------------------------ | |
941 | ||
942 | class TestSubsetEmptyNonEmpty(TestSubsets): | |
943 | left = set() | |
944 | right = set([1, 2]) | |
945 | name = "one empty, one non-empty" | |
946 | cases = "!=", "<", "<=" | |
947 | ||
948 | #------------------------------------------------------------------------------ | |
949 | ||
950 | class TestSubsetPartial(TestSubsets): | |
951 | left = set([1]) | |
952 | right = set([1, 2]) | |
953 | name = "one a non-empty proper subset of other" | |
954 | cases = "!=", "<", "<=" | |
955 | ||
956 | #------------------------------------------------------------------------------ | |
957 | ||
958 | class TestSubsetNonOverlap(TestSubsets): | |
959 | left = set([1]) | |
960 | right = set([2]) | |
961 | name = "neither empty, neither contains" | |
962 | cases = "!=" | |
963 | ||
964 | #============================================================================== | |
965 | ||
966 | class TestOnlySetsInBinaryOps(unittest.TestCase): | |
967 | ||
968 | def test_eq_ne(self): | |
969 | # Unlike the others, this is testing that == and != *are* allowed. | |
970 | self.assertEqual(self.other == self.set, False) | |
971 | self.assertEqual(self.set == self.other, False) | |
972 | self.assertEqual(self.other != self.set, True) | |
973 | self.assertEqual(self.set != self.other, True) | |
974 | ||
975 | def test_ge_gt_le_lt(self): | |
976 | self.assertRaises(TypeError, lambda: self.set < self.other) | |
977 | self.assertRaises(TypeError, lambda: self.set <= self.other) | |
978 | self.assertRaises(TypeError, lambda: self.set > self.other) | |
979 | self.assertRaises(TypeError, lambda: self.set >= self.other) | |
980 | ||
981 | self.assertRaises(TypeError, lambda: self.other < self.set) | |
982 | self.assertRaises(TypeError, lambda: self.other <= self.set) | |
983 | self.assertRaises(TypeError, lambda: self.other > self.set) | |
984 | self.assertRaises(TypeError, lambda: self.other >= self.set) | |
985 | ||
986 | def test_update_operator(self): | |
987 | try: | |
988 | self.set |= self.other | |
989 | except TypeError: | |
990 | pass | |
991 | else: | |
992 | self.fail("expected TypeError") | |
993 | ||
994 | def test_update(self): | |
995 | if self.otherIsIterable: | |
996 | self.set.update(self.other) | |
997 | else: | |
998 | self.assertRaises(TypeError, self.set.update, self.other) | |
999 | ||
1000 | def test_union(self): | |
1001 | self.assertRaises(TypeError, lambda: self.set | self.other) | |
1002 | self.assertRaises(TypeError, lambda: self.other | self.set) | |
1003 | if self.otherIsIterable: | |
1004 | self.set.union(self.other) | |
1005 | else: | |
1006 | self.assertRaises(TypeError, self.set.union, self.other) | |
1007 | ||
1008 | def test_intersection_update_operator(self): | |
1009 | try: | |
1010 | self.set &= self.other | |
1011 | except TypeError: | |
1012 | pass | |
1013 | else: | |
1014 | self.fail("expected TypeError") | |
1015 | ||
1016 | def test_intersection_update(self): | |
1017 | if self.otherIsIterable: | |
1018 | self.set.intersection_update(self.other) | |
1019 | else: | |
1020 | self.assertRaises(TypeError, | |
1021 | self.set.intersection_update, | |
1022 | self.other) | |
1023 | ||
1024 | def test_intersection(self): | |
1025 | self.assertRaises(TypeError, lambda: self.set & self.other) | |
1026 | self.assertRaises(TypeError, lambda: self.other & self.set) | |
1027 | if self.otherIsIterable: | |
1028 | self.set.intersection(self.other) | |
1029 | else: | |
1030 | self.assertRaises(TypeError, self.set.intersection, self.other) | |
1031 | ||
1032 | def test_sym_difference_update_operator(self): | |
1033 | try: | |
1034 | self.set ^= self.other | |
1035 | except TypeError: | |
1036 | pass | |
1037 | else: | |
1038 | self.fail("expected TypeError") | |
1039 | ||
1040 | def test_sym_difference_update(self): | |
1041 | if self.otherIsIterable: | |
1042 | self.set.symmetric_difference_update(self.other) | |
1043 | else: | |
1044 | self.assertRaises(TypeError, | |
1045 | self.set.symmetric_difference_update, | |
1046 | self.other) | |
1047 | ||
1048 | def test_sym_difference(self): | |
1049 | self.assertRaises(TypeError, lambda: self.set ^ self.other) | |
1050 | self.assertRaises(TypeError, lambda: self.other ^ self.set) | |
1051 | if self.otherIsIterable: | |
1052 | self.set.symmetric_difference(self.other) | |
1053 | else: | |
1054 | self.assertRaises(TypeError, self.set.symmetric_difference, self.other) | |
1055 | ||
1056 | def test_difference_update_operator(self): | |
1057 | try: | |
1058 | self.set -= self.other | |
1059 | except TypeError: | |
1060 | pass | |
1061 | else: | |
1062 | self.fail("expected TypeError") | |
1063 | ||
1064 | def test_difference_update(self): | |
1065 | if self.otherIsIterable: | |
1066 | self.set.difference_update(self.other) | |
1067 | else: | |
1068 | self.assertRaises(TypeError, | |
1069 | self.set.difference_update, | |
1070 | self.other) | |
1071 | ||
1072 | def test_difference(self): | |
1073 | self.assertRaises(TypeError, lambda: self.set - self.other) | |
1074 | self.assertRaises(TypeError, lambda: self.other - self.set) | |
1075 | if self.otherIsIterable: | |
1076 | self.set.difference(self.other) | |
1077 | else: | |
1078 | self.assertRaises(TypeError, self.set.difference, self.other) | |
1079 | ||
1080 | #------------------------------------------------------------------------------ | |
1081 | ||
1082 | class TestOnlySetsNumeric(TestOnlySetsInBinaryOps): | |
1083 | def setUp(self): | |
1084 | self.set = set((1, 2, 3)) | |
1085 | self.other = 19 | |
1086 | self.otherIsIterable = False | |
1087 | ||
1088 | #------------------------------------------------------------------------------ | |
1089 | ||
1090 | class TestOnlySetsDict(TestOnlySetsInBinaryOps): | |
1091 | def setUp(self): | |
1092 | self.set = set((1, 2, 3)) | |
1093 | self.other = {1:2, 3:4} | |
1094 | self.otherIsIterable = True | |
1095 | ||
1096 | #------------------------------------------------------------------------------ | |
1097 | ||
1098 | class TestOnlySetsOperator(TestOnlySetsInBinaryOps): | |
1099 | def setUp(self): | |
1100 | self.set = set((1, 2, 3)) | |
1101 | self.other = operator.add | |
1102 | self.otherIsIterable = False | |
1103 | ||
1104 | #------------------------------------------------------------------------------ | |
1105 | ||
1106 | class TestOnlySetsTuple(TestOnlySetsInBinaryOps): | |
1107 | def setUp(self): | |
1108 | self.set = set((1, 2, 3)) | |
1109 | self.other = (2, 4, 6) | |
1110 | self.otherIsIterable = True | |
1111 | ||
1112 | #------------------------------------------------------------------------------ | |
1113 | ||
1114 | class TestOnlySetsString(TestOnlySetsInBinaryOps): | |
1115 | def setUp(self): | |
1116 | self.set = set((1, 2, 3)) | |
1117 | self.other = 'abc' | |
1118 | self.otherIsIterable = True | |
1119 | ||
1120 | #------------------------------------------------------------------------------ | |
1121 | ||
1122 | class TestOnlySetsGenerator(TestOnlySetsInBinaryOps): | |
1123 | def setUp(self): | |
1124 | def gen(): | |
1125 | for i in xrange(0, 10, 2): | |
1126 | yield i | |
1127 | self.set = set((1, 2, 3)) | |
1128 | self.other = gen() | |
1129 | self.otherIsIterable = True | |
1130 | ||
1131 | #============================================================================== | |
1132 | ||
1133 | class TestCopying(unittest.TestCase): | |
1134 | ||
1135 | def test_copy(self): | |
1136 | dup = self.set.copy() | |
1137 | dup_list = list(dup); dup_list.sort() | |
1138 | set_list = list(self.set); set_list.sort() | |
1139 | self.assertEqual(len(dup_list), len(set_list)) | |
1140 | for i in range(len(dup_list)): | |
1141 | self.failUnless(dup_list[i] is set_list[i]) | |
1142 | ||
1143 | def test_deep_copy(self): | |
1144 | dup = copy.deepcopy(self.set) | |
1145 | ##print type(dup), repr(dup) | |
1146 | dup_list = list(dup); dup_list.sort() | |
1147 | set_list = list(self.set); set_list.sort() | |
1148 | self.assertEqual(len(dup_list), len(set_list)) | |
1149 | for i in range(len(dup_list)): | |
1150 | self.assertEqual(dup_list[i], set_list[i]) | |
1151 | ||
1152 | #------------------------------------------------------------------------------ | |
1153 | ||
1154 | class TestCopyingEmpty(TestCopying): | |
1155 | def setUp(self): | |
1156 | self.set = set() | |
1157 | ||
1158 | #------------------------------------------------------------------------------ | |
1159 | ||
1160 | class TestCopyingSingleton(TestCopying): | |
1161 | def setUp(self): | |
1162 | self.set = set(["hello"]) | |
1163 | ||
1164 | #------------------------------------------------------------------------------ | |
1165 | ||
1166 | class TestCopyingTriple(TestCopying): | |
1167 | def setUp(self): | |
1168 | self.set = set(["zero", 0, None]) | |
1169 | ||
1170 | #------------------------------------------------------------------------------ | |
1171 | ||
1172 | class TestCopyingTuple(TestCopying): | |
1173 | def setUp(self): | |
1174 | self.set = set([(1, 2)]) | |
1175 | ||
1176 | #------------------------------------------------------------------------------ | |
1177 | ||
1178 | class TestCopyingNested(TestCopying): | |
1179 | def setUp(self): | |
1180 | self.set = set([((1, 2), (3, 4))]) | |
1181 | ||
1182 | #============================================================================== | |
1183 | ||
1184 | class TestIdentities(unittest.TestCase): | |
1185 | def setUp(self): | |
1186 | self.a = set('abracadabra') | |
1187 | self.b = set('alacazam') | |
1188 | ||
1189 | def test_binopsVsSubsets(self): | |
1190 | a, b = self.a, self.b | |
1191 | self.assert_(a - b < a) | |
1192 | self.assert_(b - a < b) | |
1193 | self.assert_(a & b < a) | |
1194 | self.assert_(a & b < b) | |
1195 | self.assert_(a | b > a) | |
1196 | self.assert_(a | b > b) | |
1197 | self.assert_(a ^ b < a | b) | |
1198 | ||
1199 | def test_commutativity(self): | |
1200 | a, b = self.a, self.b | |
1201 | self.assertEqual(a&b, b&a) | |
1202 | self.assertEqual(a|b, b|a) | |
1203 | self.assertEqual(a^b, b^a) | |
1204 | if a != b: | |
1205 | self.assertNotEqual(a-b, b-a) | |
1206 | ||
1207 | def test_summations(self): | |
1208 | # check that sums of parts equal the whole | |
1209 | a, b = self.a, self.b | |
1210 | self.assertEqual((a-b)|(a&b)|(b-a), a|b) | |
1211 | self.assertEqual((a&b)|(a^b), a|b) | |
1212 | self.assertEqual(a|(b-a), a|b) | |
1213 | self.assertEqual((a-b)|b, a|b) | |
1214 | self.assertEqual((a-b)|(a&b), a) | |
1215 | self.assertEqual((b-a)|(a&b), b) | |
1216 | self.assertEqual((a-b)|(b-a), a^b) | |
1217 | ||
1218 | def test_exclusion(self): | |
1219 | # check that inverse operations show non-overlap | |
1220 | a, b, zero = self.a, self.b, set() | |
1221 | self.assertEqual((a-b)&b, zero) | |
1222 | self.assertEqual((b-a)&a, zero) | |
1223 | self.assertEqual((a&b)&(a^b), zero) | |
1224 | ||
1225 | # Tests derived from test_itertools.py ======================================= | |
1226 | ||
1227 | def R(seqn): | |
1228 | 'Regular generator' | |
1229 | for i in seqn: | |
1230 | yield i | |
1231 | ||
1232 | class G: | |
1233 | 'Sequence using __getitem__' | |
1234 | def __init__(self, seqn): | |
1235 | self.seqn = seqn | |
1236 | def __getitem__(self, i): | |
1237 | return self.seqn[i] | |
1238 | ||
1239 | class I: | |
1240 | 'Sequence using iterator protocol' | |
1241 | def __init__(self, seqn): | |
1242 | self.seqn = seqn | |
1243 | self.i = 0 | |
1244 | def __iter__(self): | |
1245 | return self | |
1246 | def next(self): | |
1247 | if self.i >= len(self.seqn): raise StopIteration | |
1248 | v = self.seqn[self.i] | |
1249 | self.i += 1 | |
1250 | return v | |
1251 | ||
1252 | class Ig: | |
1253 | 'Sequence using iterator protocol defined with a generator' | |
1254 | def __init__(self, seqn): | |
1255 | self.seqn = seqn | |
1256 | self.i = 0 | |
1257 | def __iter__(self): | |
1258 | for val in self.seqn: | |
1259 | yield val | |
1260 | ||
1261 | class X: | |
1262 | 'Missing __getitem__ and __iter__' | |
1263 | def __init__(self, seqn): | |
1264 | self.seqn = seqn | |
1265 | self.i = 0 | |
1266 | def next(self): | |
1267 | if self.i >= len(self.seqn): raise StopIteration | |
1268 | v = self.seqn[self.i] | |
1269 | self.i += 1 | |
1270 | return v | |
1271 | ||
1272 | class N: | |
1273 | 'Iterator missing next()' | |
1274 | def __init__(self, seqn): | |
1275 | self.seqn = seqn | |
1276 | self.i = 0 | |
1277 | def __iter__(self): | |
1278 | return self | |
1279 | ||
1280 | class E: | |
1281 | 'Test propagation of exceptions' | |
1282 | def __init__(self, seqn): | |
1283 | self.seqn = seqn | |
1284 | self.i = 0 | |
1285 | def __iter__(self): | |
1286 | return self | |
1287 | def next(self): | |
1288 | 3 // 0 | |
1289 | ||
1290 | class S: | |
1291 | 'Test immediate stop' | |
1292 | def __init__(self, seqn): | |
1293 | pass | |
1294 | def __iter__(self): | |
1295 | return self | |
1296 | def next(self): | |
1297 | raise StopIteration | |
1298 | ||
1299 | from itertools import chain, imap | |
1300 | def L(seqn): | |
1301 | 'Test multiple tiers of iterators' | |
1302 | return chain(imap(lambda x:x, R(Ig(G(seqn))))) | |
1303 | ||
1304 | class TestVariousIteratorArgs(unittest.TestCase): | |
1305 | ||
1306 | def test_constructor(self): | |
1307 | for cons in (set, frozenset): | |
1308 | for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)): | |
1309 | for g in (G, I, Ig, S, L, R): | |
1310 | self.assertEqual(sorted(cons(g(s))), sorted(g(s))) | |
1311 | self.assertRaises(TypeError, cons , X(s)) | |
1312 | self.assertRaises(TypeError, cons , N(s)) | |
1313 | self.assertRaises(ZeroDivisionError, cons , E(s)) | |
1314 | ||
1315 | def test_inline_methods(self): | |
1316 | s = set('november') | |
1317 | for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'): | |
1318 | for meth in (s.union, s.intersection, s.difference, s.symmetric_difference): | |
1319 | for g in (G, I, Ig, L, R): | |
1320 | expected = meth(data) | |
1321 | actual = meth(G(data)) | |
1322 | self.assertEqual(sorted(actual), sorted(expected)) | |
1323 | self.assertRaises(TypeError, meth, X(s)) | |
1324 | self.assertRaises(TypeError, meth, N(s)) | |
1325 | self.assertRaises(ZeroDivisionError, meth, E(s)) | |
1326 | ||
1327 | def test_inplace_methods(self): | |
1328 | for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'): | |
1329 | for methname in ('update', 'intersection_update', | |
1330 | 'difference_update', 'symmetric_difference_update'): | |
1331 | for g in (G, I, Ig, S, L, R): | |
1332 | s = set('january') | |
1333 | t = s.copy() | |
1334 | getattr(s, methname)(list(g(data))) | |
1335 | getattr(t, methname)(g(data)) | |
1336 | self.assertEqual(sorted(s), sorted(t)) | |
1337 | ||
1338 | self.assertRaises(TypeError, getattr(set('january'), methname), X(data)) | |
1339 | self.assertRaises(TypeError, getattr(set('january'), methname), N(data)) | |
1340 | self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data)) | |
1341 | ||
1342 | #============================================================================== | |
1343 | ||
1344 | def test_main(verbose=None): | |
1345 | import sys | |
1346 | from test import test_sets | |
1347 | test_classes = ( | |
1348 | TestSet, | |
1349 | TestSetSubclass, | |
1350 | TestFrozenSet, | |
1351 | TestFrozenSetSubclass, | |
1352 | TestSetOfSets, | |
1353 | TestExceptionPropagation, | |
1354 | TestBasicOpsEmpty, | |
1355 | TestBasicOpsSingleton, | |
1356 | TestBasicOpsTuple, | |
1357 | TestBasicOpsTriple, | |
1358 | TestBinaryOps, | |
1359 | TestUpdateOps, | |
1360 | TestMutate, | |
1361 | TestSubsetEqualEmpty, | |
1362 | TestSubsetEqualNonEmpty, | |
1363 | TestSubsetEmptyNonEmpty, | |
1364 | TestSubsetPartial, | |
1365 | TestSubsetNonOverlap, | |
1366 | TestOnlySetsNumeric, | |
1367 | TestOnlySetsDict, | |
1368 | TestOnlySetsOperator, | |
1369 | TestOnlySetsTuple, | |
1370 | TestOnlySetsString, | |
1371 | TestOnlySetsGenerator, | |
1372 | TestCopyingEmpty, | |
1373 | TestCopyingSingleton, | |
1374 | TestCopyingTriple, | |
1375 | TestCopyingTuple, | |
1376 | TestCopyingNested, | |
1377 | TestIdentities, | |
1378 | TestVariousIteratorArgs, | |
1379 | ) | |
1380 | ||
1381 | test_support.run_unittest(*test_classes) | |
1382 | ||
1383 | # verify reference counting | |
1384 | if verbose and hasattr(sys, "gettotalrefcount"): | |
1385 | import gc | |
1386 | counts = [None] * 5 | |
1387 | for i in xrange(len(counts)): | |
1388 | test_support.run_unittest(*test_classes) | |
1389 | gc.collect() | |
1390 | counts[i] = sys.gettotalrefcount() | |
1391 | print counts | |
1392 | ||
1393 | if __name__ == "__main__": | |
1394 | test_main(verbose=True) |