1 #!/usr/bin/env python 2 3 import unittest, operator, copy, pickle, random 4 from test import test_support 5 6 test_support.import_module("sets", deprecated=True) 7 from sets import Set, ImmutableSet 8 9 empty_set = Set() 10 11 #============================================================================== 12 13 class TestBasicOps(unittest.TestCase): 14 15 def test_repr(self): 16 if self.repr is not None: 17 self.assertEqual(repr(self.set), self.repr) 18 19 def test_length(self): 20 self.assertEqual(len(self.set), self.length) 21 22 def test_self_equality(self): 23 self.assertEqual(self.set, self.set) 24 25 def test_equivalent_equality(self): 26 self.assertEqual(self.set, self.dup) 27 28 def test_copy(self): 29 self.assertEqual(self.set.copy(), self.dup) 30 31 def test_self_union(self): 32 result = self.set | self.set 33 self.assertEqual(result, self.dup) 34 35 def test_empty_union(self): 36 result = self.set | empty_set 37 self.assertEqual(result, self.dup) 38 39 def test_union_empty(self): 40 result = empty_set | self.set 41 self.assertEqual(result, self.dup) 42 43 def test_self_intersection(self): 44 result = self.set & self.set 45 self.assertEqual(result, self.dup) 46 47 def test_empty_intersection(self): 48 result = self.set & empty_set 49 self.assertEqual(result, empty_set) 50 51 def test_intersection_empty(self): 52 result = empty_set & self.set 53 self.assertEqual(result, empty_set) 54 55 def test_self_symmetric_difference(self): 56 result = self.set ^ self.set 57 self.assertEqual(result, empty_set) 58 59 def checkempty_symmetric_difference(self): 60 result = self.set ^ empty_set 61 self.assertEqual(result, self.set) 62 63 def test_self_difference(self): 64 result = self.set - self.set 65 self.assertEqual(result, empty_set) 66 67 def test_empty_difference(self): 68 result = self.set - empty_set 69 self.assertEqual(result, self.dup) 70 71 def test_empty_difference_rev(self): 72 result = empty_set - self.set 73 self.assertEqual(result, empty_set) 74 75 def test_iteration(self): 76 for v in self.set: 77 self.assertIn(v, self.values) 78 79 def test_pickling(self): 80 p = pickle.dumps(self.set) 81 copy = pickle.loads(p) 82 self.assertEqual(self.set, copy, 83 "%s != %s" % (self.set, copy)) 84 85 #------------------------------------------------------------------------------ 86 87 class TestBasicOpsEmpty(TestBasicOps): 88 def setUp(self): 89 self.case = "empty set" 90 self.values = [] 91 self.set = Set(self.values) 92 self.dup = Set(self.values) 93 self.length = 0 94 self.repr = "Set([])" 95 96 #------------------------------------------------------------------------------ 97 98 class TestBasicOpsSingleton(TestBasicOps): 99 def setUp(self): 100 self.case = "unit set (number)" 101 self.values = [3] 102 self.set = Set(self.values) 103 self.dup = Set(self.values) 104 self.length = 1 105 self.repr = "Set([3])" 106 107 def test_in(self): 108 self.assertTrue(3 in self.set) 109 110 def test_not_in(self): 111 self.assertTrue(2 not in self.set) 112 113 #------------------------------------------------------------------------------ 114 115 class TestBasicOpsTuple(TestBasicOps): 116 def setUp(self): 117 self.case = "unit set (tuple)" 118 self.values = [(0, "zero")] 119 self.set = Set(self.values) 120 self.dup = Set(self.values) 121 self.length = 1 122 self.repr = "Set([(0, 'zero')])" 123 124 def test_in(self): 125 self.assertTrue((0, "zero") in self.set) 126 127 def test_not_in(self): 128 self.assertTrue(9 not in self.set) 129 130 #------------------------------------------------------------------------------ 131 132 class TestBasicOpsTriple(TestBasicOps): 133 def setUp(self): 134 self.case = "triple set" 135 self.values = [0, "zero", operator.add] 136 self.set = Set(self.values) 137 self.dup = Set(self.values) 138 self.length = 3 139 self.repr = None 140 141 #============================================================================== 142 143 def baditer(): 144 raise TypeError 145 yield True 146 147 def gooditer(): 148 yield True 149 150 class TestExceptionPropagation(unittest.TestCase): 151 """SF 628246: Set constructor should not trap iterator TypeErrors""" 152 153 def test_instanceWithException(self): 154 self.assertRaises(TypeError, Set, baditer()) 155 156 def test_instancesWithoutException(self): 157 # All of these iterables should load without exception. 158 Set([1,2,3]) 159 Set((1,2,3)) 160 Set({'one':1, 'two':2, 'three':3}) 161 Set(xrange(3)) 162 Set('abc') 163 Set(gooditer()) 164 165 #============================================================================== 166 167 class TestSetOfSets(unittest.TestCase): 168 def test_constructor(self): 169 inner = Set([1]) 170 outer = Set([inner]) 171 element = outer.pop() 172 self.assertEqual(type(element), ImmutableSet) 173 outer.add(inner) # Rebuild set of sets with .add method 174 outer.remove(inner) 175 self.assertEqual(outer, Set()) # Verify that remove worked 176 outer.discard(inner) # Absence of KeyError indicates working fine 177 178 #============================================================================== 179 180 class TestBinaryOps(unittest.TestCase): 181 def setUp(self): 182 self.set = Set((2, 4, 6)) 183 184 def test_eq(self): # SF bug 643115 185 self.assertEqual(self.set, Set({2:1,4:3,6:5})) 186 187 def test_union_subset(self): 188 result = self.set | Set([2]) 189 self.assertEqual(result, Set((2, 4, 6))) 190 191 def test_union_superset(self): 192 result = self.set | Set([2, 4, 6, 8]) 193 self.assertEqual(result, Set([2, 4, 6, 8])) 194 195 def test_union_overlap(self): 196 result = self.set | Set([3, 4, 5]) 197 self.assertEqual(result, Set([2, 3, 4, 5, 6])) 198 199 def test_union_non_overlap(self): 200 result = self.set | Set([8]) 201 self.assertEqual(result, Set([2, 4, 6, 8])) 202 203 def test_intersection_subset(self): 204 result = self.set & Set((2, 4)) 205 self.assertEqual(result, Set((2, 4))) 206 207 def test_intersection_superset(self): 208 result = self.set & Set([2, 4, 6, 8]) 209 self.assertEqual(result, Set([2, 4, 6])) 210 211 def test_intersection_overlap(self): 212 result = self.set & Set([3, 4, 5]) 213 self.assertEqual(result, Set([4])) 214 215 def test_intersection_non_overlap(self): 216 result = self.set & Set([8]) 217 self.assertEqual(result, empty_set) 218 219 def test_sym_difference_subset(self): 220 result = self.set ^ Set((2, 4)) 221 self.assertEqual(result, Set([6])) 222 223 def test_sym_difference_superset(self): 224 result = self.set ^ Set((2, 4, 6, 8)) 225 self.assertEqual(result, Set([8])) 226 227 def test_sym_difference_overlap(self): 228 result = self.set ^ Set((3, 4, 5)) 229 self.assertEqual(result, Set([2, 3, 5, 6])) 230 231 def test_sym_difference_non_overlap(self): 232 result = self.set ^ Set([8]) 233 self.assertEqual(result, Set([2, 4, 6, 8])) 234 235 def test_cmp(self): 236 a, b = Set('a'), Set('b') 237 self.assertRaises(TypeError, cmp, a, b) 238 239 # You can view this as a buglet: cmp(a, a) does not raise TypeError, 240 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True, 241 # which Python thinks is good enough to synthesize a cmp() result 242 # without calling __cmp__. 243 self.assertEqual(cmp(a, a), 0) 244 245 self.assertRaises(TypeError, cmp, a, 12) 246 self.assertRaises(TypeError, cmp, "abc", a) 247 248 def test_inplace_on_self(self): 249 t = self.set.copy() 250 t |= t 251 self.assertEqual(t, self.set) 252 t &= t 253 self.assertEqual(t, self.set) 254 t -= t 255 self.assertEqual(len(t), 0) 256 t = self.set.copy() 257 t ^= t 258 self.assertEqual(len(t), 0) 259 260 261 #============================================================================== 262 263 class TestUpdateOps(unittest.TestCase): 264 def setUp(self): 265 self.set = Set((2, 4, 6)) 266 267 def test_union_subset(self): 268 self.set |= Set([2]) 269 self.assertEqual(self.set, Set((2, 4, 6))) 270 271 def test_union_superset(self): 272 self.set |= Set([2, 4, 6, 8]) 273 self.assertEqual(self.set, Set([2, 4, 6, 8])) 274 275 def test_union_overlap(self): 276 self.set |= Set([3, 4, 5]) 277 self.assertEqual(self.set, Set([2, 3, 4, 5, 6])) 278 279 def test_union_non_overlap(self): 280 self.set |= Set([8]) 281 self.assertEqual(self.set, Set([2, 4, 6, 8])) 282 283 def test_union_method_call(self): 284 self.set.union_update(Set([3, 4, 5])) 285 self.assertEqual(self.set, Set([2, 3, 4, 5, 6])) 286 287 def test_intersection_subset(self): 288 self.set &= Set((2, 4)) 289 self.assertEqual(self.set, Set((2, 4))) 290 291 def test_intersection_superset(self): 292 self.set &= Set([2, 4, 6, 8]) 293 self.assertEqual(self.set, Set([2, 4, 6])) 294 295 def test_intersection_overlap(self): 296 self.set &= Set([3, 4, 5]) 297 self.assertEqual(self.set, Set([4])) 298 299 def test_intersection_non_overlap(self): 300 self.set &= Set([8]) 301 self.assertEqual(self.set, empty_set) 302 303 def test_intersection_method_call(self): 304 self.set.intersection_update(Set([3, 4, 5])) 305 self.assertEqual(self.set, Set([4])) 306 307 def test_sym_difference_subset(self): 308 self.set ^= Set((2, 4)) 309 self.assertEqual(self.set, Set([6])) 310 311 def test_sym_difference_superset(self): 312 self.set ^= Set((2, 4, 6, 8)) 313 self.assertEqual(self.set, Set([8])) 314 315 def test_sym_difference_overlap(self): 316 self.set ^= Set((3, 4, 5)) 317 self.assertEqual(self.set, Set([2, 3, 5, 6])) 318 319 def test_sym_difference_non_overlap(self): 320 self.set ^= Set([8]) 321 self.assertEqual(self.set, Set([2, 4, 6, 8])) 322 323 def test_sym_difference_method_call(self): 324 self.set.symmetric_difference_update(Set([3, 4, 5])) 325 self.assertEqual(self.set, Set([2, 3, 5, 6])) 326 327 def test_difference_subset(self): 328 self.set -= Set((2, 4)) 329 self.assertEqual(self.set, Set([6])) 330 331 def test_difference_superset(self): 332 self.set -= Set((2, 4, 6, 8)) 333 self.assertEqual(self.set, Set([])) 334 335 def test_difference_overlap(self): 336 self.set -= Set((3, 4, 5)) 337 self.assertEqual(self.set, Set([2, 6])) 338 339 def test_difference_non_overlap(self): 340 self.set -= Set([8]) 341 self.assertEqual(self.set, Set([2, 4, 6])) 342 343 def test_difference_method_call(self): 344 self.set.difference_update(Set([3, 4, 5])) 345 self.assertEqual(self.set, Set([2, 6])) 346 347 #============================================================================== 348 349 class TestMutate(unittest.TestCase): 350 def setUp(self): 351 self.values = ["a", "b", "c"] 352 self.set = Set(self.values) 353 354 def test_add_present(self): 355 self.set.add("c") 356 self.assertEqual(self.set, Set("abc")) 357 358 def test_add_absent(self): 359 self.set.add("d") 360 self.assertEqual(self.set, Set("abcd")) 361 362 def test_add_until_full(self): 363 tmp = Set() 364 expected_len = 0 365 for v in self.values: 366 tmp.add(v) 367 expected_len += 1 368 self.assertEqual(len(tmp), expected_len) 369 self.assertEqual(tmp, self.set) 370 371 def test_remove_present(self): 372 self.set.remove("b") 373 self.assertEqual(self.set, Set("ac")) 374 375 def test_remove_absent(self): 376 try: 377 self.set.remove("d") 378 self.fail("Removing missing element should have raised LookupError") 379 except LookupError: 380 pass 381 382 def test_remove_until_empty(self): 383 expected_len = len(self.set) 384 for v in self.values: 385 self.set.remove(v) 386 expected_len -= 1 387 self.assertEqual(len(self.set), expected_len) 388 389 def test_discard_present(self): 390 self.set.discard("c") 391 self.assertEqual(self.set, Set("ab")) 392 393 def test_discard_absent(self): 394 self.set.discard("d") 395 self.assertEqual(self.set, Set("abc")) 396 397 def test_clear(self): 398 self.set.clear() 399 self.assertEqual(len(self.set), 0) 400 401 def test_pop(self): 402 popped = {} 403 while self.set: 404 popped[self.set.pop()] = None 405 self.assertEqual(len(popped), len(self.values)) 406 for v in self.values: 407 self.assertIn(v, popped) 408 409 def test_update_empty_tuple(self): 410 self.set.union_update(()) 411 self.assertEqual(self.set, Set(self.values)) 412 413 def test_update_unit_tuple_overlap(self): 414 self.set.union_update(("a",)) 415 self.assertEqual(self.set, Set(self.values)) 416 417 def test_update_unit_tuple_non_overlap(self): 418 self.set.union_update(("a", "z")) 419 self.assertEqual(self.set, Set(self.values + ["z"])) 420 421 #============================================================================== 422 423 class TestSubsets(unittest.TestCase): 424 425 case2method = {"<=": "issubset", 426 ">=": "issuperset", 427 } 428 429 reverse = {"==": "==", 430 "!=": "!=", 431 "<": ">", 432 ">": "<", 433 "<=": ">=", 434 ">=": "<=", 435 } 436 437 def test_issubset(self): 438 x = self.left 439 y = self.right 440 for case in "!=", "==", "<", "<=", ">", ">=": 441 expected = case in self.cases 442 # Test the binary infix spelling. 443 result = eval("x" + case + "y", locals()) 444 self.assertEqual(result, expected) 445 # Test the "friendly" method-name spelling, if one exists. 446 if case in TestSubsets.case2method: 447 method = getattr(x, TestSubsets.case2method[case]) 448 result = method(y) 449 self.assertEqual(result, expected) 450 451 # Now do the same for the operands reversed. 452 rcase = TestSubsets.reverse[case] 453 result = eval("y" + rcase + "x", locals()) 454 self.assertEqual(result, expected) 455 if rcase in TestSubsets.case2method: 456 method = getattr(y, TestSubsets.case2method[rcase]) 457 result = method(x) 458 self.assertEqual(result, expected) 459 #------------------------------------------------------------------------------ 460 461 class TestSubsetEqualEmpty(TestSubsets): 462 left = Set() 463 right = Set() 464 name = "both empty" 465 cases = "==", "<=", ">=" 466 467 #------------------------------------------------------------------------------ 468 469 class TestSubsetEqualNonEmpty(TestSubsets): 470 left = Set([1, 2]) 471 right = Set([1, 2]) 472 name = "equal pair" 473 cases = "==", "<=", ">=" 474 475 #------------------------------------------------------------------------------ 476 477 class TestSubsetEmptyNonEmpty(TestSubsets): 478 left = Set() 479 right = Set([1, 2]) 480 name = "one empty, one non-empty" 481 cases = "!=", "<", "<=" 482 483 #------------------------------------------------------------------------------ 484 485 class TestSubsetPartial(TestSubsets): 486 left = Set([1]) 487 right = Set([1, 2]) 488 name = "one a non-empty proper subset of other" 489 cases = "!=", "<", "<=" 490 491 #------------------------------------------------------------------------------ 492 493 class TestSubsetNonOverlap(TestSubsets): 494 left = Set([1]) 495 right = Set([2]) 496 name = "neither empty, neither contains" 497 cases = "!=" 498 499 #============================================================================== 500 501 class TestOnlySetsInBinaryOps(unittest.TestCase): 502 503 def test_eq_ne(self): 504 # Unlike the others, this is testing that == and != *are* allowed. 505 self.assertEqual(self.other == self.set, False) 506 self.assertEqual(self.set == self.other, False) 507 self.assertEqual(self.other != self.set, True) 508 self.assertEqual(self.set != self.other, True) 509 510 def test_ge_gt_le_lt(self): 511 self.assertRaises(TypeError, lambda: self.set < self.other) 512 self.assertRaises(TypeError, lambda: self.set <= self.other) 513 self.assertRaises(TypeError, lambda: self.set > self.other) 514 self.assertRaises(TypeError, lambda: self.set >= self.other) 515 516 self.assertRaises(TypeError, lambda: self.other < self.set) 517 self.assertRaises(TypeError, lambda: self.other <= self.set) 518 self.assertRaises(TypeError, lambda: self.other > self.set) 519 self.assertRaises(TypeError, lambda: self.other >= self.set) 520 521 def test_union_update_operator(self): 522 try: 523 self.set |= self.other 524 except TypeError: 525 pass 526 else: 527 self.fail("expected TypeError") 528 529 def test_union_update(self): 530 if self.otherIsIterable: 531 self.set.union_update(self.other) 532 else: 533 self.assertRaises(TypeError, self.set.union_update, self.other) 534 535 def test_union(self): 536 self.assertRaises(TypeError, lambda: self.set | self.other) 537 self.assertRaises(TypeError, lambda: self.other | self.set) 538 if self.otherIsIterable: 539 self.set.union(self.other) 540 else: 541 self.assertRaises(TypeError, self.set.union, self.other) 542 543 def test_intersection_update_operator(self): 544 try: 545 self.set &= self.other 546 except TypeError: 547 pass 548 else: 549 self.fail("expected TypeError") 550 551 def test_intersection_update(self): 552 if self.otherIsIterable: 553 self.set.intersection_update(self.other) 554 else: 555 self.assertRaises(TypeError, 556 self.set.intersection_update, 557 self.other) 558 559 def test_intersection(self): 560 self.assertRaises(TypeError, lambda: self.set & self.other) 561 self.assertRaises(TypeError, lambda: self.other & self.set) 562 if self.otherIsIterable: 563 self.set.intersection(self.other) 564 else: 565 self.assertRaises(TypeError, self.set.intersection, self.other) 566 567 def test_sym_difference_update_operator(self): 568 try: 569 self.set ^= self.other 570 except TypeError: 571 pass 572 else: 573 self.fail("expected TypeError") 574 575 def test_sym_difference_update(self): 576 if self.otherIsIterable: 577 self.set.symmetric_difference_update(self.other) 578 else: 579 self.assertRaises(TypeError, 580 self.set.symmetric_difference_update, 581 self.other) 582 583 def test_sym_difference(self): 584 self.assertRaises(TypeError, lambda: self.set ^ self.other) 585 self.assertRaises(TypeError, lambda: self.other ^ self.set) 586 if self.otherIsIterable: 587 self.set.symmetric_difference(self.other) 588 else: 589 self.assertRaises(TypeError, self.set.symmetric_difference, self.other) 590 591 def test_difference_update_operator(self): 592 try: 593 self.set -= self.other 594 except TypeError: 595 pass 596 else: 597 self.fail("expected TypeError") 598 599 def test_difference_update(self): 600 if self.otherIsIterable: 601 self.set.difference_update(self.other) 602 else: 603 self.assertRaises(TypeError, 604 self.set.difference_update, 605 self.other) 606 607 def test_difference(self): 608 self.assertRaises(TypeError, lambda: self.set - self.other) 609 self.assertRaises(TypeError, lambda: self.other - self.set) 610 if self.otherIsIterable: 611 self.set.difference(self.other) 612 else: 613 self.assertRaises(TypeError, self.set.difference, self.other) 614 615 #------------------------------------------------------------------------------ 616 617 class TestOnlySetsNumeric(TestOnlySetsInBinaryOps): 618 def setUp(self): 619 self.set = Set((1, 2, 3)) 620 self.other = 19 621 self.otherIsIterable = False 622 623 #------------------------------------------------------------------------------ 624 625 class TestOnlySetsDict(TestOnlySetsInBinaryOps): 626 def setUp(self): 627 self.set = Set((1, 2, 3)) 628 self.other = {1:2, 3:4} 629 self.otherIsIterable = True 630 631 #------------------------------------------------------------------------------ 632 633 class TestOnlySetsOperator(TestOnlySetsInBinaryOps): 634 def setUp(self): 635 self.set = Set((1, 2, 3)) 636 self.other = operator.add 637 self.otherIsIterable = False 638 639 def test_ge_gt_le_lt(self): 640 with test_support.check_py3k_warnings(): 641 super(TestOnlySetsOperator, self).test_ge_gt_le_lt() 642 643 #------------------------------------------------------------------------------ 644 645 class TestOnlySetsTuple(TestOnlySetsInBinaryOps): 646 def setUp(self): 647 self.set = Set((1, 2, 3)) 648 self.other = (2, 4, 6) 649 self.otherIsIterable = True 650 651 #------------------------------------------------------------------------------ 652 653 class TestOnlySetsString(TestOnlySetsInBinaryOps): 654 def setUp(self): 655 self.set = Set((1, 2, 3)) 656 self.other = 'abc' 657 self.otherIsIterable = True 658 659 #------------------------------------------------------------------------------ 660 661 class TestOnlySetsGenerator(TestOnlySetsInBinaryOps): 662 def setUp(self): 663 def gen(): 664 for i in xrange(0, 10, 2): 665 yield i 666 self.set = Set((1, 2, 3)) 667 self.other = gen() 668 self.otherIsIterable = True 669 670 #------------------------------------------------------------------------------ 671 672 class TestOnlySetsofSets(TestOnlySetsInBinaryOps): 673 def setUp(self): 674 self.set = Set((1, 2, 3)) 675 self.other = [Set('ab'), ImmutableSet('cd')] 676 self.otherIsIterable = True 677 678 #============================================================================== 679 680 class TestCopying(unittest.TestCase): 681 682 def test_copy(self): 683 dup = self.set.copy() 684 self.assertEqual(len(dup), len(self.set)) 685 dup_list = sorted(dup) 686 set_list = sorted(self.set) 687 self.assertEqual(len(dup_list), len(set_list)) 688 for i, el in enumerate(dup_list): 689 self.assertIs(el, set_list[i]) 690 691 def test_deep_copy(self): 692 dup = copy.deepcopy(self.set) 693 self.assertSetEqual(dup, self.set) 694 695 #------------------------------------------------------------------------------ 696 697 class TestCopyingEmpty(TestCopying): 698 def setUp(self): 699 self.set = Set() 700 701 #------------------------------------------------------------------------------ 702 703 class TestCopyingSingleton(TestCopying): 704 def setUp(self): 705 self.set = Set(["hello"]) 706 707 #------------------------------------------------------------------------------ 708 709 class TestCopyingTriple(TestCopying): 710 def setUp(self): 711 self.set = Set(["zero", 0, None]) 712 713 def test_copy(self): 714 with test_support.check_py3k_warnings(): 715 super(TestCopyingTriple, self).test_copy() 716 717 #------------------------------------------------------------------------------ 718 719 class TestCopyingTuple(TestCopying): 720 def setUp(self): 721 self.set = Set([(1, 2)]) 722 723 #------------------------------------------------------------------------------ 724 725 class TestCopyingNested(TestCopying): 726 def setUp(self): 727 self.set = Set([((1, 2), (3, 4))]) 728 729 #============================================================================== 730 731 class TestIdentities(unittest.TestCase): 732 def setUp(self): 733 self.a = Set([random.randrange(100) for i in xrange(50)]) 734 self.b = Set([random.randrange(100) for i in xrange(50)]) 735 736 def test_binopsVsSubsets(self): 737 a, b = self.a, self.b 738 self.assertTrue(a - b <= a) 739 self.assertTrue(b - a <= b) 740 self.assertTrue(a & b <= a) 741 self.assertTrue(a & b <= b) 742 self.assertTrue(a | b >= a) 743 self.assertTrue(a | b >= b) 744 self.assertTrue(a ^ b <= a | b) 745 746 def test_commutativity(self): 747 a, b = self.a, self.b 748 self.assertEqual(a&b, b&a) 749 self.assertEqual(a|b, b|a) 750 self.assertEqual(a^b, b^a) 751 if a != b: 752 self.assertNotEqual(a-b, b-a) 753 754 def test_reflexsive_relations(self): 755 a, zero = self.a, Set() 756 self.assertEqual(a ^ a, zero) 757 self.assertEqual(a - a, zero) 758 self.assertEqual(a | a, a) 759 self.assertEqual(a & a, a) 760 self.assertTrue(a <= a) 761 self.assertTrue(a >= a) 762 self.assertTrue(a == a) 763 764 def test_summations(self): 765 # check that sums of parts equal the whole 766 a, b = self.a, self.b 767 self.assertEqual((a-b)|(a&b)|(b-a), a|b) 768 self.assertEqual((a&b)|(a^b), a|b) 769 self.assertEqual(a|(b-a), a|b) 770 self.assertEqual((a-b)|b, a|b) 771 self.assertEqual((a-b)|(a&b), a) 772 self.assertEqual((b-a)|(a&b), b) 773 self.assertEqual((a-b)|(b-a), a^b) 774 775 def test_exclusion(self): 776 # check that inverse operations do not overlap 777 a, b, zero = self.a, self.b, Set() 778 self.assertEqual((a-b)&b, zero) 779 self.assertEqual((b-a)&a, zero) 780 self.assertEqual((a&b)&(a^b), zero) 781 782 def test_cardinality_relations(self): 783 a, b = self.a, self.b 784 self.assertEqual(len(a), len(a-b) + len(a&b)) 785 self.assertEqual(len(b), len(b-a) + len(a&b)) 786 self.assertEqual(len(a^b), len(a-b) + len(b-a)) 787 self.assertEqual(len(a|b), len(a-b) + len(a&b) + len(b-a)) 788 self.assertEqual(len(a^b) + len(a&b), len(a|b)) 789 790 #============================================================================== 791 792 libreftest = """ 793 Example from the Library Reference: Doc/lib/libsets.tex 794 795 >>> from sets import Set as Base # override _repr to get sorted output 796 >>> class Set(Base): 797 ... def _repr(self): 798 ... return Base._repr(self, sorted=True) 799 >>> engineers = Set(['John', 'Jane', 'Jack', 'Janice']) 800 >>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice']) 801 >>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack']) 802 >>> employees = engineers | programmers | managers # union 803 >>> engineering_management = engineers & managers # intersection 804 >>> fulltime_management = managers - engineers - programmers # difference 805 >>> engineers.add('Marvin') 806 >>> print engineers 807 Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin']) 808 >>> employees.issuperset(engineers) # superset test 809 False 810 >>> employees.union_update(engineers) # update from another set 811 >>> employees.issuperset(engineers) 812 True 813 >>> for group in [engineers, programmers, managers, employees]: 814 ... group.discard('Susan') # unconditionally remove element 815 ... print group 816 ... 817 Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin']) 818 Set(['Jack', 'Janice', 'Sam']) 819 Set(['Jack', 'Jane', 'Zack']) 820 Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin', 'Sam', 'Zack']) 821 """ 822 823 #============================================================================== 824 825 __test__ = {'libreftest' : libreftest} 826 827 def test_main(verbose=None): 828 import doctest 829 from test import test_sets 830 test_support.run_unittest( 831 TestSetOfSets, 832 TestExceptionPropagation, 833 TestBasicOpsEmpty, 834 TestBasicOpsSingleton, 835 TestBasicOpsTuple, 836 TestBasicOpsTriple, 837 TestBinaryOps, 838 TestUpdateOps, 839 TestMutate, 840 TestSubsetEqualEmpty, 841 TestSubsetEqualNonEmpty, 842 TestSubsetEmptyNonEmpty, 843 TestSubsetPartial, 844 TestSubsetNonOverlap, 845 TestOnlySetsNumeric, 846 TestOnlySetsDict, 847 TestOnlySetsOperator, 848 TestOnlySetsTuple, 849 TestOnlySetsString, 850 TestOnlySetsGenerator, 851 TestOnlySetsofSets, 852 TestCopyingEmpty, 853 TestCopyingSingleton, 854 TestCopyingTriple, 855 TestCopyingTuple, 856 TestCopyingNested, 857 TestIdentities, 858 doctest.DocTestSuite(test_sets), 859 ) 860 861 if __name__ == "__main__": 862 test_main(verbose=True) 863