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