Home | History | Annotate | Download | only in test
      1 
      2 import unittest
      3 from test import test_support
      4 import gc
      5 import weakref
      6 import operator
      7 import copy
      8 import pickle
      9 from random import randrange, shuffle
     10 import sys
     11 import collections
     12 
     13 class PassThru(Exception):
     14     pass
     15 
     16 def check_pass_thru():
     17     raise PassThru
     18     yield 1
     19 
     20 class BadCmp:
     21     def __hash__(self):
     22         return 1
     23     def __cmp__(self, other):
     24         raise RuntimeError
     25 
     26 class ReprWrapper:
     27     'Used to test self-referential repr() calls'
     28     def __repr__(self):
     29         return repr(self.value)
     30 
     31 class HashCountingInt(int):
     32     'int-like object that counts the number of times __hash__ is called'
     33     def __init__(self, *args):
     34         self.hash_count = 0
     35     def __hash__(self):
     36         self.hash_count += 1
     37         return int.__hash__(self)
     38 
     39 class TestJointOps(unittest.TestCase):
     40     # Tests common to both set and frozenset
     41 
     42     def setUp(self):
     43         self.word = word = 'simsalabim'
     44         self.otherword = 'madagascar'
     45         self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
     46         self.s = self.thetype(word)
     47         self.d = dict.fromkeys(word)
     48 
     49     def test_new_or_init(self):
     50         self.assertRaises(TypeError, self.thetype, [], 2)
     51         self.assertRaises(TypeError, set().__init__, a=1)
     52 
     53     def test_uniquification(self):
     54         actual = sorted(self.s)
     55         expected = sorted(self.d)
     56         self.assertEqual(actual, expected)
     57         self.assertRaises(PassThru, self.thetype, check_pass_thru())
     58         self.assertRaises(TypeError, self.thetype, [[]])
     59 
     60     def test_len(self):
     61         self.assertEqual(len(self.s), len(self.d))
     62 
     63     def test_contains(self):
     64         for c in self.letters:
     65             self.assertEqual(c in self.s, c in self.d)
     66         self.assertRaises(TypeError, self.s.__contains__, [[]])
     67         s = self.thetype([frozenset(self.letters)])
     68         self.assertIn(self.thetype(self.letters), s)
     69 
     70     def test_union(self):
     71         u = self.s.union(self.otherword)
     72         for c in self.letters:
     73             self.assertEqual(c in u, c in self.d or c in self.otherword)
     74         self.assertEqual(self.s, self.thetype(self.word))
     75         self.assertEqual(type(u), self.thetype)
     76         self.assertRaises(PassThru, self.s.union, check_pass_thru())
     77         self.assertRaises(TypeError, self.s.union, [[]])
     78         for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
     79             self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
     80             self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
     81             self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
     82             self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
     83             self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
     84 
     85         # Issue #6573
     86         x = self.thetype()
     87         self.assertEqual(x.union(set([1]), x, set([2])), self.thetype([1, 2]))
     88 
     89     def test_or(self):
     90         i = self.s.union(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_intersection(self):
    101         i = self.s.intersection(self.otherword)
    102         for c in self.letters:
    103             self.assertEqual(c in i, c in self.d and c in self.otherword)
    104         self.assertEqual(self.s, self.thetype(self.word))
    105         self.assertEqual(type(i), self.thetype)
    106         self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
    107         for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
    108             self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
    109             self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
    110             self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
    111             self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
    112             self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
    113         s = self.thetype('abcba')
    114         z = s.intersection()
    115         if self.thetype == frozenset():
    116             self.assertEqual(id(s), id(z))
    117         else:
    118             self.assertNotEqual(id(s), id(z))
    119 
    120     def test_isdisjoint(self):
    121         def f(s1, s2):
    122             'Pure python equivalent of isdisjoint()'
    123             return not set(s1).intersection(s2)
    124         for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
    125             s1 = self.thetype(larg)
    126             for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
    127                 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
    128                     s2 = C(rarg)
    129                     actual = s1.isdisjoint(s2)
    130                     expected = f(s1, s2)
    131                     self.assertEqual(actual, expected)
    132                     self.assertTrue(actual is True or actual is False)
    133 
    134     def test_and(self):
    135         i = self.s.intersection(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_difference(self):
    146         i = self.s.difference(self.otherword)
    147         for c in self.letters:
    148             self.assertEqual(c in i, c in self.d and c not in self.otherword)
    149         self.assertEqual(self.s, self.thetype(self.word))
    150         self.assertEqual(type(i), self.thetype)
    151         self.assertRaises(PassThru, self.s.difference, check_pass_thru())
    152         self.assertRaises(TypeError, self.s.difference, [[]])
    153         for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
    154             self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
    155             self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
    156             self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
    157             self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
    158             self.assertEqual(self.thetype('abcba').difference(), set('abc'))
    159             self.assertEqual(self.thetype('abcba').difference(C('a'), C('b')), set('c'))
    160 
    161     def test_sub(self):
    162         i = self.s.difference(self.otherword)
    163         self.assertEqual(self.s - set(self.otherword), i)
    164         self.assertEqual(self.s - frozenset(self.otherword), i)
    165         try:
    166             self.s - self.otherword
    167         except TypeError:
    168             pass
    169         else:
    170             self.fail("s-t did not screen-out general iterables")
    171 
    172     def test_symmetric_difference(self):
    173         i = self.s.symmetric_difference(self.otherword)
    174         for c in self.letters:
    175             self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
    176         self.assertEqual(self.s, self.thetype(self.word))
    177         self.assertEqual(type(i), self.thetype)
    178         self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
    179         self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
    180         for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
    181             self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
    182             self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
    183             self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
    184             self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
    185 
    186     def test_xor(self):
    187         i = self.s.symmetric_difference(self.otherword)
    188         self.assertEqual(self.s ^ set(self.otherword), i)
    189         self.assertEqual(self.s ^ frozenset(self.otherword), i)
    190         try:
    191             self.s ^ self.otherword
    192         except TypeError:
    193             pass
    194         else:
    195             self.fail("s^t did not screen-out general iterables")
    196 
    197     def test_equality(self):
    198         self.assertEqual(self.s, set(self.word))
    199         self.assertEqual(self.s, frozenset(self.word))
    200         self.assertEqual(self.s == self.word, False)
    201         self.assertNotEqual(self.s, set(self.otherword))
    202         self.assertNotEqual(self.s, frozenset(self.otherword))
    203         self.assertEqual(self.s != self.word, True)
    204 
    205     def test_setOfFrozensets(self):
    206         t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
    207         s = self.thetype(t)
    208         self.assertEqual(len(s), 3)
    209 
    210     def test_compare(self):
    211         self.assertRaises(TypeError, self.s.__cmp__, self.s)
    212 
    213     def test_sub_and_super(self):
    214         p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
    215         self.assertTrue(p < q)
    216         self.assertTrue(p <= q)
    217         self.assertTrue(q <= q)
    218         self.assertTrue(q > p)
    219         self.assertTrue(q >= p)
    220         self.assertFalse(q < r)
    221         self.assertFalse(q <= r)
    222         self.assertFalse(q > r)
    223         self.assertFalse(q >= r)
    224         self.assertTrue(set('a').issubset('abc'))
    225         self.assertTrue(set('abc').issuperset('a'))
    226         self.assertFalse(set('a').issubset('cbs'))
    227         self.assertFalse(set('cbs').issuperset('a'))
    228 
    229     def test_pickling(self):
    230         for i in range(pickle.HIGHEST_PROTOCOL + 1):
    231             p = pickle.dumps(self.s, i)
    232             dup = pickle.loads(p)
    233             self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
    234             if type(self.s) not in (set, frozenset):
    235                 self.s.x = 10
    236                 p = pickle.dumps(self.s)
    237                 dup = pickle.loads(p)
    238                 self.assertEqual(self.s.x, dup.x)
    239 
    240     def test_deepcopy(self):
    241         class Tracer:
    242             def __init__(self, value):
    243                 self.value = value
    244             def __hash__(self):
    245                 return self.value
    246             def __deepcopy__(self, memo=None):
    247                 return Tracer(self.value + 1)
    248         t = Tracer(10)
    249         s = self.thetype([t])
    250         dup = copy.deepcopy(s)
    251         self.assertNotEqual(id(s), id(dup))
    252         for elem in dup:
    253             newt = elem
    254         self.assertNotEqual(id(t), id(newt))
    255         self.assertEqual(t.value + 1, newt.value)
    256 
    257     def test_gc(self):
    258         # Create a nest of cycles to exercise overall ref count check
    259         class A:
    260             pass
    261         s = set(A() for i in xrange(1000))
    262         for elem in s:
    263             elem.cycle = s
    264             elem.sub = elem
    265             elem.set = set([elem])
    266 
    267     def test_subclass_with_custom_hash(self):
    268         # Bug #1257731
    269         class H(self.thetype):
    270             def __hash__(self):
    271                 return int(id(self) & 0x7fffffff)
    272         s=H()
    273         f=set()
    274         f.add(s)
    275         self.assertIn(s, f)
    276         f.remove(s)
    277         f.add(s)
    278         f.discard(s)
    279 
    280     def test_badcmp(self):
    281         s = self.thetype([BadCmp()])
    282         # Detect comparison errors during insertion and lookup
    283         self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
    284         self.assertRaises(RuntimeError, s.__contains__, BadCmp())
    285         # Detect errors during mutating operations
    286         if hasattr(s, 'add'):
    287             self.assertRaises(RuntimeError, s.add, BadCmp())
    288             self.assertRaises(RuntimeError, s.discard, BadCmp())
    289             self.assertRaises(RuntimeError, s.remove, BadCmp())
    290 
    291     def test_cyclical_repr(self):
    292         w = ReprWrapper()
    293         s = self.thetype([w])
    294         w.value = s
    295         name = repr(s).partition('(')[0]    # strip class name from repr string
    296         self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
    297 
    298     def test_cyclical_print(self):
    299         w = ReprWrapper()
    300         s = self.thetype([w])
    301         w.value = s
    302         fo = open(test_support.TESTFN, "wb")
    303         try:
    304             print >> fo, s,
    305             fo.close()
    306             fo = open(test_support.TESTFN, "rb")
    307             self.assertEqual(fo.read(), repr(s))
    308         finally:
    309             fo.close()
    310             test_support.unlink(test_support.TESTFN)
    311 
    312     def test_do_not_rehash_dict_keys(self):
    313         n = 10
    314         d = dict.fromkeys(map(HashCountingInt, xrange(n)))
    315         self.assertEqual(sum(elem.hash_count for elem in d), n)
    316         s = self.thetype(d)
    317         self.assertEqual(sum(elem.hash_count for elem in d), n)
    318         s.difference(d)
    319         self.assertEqual(sum(elem.hash_count for elem in d), n)
    320         if hasattr(s, 'symmetric_difference_update'):
    321             s.symmetric_difference_update(d)
    322         self.assertEqual(sum(elem.hash_count for elem in d), n)
    323         d2 = dict.fromkeys(set(d))
    324         self.assertEqual(sum(elem.hash_count for elem in d), n)
    325         d3 = dict.fromkeys(frozenset(d))
    326         self.assertEqual(sum(elem.hash_count for elem in d), n)
    327         d3 = dict.fromkeys(frozenset(d), 123)
    328         self.assertEqual(sum(elem.hash_count for elem in d), n)
    329         self.assertEqual(d3, dict.fromkeys(d, 123))
    330 
    331     def test_container_iterator(self):
    332         # Bug #3680: tp_traverse was not implemented for set iterator object
    333         class C(object):
    334             pass
    335         obj = C()
    336         ref = weakref.ref(obj)
    337         container = set([obj, 1])
    338         obj.x = iter(container)
    339         del obj, container
    340         gc.collect()
    341         self.assertTrue(ref() is None, "Cycle was not collected")
    342 
    343 class TestSet(TestJointOps):
    344     thetype = set
    345 
    346     def test_init(self):
    347         s = self.thetype()
    348         s.__init__(self.word)
    349         self.assertEqual(s, set(self.word))
    350         s.__init__(self.otherword)
    351         self.assertEqual(s, set(self.otherword))
    352         self.assertRaises(TypeError, s.__init__, s, 2);
    353         self.assertRaises(TypeError, s.__init__, 1);
    354 
    355     def test_constructor_identity(self):
    356         s = self.thetype(range(3))
    357         t = self.thetype(s)
    358         self.assertNotEqual(id(s), id(t))
    359 
    360     def test_hash(self):
    361         self.assertRaises(TypeError, hash, self.s)
    362 
    363     def test_clear(self):
    364         self.s.clear()
    365         self.assertEqual(self.s, set())
    366         self.assertEqual(len(self.s), 0)
    367 
    368     def test_copy(self):
    369         dup = self.s.copy()
    370         self.assertEqual(self.s, dup)
    371         self.assertNotEqual(id(self.s), id(dup))
    372 
    373     def test_add(self):
    374         self.s.add('Q')
    375         self.assertIn('Q', self.s)
    376         dup = self.s.copy()
    377         self.s.add('Q')
    378         self.assertEqual(self.s, dup)
    379         self.assertRaises(TypeError, self.s.add, [])
    380 
    381     def test_remove(self):
    382         self.s.remove('a')
    383         self.assertNotIn('a', self.s)
    384         self.assertRaises(KeyError, self.s.remove, 'Q')
    385         self.assertRaises(TypeError, self.s.remove, [])
    386         s = self.thetype([frozenset(self.word)])
    387         self.assertIn(self.thetype(self.word), s)
    388         s.remove(self.thetype(self.word))
    389         self.assertNotIn(self.thetype(self.word), s)
    390         self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
    391 
    392     def test_remove_keyerror_unpacking(self):
    393         # bug:  www.python.org/sf/1576657
    394         for v1 in ['Q', (1,)]:
    395             try:
    396                 self.s.remove(v1)
    397             except KeyError, e:
    398                 v2 = e.args[0]
    399                 self.assertEqual(v1, v2)
    400             else:
    401                 self.fail()
    402 
    403     def test_remove_keyerror_set(self):
    404         key = self.thetype([3, 4])
    405         try:
    406             self.s.remove(key)
    407         except KeyError as e:
    408             self.assertTrue(e.args[0] is key,
    409                          "KeyError should be {0}, not {1}".format(key,
    410                                                                   e.args[0]))
    411         else:
    412             self.fail()
    413 
    414     def test_discard(self):
    415         self.s.discard('a')
    416         self.assertNotIn('a', self.s)
    417         self.s.discard('Q')
    418         self.assertRaises(TypeError, self.s.discard, [])
    419         s = self.thetype([frozenset(self.word)])
    420         self.assertIn(self.thetype(self.word), s)
    421         s.discard(self.thetype(self.word))
    422         self.assertNotIn(self.thetype(self.word), s)
    423         s.discard(self.thetype(self.word))
    424 
    425     def test_pop(self):
    426         for i in xrange(len(self.s)):
    427             elem = self.s.pop()
    428             self.assertNotIn(elem, self.s)
    429         self.assertRaises(KeyError, self.s.pop)
    430 
    431     def test_update(self):
    432         retval = self.s.update(self.otherword)
    433         self.assertEqual(retval, None)
    434         for c in (self.word + self.otherword):
    435             self.assertIn(c, self.s)
    436         self.assertRaises(PassThru, self.s.update, check_pass_thru())
    437         self.assertRaises(TypeError, self.s.update, [[]])
    438         for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
    439             for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
    440                 s = self.thetype('abcba')
    441                 self.assertEqual(s.update(C(p)), None)
    442                 self.assertEqual(s, set(q))
    443         for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
    444             q = 'ahi'
    445             for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
    446                 s = self.thetype('abcba')
    447                 self.assertEqual(s.update(C(p), C(q)), None)
    448                 self.assertEqual(s, set(s) | set(p) | set(q))
    449 
    450     def test_ior(self):
    451         self.s |= set(self.otherword)
    452         for c in (self.word + self.otherword):
    453             self.assertIn(c, self.s)
    454 
    455     def test_intersection_update(self):
    456         retval = self.s.intersection_update(self.otherword)
    457         self.assertEqual(retval, None)
    458         for c in (self.word + self.otherword):
    459             if c in self.otherword and c in self.word:
    460                 self.assertIn(c, self.s)
    461             else:
    462                 self.assertNotIn(c, self.s)
    463         self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
    464         self.assertRaises(TypeError, self.s.intersection_update, [[]])
    465         for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
    466             for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
    467                 s = self.thetype('abcba')
    468                 self.assertEqual(s.intersection_update(C(p)), None)
    469                 self.assertEqual(s, set(q))
    470                 ss = 'abcba'
    471                 s = self.thetype(ss)
    472                 t = 'cbc'
    473                 self.assertEqual(s.intersection_update(C(p), C(t)), None)
    474                 self.assertEqual(s, set('abcba')&set(p)&set(t))
    475 
    476     def test_iand(self):
    477         self.s &= set(self.otherword)
    478         for c in (self.word + self.otherword):
    479             if c in self.otherword and c in self.word:
    480                 self.assertIn(c, self.s)
    481             else:
    482                 self.assertNotIn(c, self.s)
    483 
    484     def test_difference_update(self):
    485         retval = self.s.difference_update(self.otherword)
    486         self.assertEqual(retval, None)
    487         for c in (self.word + self.otherword):
    488             if c in self.word and c not in self.otherword:
    489                 self.assertIn(c, self.s)
    490             else:
    491                 self.assertNotIn(c, self.s)
    492         self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
    493         self.assertRaises(TypeError, self.s.difference_update, [[]])
    494         self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
    495         for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
    496             for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
    497                 s = self.thetype('abcba')
    498                 self.assertEqual(s.difference_update(C(p)), None)
    499                 self.assertEqual(s, set(q))
    500 
    501                 s = self.thetype('abcdefghih')
    502                 s.difference_update()
    503                 self.assertEqual(s, self.thetype('abcdefghih'))
    504 
    505                 s = self.thetype('abcdefghih')
    506                 s.difference_update(C('aba'))
    507                 self.assertEqual(s, self.thetype('cdefghih'))
    508 
    509                 s = self.thetype('abcdefghih')
    510                 s.difference_update(C('cdc'), C('aba'))
    511                 self.assertEqual(s, self.thetype('efghih'))
    512 
    513     def test_isub(self):
    514         self.s -= set(self.otherword)
    515         for c in (self.word + self.otherword):
    516             if c in self.word and c not in self.otherword:
    517                 self.assertIn(c, self.s)
    518             else:
    519                 self.assertNotIn(c, self.s)
    520 
    521     def test_symmetric_difference_update(self):
    522         retval = self.s.symmetric_difference_update(self.otherword)
    523         self.assertEqual(retval, None)
    524         for c in (self.word + self.otherword):
    525             if (c in self.word) ^ (c in self.otherword):
    526                 self.assertIn(c, self.s)
    527             else:
    528                 self.assertNotIn(c, self.s)
    529         self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
    530         self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
    531         for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
    532             for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
    533                 s = self.thetype('abcba')
    534                 self.assertEqual(s.symmetric_difference_update(C(p)), None)
    535                 self.assertEqual(s, set(q))
    536 
    537     def test_ixor(self):
    538         self.s ^= set(self.otherword)
    539         for c in (self.word + self.otherword):
    540             if (c in self.word) ^ (c in self.otherword):
    541                 self.assertIn(c, self.s)
    542             else:
    543                 self.assertNotIn(c, self.s)
    544 
    545     def test_inplace_on_self(self):
    546         t = self.s.copy()
    547         t |= t
    548         self.assertEqual(t, self.s)
    549         t &= t
    550         self.assertEqual(t, self.s)
    551         t -= t
    552         self.assertEqual(t, self.thetype())
    553         t = self.s.copy()
    554         t ^= t
    555         self.assertEqual(t, self.thetype())
    556 
    557     def test_weakref(self):
    558         s = self.thetype('gallahad')
    559         p = weakref.proxy(s)
    560         self.assertEqual(str(p), str(s))
    561         s = None
    562         self.assertRaises(ReferenceError, str, p)
    563 
    564     # C API test only available in a debug build
    565     if hasattr(set, "test_c_api"):
    566         def test_c_api(self):
    567             self.assertEqual(set().test_c_api(), True)
    568 
    569 class SetSubclass(set):
    570     pass
    571 
    572 class TestSetSubclass(TestSet):
    573     thetype = SetSubclass
    574 
    575 class SetSubclassWithKeywordArgs(set):
    576     def __init__(self, iterable=[], newarg=None):
    577         set.__init__(self, iterable)
    578 
    579 class TestSetSubclassWithKeywordArgs(TestSet):
    580 
    581     def test_keywords_in_subclass(self):
    582         'SF bug #1486663 -- this used to erroneously raise a TypeError'
    583         SetSubclassWithKeywordArgs(newarg=1)
    584 
    585 class TestFrozenSet(TestJointOps):
    586     thetype = frozenset
    587 
    588     def test_init(self):
    589         s = self.thetype(self.word)
    590         s.__init__(self.otherword)
    591         self.assertEqual(s, set(self.word))
    592 
    593     def test_singleton_empty_frozenset(self):
    594         f = frozenset()
    595         efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
    596                frozenset(), frozenset([]), frozenset(()), frozenset(''),
    597                frozenset(xrange(0)), frozenset(frozenset()),
    598                frozenset(f), f]
    599         # All of the empty frozensets should have just one id()
    600         self.assertEqual(len(set(map(id, efs))), 1)
    601 
    602     def test_constructor_identity(self):
    603         s = self.thetype(range(3))
    604         t = self.thetype(s)
    605         self.assertEqual(id(s), id(t))
    606 
    607     def test_hash(self):
    608         self.assertEqual(hash(self.thetype('abcdeb')),
    609                          hash(self.thetype('ebecda')))
    610 
    611         # make sure that all permutations give the same hash value
    612         n = 100
    613         seq = [randrange(n) for i in xrange(n)]
    614         results = set()
    615         for i in xrange(200):
    616             shuffle(seq)
    617             results.add(hash(self.thetype(seq)))
    618         self.assertEqual(len(results), 1)
    619 
    620     def test_copy(self):
    621         dup = self.s.copy()
    622         self.assertEqual(id(self.s), id(dup))
    623 
    624     def test_frozen_as_dictkey(self):
    625         seq = range(10) + list('abcdefg') + ['apple']
    626         key1 = self.thetype(seq)
    627         key2 = self.thetype(reversed(seq))
    628         self.assertEqual(key1, key2)
    629         self.assertNotEqual(id(key1), id(key2))
    630         d = {}
    631         d[key1] = 42
    632         self.assertEqual(d[key2], 42)
    633 
    634     def test_hash_caching(self):
    635         f = self.thetype('abcdcda')
    636         self.assertEqual(hash(f), hash(f))
    637 
    638     def test_hash_effectiveness(self):
    639         n = 13
    640         hashvalues = set()
    641         addhashvalue = hashvalues.add
    642         elemmasks = [(i+1, 1<<i) for i in range(n)]
    643         for i in xrange(2**n):
    644             addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
    645         self.assertEqual(len(hashvalues), 2**n)
    646 
    647 class FrozenSetSubclass(frozenset):
    648     pass
    649 
    650 class TestFrozenSetSubclass(TestFrozenSet):
    651     thetype = FrozenSetSubclass
    652 
    653     def test_constructor_identity(self):
    654         s = self.thetype(range(3))
    655         t = self.thetype(s)
    656         self.assertNotEqual(id(s), id(t))
    657 
    658     def test_copy(self):
    659         dup = self.s.copy()
    660         self.assertNotEqual(id(self.s), id(dup))
    661 
    662     def test_nested_empty_constructor(self):
    663         s = self.thetype()
    664         t = self.thetype(s)
    665         self.assertEqual(s, t)
    666 
    667     def test_singleton_empty_frozenset(self):
    668         Frozenset = self.thetype
    669         f = frozenset()
    670         F = Frozenset()
    671         efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
    672                Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
    673                Frozenset(xrange(0)), Frozenset(Frozenset()),
    674                Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
    675         # All empty frozenset subclass instances should have different ids
    676         self.assertEqual(len(set(map(id, efs))), len(efs))
    677 
    678 # Tests taken from test_sets.py =============================================
    679 
    680 empty_set = set()
    681 
    682 #==============================================================================
    683 
    684 class TestBasicOps(unittest.TestCase):
    685 
    686     def test_repr(self):
    687         if self.repr is not None:
    688             self.assertEqual(repr(self.set), self.repr)
    689 
    690     def check_repr_against_values(self):
    691         text = repr(self.set)
    692         self.assertTrue(text.startswith('{'))
    693         self.assertTrue(text.endswith('}'))
    694 
    695         result = text[1:-1].split(', ')
    696         result.sort()
    697         sorted_repr_values = [repr(value) for value in self.values]
    698         sorted_repr_values.sort()
    699         self.assertEqual(result, sorted_repr_values)
    700 
    701     def test_print(self):
    702         fo = open(test_support.TESTFN, "wb")
    703         try:
    704             print >> fo, self.set,
    705             fo.close()
    706             fo = open(test_support.TESTFN, "rb")
    707             self.assertEqual(fo.read(), repr(self.set))
    708         finally:
    709             fo.close()
    710             test_support.unlink(test_support.TESTFN)
    711 
    712     def test_length(self):
    713         self.assertEqual(len(self.set), self.length)
    714 
    715     def test_self_equality(self):
    716         self.assertEqual(self.set, self.set)
    717 
    718     def test_equivalent_equality(self):
    719         self.assertEqual(self.set, self.dup)
    720 
    721     def test_copy(self):
    722         self.assertEqual(self.set.copy(), self.dup)
    723 
    724     def test_self_union(self):
    725         result = self.set | self.set
    726         self.assertEqual(result, self.dup)
    727 
    728     def test_empty_union(self):
    729         result = self.set | empty_set
    730         self.assertEqual(result, self.dup)
    731 
    732     def test_union_empty(self):
    733         result = empty_set | self.set
    734         self.assertEqual(result, self.dup)
    735 
    736     def test_self_intersection(self):
    737         result = self.set & self.set
    738         self.assertEqual(result, self.dup)
    739 
    740     def test_empty_intersection(self):
    741         result = self.set & empty_set
    742         self.assertEqual(result, empty_set)
    743 
    744     def test_intersection_empty(self):
    745         result = empty_set & self.set
    746         self.assertEqual(result, empty_set)
    747 
    748     def test_self_isdisjoint(self):
    749         result = self.set.isdisjoint(self.set)
    750         self.assertEqual(result, not self.set)
    751 
    752     def test_empty_isdisjoint(self):
    753         result = self.set.isdisjoint(empty_set)
    754         self.assertEqual(result, True)
    755 
    756     def test_isdisjoint_empty(self):
    757         result = empty_set.isdisjoint(self.set)
    758         self.assertEqual(result, True)
    759 
    760     def test_self_symmetric_difference(self):
    761         result = self.set ^ self.set
    762         self.assertEqual(result, empty_set)
    763 
    764     def test_empty_symmetric_difference(self):
    765         result = self.set ^ empty_set
    766         self.assertEqual(result, self.set)
    767 
    768     def test_self_difference(self):
    769         result = self.set - self.set
    770         self.assertEqual(result, empty_set)
    771 
    772     def test_empty_difference(self):
    773         result = self.set - empty_set
    774         self.assertEqual(result, self.dup)
    775 
    776     def test_empty_difference_rev(self):
    777         result = empty_set - self.set
    778         self.assertEqual(result, empty_set)
    779 
    780     def test_iteration(self):
    781         for v in self.set:
    782             self.assertIn(v, self.values)
    783         setiter = iter(self.set)
    784         # note: __length_hint__ is an internal undocumented API,
    785         # don't rely on it in your own programs
    786         self.assertEqual(setiter.__length_hint__(), len(self.set))
    787 
    788     def test_pickling(self):
    789         p = pickle.dumps(self.set)
    790         copy = pickle.loads(p)
    791         self.assertEqual(self.set, copy,
    792                          "%s != %s" % (self.set, copy))
    793 
    794 #------------------------------------------------------------------------------
    795 
    796 class TestBasicOpsEmpty(TestBasicOps):
    797     def setUp(self):
    798         self.case   = "empty set"
    799         self.values = []
    800         self.set    = set(self.values)
    801         self.dup    = set(self.values)
    802         self.length = 0
    803         self.repr   = "set([])"
    804 
    805 #------------------------------------------------------------------------------
    806 
    807 class TestBasicOpsSingleton(TestBasicOps):
    808     def setUp(self):
    809         self.case   = "unit set (number)"
    810         self.values = [3]
    811         self.set    = set(self.values)
    812         self.dup    = set(self.values)
    813         self.length = 1
    814         self.repr   = "set([3])"
    815 
    816     def test_in(self):
    817         self.assertIn(3, self.set)
    818 
    819     def test_not_in(self):
    820         self.assertNotIn(2, self.set)
    821 
    822 #------------------------------------------------------------------------------
    823 
    824 class TestBasicOpsTuple(TestBasicOps):
    825     def setUp(self):
    826         self.case   = "unit set (tuple)"
    827         self.values = [(0, "zero")]
    828         self.set    = set(self.values)
    829         self.dup    = set(self.values)
    830         self.length = 1
    831         self.repr   = "set([(0, 'zero')])"
    832 
    833     def test_in(self):
    834         self.assertIn((0, "zero"), self.set)
    835 
    836     def test_not_in(self):
    837         self.assertNotIn(9, self.set)
    838 
    839 #------------------------------------------------------------------------------
    840 
    841 class TestBasicOpsTriple(TestBasicOps):
    842     def setUp(self):
    843         self.case   = "triple set"
    844         self.values = [0, "zero", operator.add]
    845         self.set    = set(self.values)
    846         self.dup    = set(self.values)
    847         self.length = 3
    848         self.repr   = None
    849 
    850 #------------------------------------------------------------------------------
    851 
    852 class TestBasicOpsString(TestBasicOps):
    853     def setUp(self):
    854         self.case   = "string set"
    855         self.values = ["a", "b", "c"]
    856         self.set    = set(self.values)
    857         self.dup    = set(self.values)
    858         self.length = 3
    859 
    860     def test_repr(self):
    861         self.check_repr_against_values()
    862 
    863 #------------------------------------------------------------------------------
    864 
    865 class TestBasicOpsUnicode(TestBasicOps):
    866     def setUp(self):
    867         self.case   = "unicode set"
    868         self.values = [u"a", u"b", u"c"]
    869         self.set    = set(self.values)
    870         self.dup    = set(self.values)
    871         self.length = 3
    872 
    873     def test_repr(self):
    874         self.check_repr_against_values()
    875 
    876 #------------------------------------------------------------------------------
    877 
    878 class TestBasicOpsMixedStringUnicode(TestBasicOps):
    879     def setUp(self):
    880         self.case   = "string and bytes set"
    881         self.values = ["a", "b", u"a", u"b"]
    882         self.set    = set(self.values)
    883         self.dup    = set(self.values)
    884         self.length = 4
    885 
    886     def test_repr(self):
    887         with test_support.check_warnings():
    888             self.check_repr_against_values()
    889 
    890 #==============================================================================
    891 
    892 def baditer():
    893     raise TypeError
    894     yield True
    895 
    896 def gooditer():
    897     yield True
    898 
    899 class TestExceptionPropagation(unittest.TestCase):
    900     """SF 628246:  Set constructor should not trap iterator TypeErrors"""
    901 
    902     def test_instanceWithException(self):
    903         self.assertRaises(TypeError, set, baditer())
    904 
    905     def test_instancesWithoutException(self):
    906         # All of these iterables should load without exception.
    907         set([1,2,3])
    908         set((1,2,3))
    909         set({'one':1, 'two':2, 'three':3})
    910         set(xrange(3))
    911         set('abc')
    912         set(gooditer())
    913 
    914     def test_changingSizeWhileIterating(self):
    915         s = set([1,2,3])
    916         try:
    917             for i in s:
    918                 s.update([4])
    919         except RuntimeError:
    920             pass
    921         else:
    922             self.fail("no exception when changing size during iteration")
    923 
    924 #==============================================================================
    925 
    926 class TestSetOfSets(unittest.TestCase):
    927     def test_constructor(self):
    928         inner = frozenset([1])
    929         outer = set([inner])
    930         element = outer.pop()
    931         self.assertEqual(type(element), frozenset)
    932         outer.add(inner)        # Rebuild set of sets with .add method
    933         outer.remove(inner)
    934         self.assertEqual(outer, set())   # Verify that remove worked
    935         outer.discard(inner)    # Absence of KeyError indicates working fine
    936 
    937 #==============================================================================
    938 
    939 class TestBinaryOps(unittest.TestCase):
    940     def setUp(self):
    941         self.set = set((2, 4, 6))
    942 
    943     def test_eq(self):              # SF bug 643115
    944         self.assertEqual(self.set, set({2:1,4:3,6:5}))
    945 
    946     def test_union_subset(self):
    947         result = self.set | set([2])
    948         self.assertEqual(result, set((2, 4, 6)))
    949 
    950     def test_union_superset(self):
    951         result = self.set | set([2, 4, 6, 8])
    952         self.assertEqual(result, set([2, 4, 6, 8]))
    953 
    954     def test_union_overlap(self):
    955         result = self.set | set([3, 4, 5])
    956         self.assertEqual(result, set([2, 3, 4, 5, 6]))
    957 
    958     def test_union_non_overlap(self):
    959         result = self.set | set([8])
    960         self.assertEqual(result, set([2, 4, 6, 8]))
    961 
    962     def test_intersection_subset(self):
    963         result = self.set & set((2, 4))
    964         self.assertEqual(result, set((2, 4)))
    965 
    966     def test_intersection_superset(self):
    967         result = self.set & set([2, 4, 6, 8])
    968         self.assertEqual(result, set([2, 4, 6]))
    969 
    970     def test_intersection_overlap(self):
    971         result = self.set & set([3, 4, 5])
    972         self.assertEqual(result, set([4]))
    973 
    974     def test_intersection_non_overlap(self):
    975         result = self.set & set([8])
    976         self.assertEqual(result, empty_set)
    977 
    978     def test_isdisjoint_subset(self):
    979         result = self.set.isdisjoint(set((2, 4)))
    980         self.assertEqual(result, False)
    981 
    982     def test_isdisjoint_superset(self):
    983         result = self.set.isdisjoint(set([2, 4, 6, 8]))
    984         self.assertEqual(result, False)
    985 
    986     def test_isdisjoint_overlap(self):
    987         result = self.set.isdisjoint(set([3, 4, 5]))
    988         self.assertEqual(result, False)
    989 
    990     def test_isdisjoint_non_overlap(self):
    991         result = self.set.isdisjoint(set([8]))
    992         self.assertEqual(result, True)
    993 
    994     def test_sym_difference_subset(self):
    995         result = self.set ^ set((2, 4))
    996         self.assertEqual(result, set([6]))
    997 
    998     def test_sym_difference_superset(self):
    999         result = self.set ^ set((2, 4, 6, 8))
   1000         self.assertEqual(result, set([8]))
   1001 
   1002     def test_sym_difference_overlap(self):
   1003         result = self.set ^ set((3, 4, 5))
   1004         self.assertEqual(result, set([2, 3, 5, 6]))
   1005 
   1006     def test_sym_difference_non_overlap(self):
   1007         result = self.set ^ set([8])
   1008         self.assertEqual(result, set([2, 4, 6, 8]))
   1009 
   1010     def test_cmp(self):
   1011         a, b = set('a'), set('b')
   1012         self.assertRaises(TypeError, cmp, a, b)
   1013 
   1014         # You can view this as a buglet:  cmp(a, a) does not raise TypeError,
   1015         # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
   1016         # which Python thinks is good enough to synthesize a cmp() result
   1017         # without calling __cmp__.
   1018         self.assertEqual(cmp(a, a), 0)
   1019 
   1020         self.assertRaises(TypeError, cmp, a, 12)
   1021         self.assertRaises(TypeError, cmp, "abc", a)
   1022 
   1023 #==============================================================================
   1024 
   1025 class TestUpdateOps(unittest.TestCase):
   1026     def setUp(self):
   1027         self.set = set((2, 4, 6))
   1028 
   1029     def test_union_subset(self):
   1030         self.set |= set([2])
   1031         self.assertEqual(self.set, set((2, 4, 6)))
   1032 
   1033     def test_union_superset(self):
   1034         self.set |= set([2, 4, 6, 8])
   1035         self.assertEqual(self.set, set([2, 4, 6, 8]))
   1036 
   1037     def test_union_overlap(self):
   1038         self.set |= set([3, 4, 5])
   1039         self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
   1040 
   1041     def test_union_non_overlap(self):
   1042         self.set |= set([8])
   1043         self.assertEqual(self.set, set([2, 4, 6, 8]))
   1044 
   1045     def test_union_method_call(self):
   1046         self.set.update(set([3, 4, 5]))
   1047         self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
   1048 
   1049     def test_intersection_subset(self):
   1050         self.set &= set((2, 4))
   1051         self.assertEqual(self.set, set((2, 4)))
   1052 
   1053     def test_intersection_superset(self):
   1054         self.set &= set([2, 4, 6, 8])
   1055         self.assertEqual(self.set, set([2, 4, 6]))
   1056 
   1057     def test_intersection_overlap(self):
   1058         self.set &= set([3, 4, 5])
   1059         self.assertEqual(self.set, set([4]))
   1060 
   1061     def test_intersection_non_overlap(self):
   1062         self.set &= set([8])
   1063         self.assertEqual(self.set, empty_set)
   1064 
   1065     def test_intersection_method_call(self):
   1066         self.set.intersection_update(set([3, 4, 5]))
   1067         self.assertEqual(self.set, set([4]))
   1068 
   1069     def test_sym_difference_subset(self):
   1070         self.set ^= set((2, 4))
   1071         self.assertEqual(self.set, set([6]))
   1072 
   1073     def test_sym_difference_superset(self):
   1074         self.set ^= set((2, 4, 6, 8))
   1075         self.assertEqual(self.set, set([8]))
   1076 
   1077     def test_sym_difference_overlap(self):
   1078         self.set ^= set((3, 4, 5))
   1079         self.assertEqual(self.set, set([2, 3, 5, 6]))
   1080 
   1081     def test_sym_difference_non_overlap(self):
   1082         self.set ^= set([8])
   1083         self.assertEqual(self.set, set([2, 4, 6, 8]))
   1084 
   1085     def test_sym_difference_method_call(self):
   1086         self.set.symmetric_difference_update(set([3, 4, 5]))
   1087         self.assertEqual(self.set, set([2, 3, 5, 6]))
   1088 
   1089     def test_difference_subset(self):
   1090         self.set -= set((2, 4))
   1091         self.assertEqual(self.set, set([6]))
   1092 
   1093     def test_difference_superset(self):
   1094         self.set -= set((2, 4, 6, 8))
   1095         self.assertEqual(self.set, set([]))
   1096 
   1097     def test_difference_overlap(self):
   1098         self.set -= set((3, 4, 5))
   1099         self.assertEqual(self.set, set([2, 6]))
   1100 
   1101     def test_difference_non_overlap(self):
   1102         self.set -= set([8])
   1103         self.assertEqual(self.set, set([2, 4, 6]))
   1104 
   1105     def test_difference_method_call(self):
   1106         self.set.difference_update(set([3, 4, 5]))
   1107         self.assertEqual(self.set, set([2, 6]))
   1108 
   1109 #==============================================================================
   1110 
   1111 class TestMutate(unittest.TestCase):
   1112     def setUp(self):
   1113         self.values = ["a", "b", "c"]
   1114         self.set = set(self.values)
   1115 
   1116     def test_add_present(self):
   1117         self.set.add("c")
   1118         self.assertEqual(self.set, set("abc"))
   1119 
   1120     def test_add_absent(self):
   1121         self.set.add("d")
   1122         self.assertEqual(self.set, set("abcd"))
   1123 
   1124     def test_add_until_full(self):
   1125         tmp = set()
   1126         expected_len = 0
   1127         for v in self.values:
   1128             tmp.add(v)
   1129             expected_len += 1
   1130             self.assertEqual(len(tmp), expected_len)
   1131         self.assertEqual(tmp, self.set)
   1132 
   1133     def test_remove_present(self):
   1134         self.set.remove("b")
   1135         self.assertEqual(self.set, set("ac"))
   1136 
   1137     def test_remove_absent(self):
   1138         try:
   1139             self.set.remove("d")
   1140             self.fail("Removing missing element should have raised LookupError")
   1141         except LookupError:
   1142             pass
   1143 
   1144     def test_remove_until_empty(self):
   1145         expected_len = len(self.set)
   1146         for v in self.values:
   1147             self.set.remove(v)
   1148             expected_len -= 1
   1149             self.assertEqual(len(self.set), expected_len)
   1150 
   1151     def test_discard_present(self):
   1152         self.set.discard("c")
   1153         self.assertEqual(self.set, set("ab"))
   1154 
   1155     def test_discard_absent(self):
   1156         self.set.discard("d")
   1157         self.assertEqual(self.set, set("abc"))
   1158 
   1159     def test_clear(self):
   1160         self.set.clear()
   1161         self.assertEqual(len(self.set), 0)
   1162 
   1163     def test_pop(self):
   1164         popped = {}
   1165         while self.set:
   1166             popped[self.set.pop()] = None
   1167         self.assertEqual(len(popped), len(self.values))
   1168         for v in self.values:
   1169             self.assertIn(v, popped)
   1170 
   1171     def test_update_empty_tuple(self):
   1172         self.set.update(())
   1173         self.assertEqual(self.set, set(self.values))
   1174 
   1175     def test_update_unit_tuple_overlap(self):
   1176         self.set.update(("a",))
   1177         self.assertEqual(self.set, set(self.values))
   1178 
   1179     def test_update_unit_tuple_non_overlap(self):
   1180         self.set.update(("a", "z"))
   1181         self.assertEqual(self.set, set(self.values + ["z"]))
   1182 
   1183 #==============================================================================
   1184 
   1185 class TestSubsets(unittest.TestCase):
   1186 
   1187     case2method = {"<=": "issubset",
   1188                    ">=": "issuperset",
   1189                   }
   1190 
   1191     reverse = {"==": "==",
   1192                "!=": "!=",
   1193                "<":  ">",
   1194                ">":  "<",
   1195                "<=": ">=",
   1196                ">=": "<=",
   1197               }
   1198 
   1199     def test_issubset(self):
   1200         x = self.left
   1201         y = self.right
   1202         for case in "!=", "==", "<", "<=", ">", ">=":
   1203             expected = case in self.cases
   1204             # Test the binary infix spelling.
   1205             result = eval("x" + case + "y", locals())
   1206             self.assertEqual(result, expected)
   1207             # Test the "friendly" method-name spelling, if one exists.
   1208             if case in TestSubsets.case2method:
   1209                 method = getattr(x, TestSubsets.case2method[case])
   1210                 result = method(y)
   1211                 self.assertEqual(result, expected)
   1212 
   1213             # Now do the same for the operands reversed.
   1214             rcase = TestSubsets.reverse[case]
   1215             result = eval("y" + rcase + "x", locals())
   1216             self.assertEqual(result, expected)
   1217             if rcase in TestSubsets.case2method:
   1218                 method = getattr(y, TestSubsets.case2method[rcase])
   1219                 result = method(x)
   1220                 self.assertEqual(result, expected)
   1221 #------------------------------------------------------------------------------
   1222 
   1223 class TestSubsetEqualEmpty(TestSubsets):
   1224     left  = set()
   1225     right = set()
   1226     name  = "both empty"
   1227     cases = "==", "<=", ">="
   1228 
   1229 #------------------------------------------------------------------------------
   1230 
   1231 class TestSubsetEqualNonEmpty(TestSubsets):
   1232     left  = set([1, 2])
   1233     right = set([1, 2])
   1234     name  = "equal pair"
   1235     cases = "==", "<=", ">="
   1236 
   1237 #------------------------------------------------------------------------------
   1238 
   1239 class TestSubsetEmptyNonEmpty(TestSubsets):
   1240     left  = set()
   1241     right = set([1, 2])
   1242     name  = "one empty, one non-empty"
   1243     cases = "!=", "<", "<="
   1244 
   1245 #------------------------------------------------------------------------------
   1246 
   1247 class TestSubsetPartial(TestSubsets):
   1248     left  = set([1])
   1249     right = set([1, 2])
   1250     name  = "one a non-empty proper subset of other"
   1251     cases = "!=", "<", "<="
   1252 
   1253 #------------------------------------------------------------------------------
   1254 
   1255 class TestSubsetNonOverlap(TestSubsets):
   1256     left  = set([1])
   1257     right = set([2])
   1258     name  = "neither empty, neither contains"
   1259     cases = "!="
   1260 
   1261 #==============================================================================
   1262 
   1263 class TestOnlySetsInBinaryOps(unittest.TestCase):
   1264 
   1265     def test_eq_ne(self):
   1266         # Unlike the others, this is testing that == and != *are* allowed.
   1267         self.assertEqual(self.other == self.set, False)
   1268         self.assertEqual(self.set == self.other, False)
   1269         self.assertEqual(self.other != self.set, True)
   1270         self.assertEqual(self.set != self.other, True)
   1271 
   1272     def test_ge_gt_le_lt(self):
   1273         self.assertRaises(TypeError, lambda: self.set < self.other)
   1274         self.assertRaises(TypeError, lambda: self.set <= self.other)
   1275         self.assertRaises(TypeError, lambda: self.set > self.other)
   1276         self.assertRaises(TypeError, lambda: self.set >= self.other)
   1277 
   1278         self.assertRaises(TypeError, lambda: self.other < self.set)
   1279         self.assertRaises(TypeError, lambda: self.other <= self.set)
   1280         self.assertRaises(TypeError, lambda: self.other > self.set)
   1281         self.assertRaises(TypeError, lambda: self.other >= self.set)
   1282 
   1283     def test_update_operator(self):
   1284         try:
   1285             self.set |= self.other
   1286         except TypeError:
   1287             pass
   1288         else:
   1289             self.fail("expected TypeError")
   1290 
   1291     def test_update(self):
   1292         if self.otherIsIterable:
   1293             self.set.update(self.other)
   1294         else:
   1295             self.assertRaises(TypeError, self.set.update, self.other)
   1296 
   1297     def test_union(self):
   1298         self.assertRaises(TypeError, lambda: self.set | self.other)
   1299         self.assertRaises(TypeError, lambda: self.other | self.set)
   1300         if self.otherIsIterable:
   1301             self.set.union(self.other)
   1302         else:
   1303             self.assertRaises(TypeError, self.set.union, self.other)
   1304 
   1305     def test_intersection_update_operator(self):
   1306         try:
   1307             self.set &= self.other
   1308         except TypeError:
   1309             pass
   1310         else:
   1311             self.fail("expected TypeError")
   1312 
   1313     def test_intersection_update(self):
   1314         if self.otherIsIterable:
   1315             self.set.intersection_update(self.other)
   1316         else:
   1317             self.assertRaises(TypeError,
   1318                               self.set.intersection_update,
   1319                               self.other)
   1320 
   1321     def test_intersection(self):
   1322         self.assertRaises(TypeError, lambda: self.set & self.other)
   1323         self.assertRaises(TypeError, lambda: self.other & self.set)
   1324         if self.otherIsIterable:
   1325             self.set.intersection(self.other)
   1326         else:
   1327             self.assertRaises(TypeError, self.set.intersection, self.other)
   1328 
   1329     def test_sym_difference_update_operator(self):
   1330         try:
   1331             self.set ^= self.other
   1332         except TypeError:
   1333             pass
   1334         else:
   1335             self.fail("expected TypeError")
   1336 
   1337     def test_sym_difference_update(self):
   1338         if self.otherIsIterable:
   1339             self.set.symmetric_difference_update(self.other)
   1340         else:
   1341             self.assertRaises(TypeError,
   1342                               self.set.symmetric_difference_update,
   1343                               self.other)
   1344 
   1345     def test_sym_difference(self):
   1346         self.assertRaises(TypeError, lambda: self.set ^ self.other)
   1347         self.assertRaises(TypeError, lambda: self.other ^ self.set)
   1348         if self.otherIsIterable:
   1349             self.set.symmetric_difference(self.other)
   1350         else:
   1351             self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
   1352 
   1353     def test_difference_update_operator(self):
   1354         try:
   1355             self.set -= self.other
   1356         except TypeError:
   1357             pass
   1358         else:
   1359             self.fail("expected TypeError")
   1360 
   1361     def test_difference_update(self):
   1362         if self.otherIsIterable:
   1363             self.set.difference_update(self.other)
   1364         else:
   1365             self.assertRaises(TypeError,
   1366                               self.set.difference_update,
   1367                               self.other)
   1368 
   1369     def test_difference(self):
   1370         self.assertRaises(TypeError, lambda: self.set - self.other)
   1371         self.assertRaises(TypeError, lambda: self.other - self.set)
   1372         if self.otherIsIterable:
   1373             self.set.difference(self.other)
   1374         else:
   1375             self.assertRaises(TypeError, self.set.difference, self.other)
   1376 
   1377 #------------------------------------------------------------------------------
   1378 
   1379 class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
   1380     def setUp(self):
   1381         self.set   = set((1, 2, 3))
   1382         self.other = 19
   1383         self.otherIsIterable = False
   1384 
   1385 #------------------------------------------------------------------------------
   1386 
   1387 class TestOnlySetsDict(TestOnlySetsInBinaryOps):
   1388     def setUp(self):
   1389         self.set   = set((1, 2, 3))
   1390         self.other = {1:2, 3:4}
   1391         self.otherIsIterable = True
   1392 
   1393 #------------------------------------------------------------------------------
   1394 
   1395 class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
   1396     def setUp(self):
   1397         self.set   = set((1, 2, 3))
   1398         self.other = operator.add
   1399         self.otherIsIterable = False
   1400 
   1401     def test_ge_gt_le_lt(self):
   1402         with test_support.check_py3k_warnings():
   1403             super(TestOnlySetsOperator, self).test_ge_gt_le_lt()
   1404 
   1405 #------------------------------------------------------------------------------
   1406 
   1407 class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
   1408     def setUp(self):
   1409         self.set   = set((1, 2, 3))
   1410         self.other = (2, 4, 6)
   1411         self.otherIsIterable = True
   1412 
   1413 #------------------------------------------------------------------------------
   1414 
   1415 class TestOnlySetsString(TestOnlySetsInBinaryOps):
   1416     def setUp(self):
   1417         self.set   = set((1, 2, 3))
   1418         self.other = 'abc'
   1419         self.otherIsIterable = True
   1420 
   1421 #------------------------------------------------------------------------------
   1422 
   1423 class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
   1424     def setUp(self):
   1425         def gen():
   1426             for i in xrange(0, 10, 2):
   1427                 yield i
   1428         self.set   = set((1, 2, 3))
   1429         self.other = gen()
   1430         self.otherIsIterable = True
   1431 
   1432 #==============================================================================
   1433 
   1434 class TestCopying(unittest.TestCase):
   1435 
   1436     def test_copy(self):
   1437         dup = list(self.set.copy())
   1438         self.assertEqual(len(dup), len(self.set))
   1439         for el in self.set:
   1440             self.assertIn(el, dup)
   1441             pos = dup.index(el)
   1442             self.assertIs(el, dup.pop(pos))
   1443         self.assertFalse(dup)
   1444 
   1445     def test_deep_copy(self):
   1446         dup = copy.deepcopy(self.set)
   1447         self.assertSetEqual(dup, self.set)
   1448 
   1449 #------------------------------------------------------------------------------
   1450 
   1451 class TestCopyingEmpty(TestCopying):
   1452     def setUp(self):
   1453         self.set = set()
   1454 
   1455 #------------------------------------------------------------------------------
   1456 
   1457 class TestCopyingSingleton(TestCopying):
   1458     def setUp(self):
   1459         self.set = set(["hello"])
   1460 
   1461 #------------------------------------------------------------------------------
   1462 
   1463 class TestCopyingTriple(TestCopying):
   1464     def setUp(self):
   1465         self.set = set(["zero", 0, None])
   1466 
   1467 #------------------------------------------------------------------------------
   1468 
   1469 class TestCopyingTuple(TestCopying):
   1470     def setUp(self):
   1471         self.set = set([(1, 2)])
   1472 
   1473 #------------------------------------------------------------------------------
   1474 
   1475 class TestCopyingNested(TestCopying):
   1476     def setUp(self):
   1477         self.set = set([((1, 2), (3, 4))])
   1478 
   1479 #==============================================================================
   1480 
   1481 class TestIdentities(unittest.TestCase):
   1482     def setUp(self):
   1483         self.a = set('abracadabra')
   1484         self.b = set('alacazam')
   1485 
   1486     def test_binopsVsSubsets(self):
   1487         a, b = self.a, self.b
   1488         self.assertTrue(a - b < a)
   1489         self.assertTrue(b - a < b)
   1490         self.assertTrue(a & b < a)
   1491         self.assertTrue(a & b < b)
   1492         self.assertTrue(a | b > a)
   1493         self.assertTrue(a | b > b)
   1494         self.assertTrue(a ^ b < a | b)
   1495 
   1496     def test_commutativity(self):
   1497         a, b = self.a, self.b
   1498         self.assertEqual(a&b, b&a)
   1499         self.assertEqual(a|b, b|a)
   1500         self.assertEqual(a^b, b^a)
   1501         if a != b:
   1502             self.assertNotEqual(a-b, b-a)
   1503 
   1504     def test_summations(self):
   1505         # check that sums of parts equal the whole
   1506         a, b = self.a, self.b
   1507         self.assertEqual((a-b)|(a&b)|(b-a), a|b)
   1508         self.assertEqual((a&b)|(a^b), a|b)
   1509         self.assertEqual(a|(b-a), a|b)
   1510         self.assertEqual((a-b)|b, a|b)
   1511         self.assertEqual((a-b)|(a&b), a)
   1512         self.assertEqual((b-a)|(a&b), b)
   1513         self.assertEqual((a-b)|(b-a), a^b)
   1514 
   1515     def test_exclusion(self):
   1516         # check that inverse operations show non-overlap
   1517         a, b, zero = self.a, self.b, set()
   1518         self.assertEqual((a-b)&b, zero)
   1519         self.assertEqual((b-a)&a, zero)
   1520         self.assertEqual((a&b)&(a^b), zero)
   1521 
   1522 # Tests derived from test_itertools.py =======================================
   1523 
   1524 def R(seqn):
   1525     'Regular generator'
   1526     for i in seqn:
   1527         yield i
   1528 
   1529 class G:
   1530     'Sequence using __getitem__'
   1531     def __init__(self, seqn):
   1532         self.seqn = seqn
   1533     def __getitem__(self, i):
   1534         return self.seqn[i]
   1535 
   1536 class I:
   1537     'Sequence using iterator protocol'
   1538     def __init__(self, seqn):
   1539         self.seqn = seqn
   1540         self.i = 0
   1541     def __iter__(self):
   1542         return self
   1543     def next(self):
   1544         if self.i >= len(self.seqn): raise StopIteration
   1545         v = self.seqn[self.i]
   1546         self.i += 1
   1547         return v
   1548 
   1549 class Ig:
   1550     'Sequence using iterator protocol defined with a generator'
   1551     def __init__(self, seqn):
   1552         self.seqn = seqn
   1553         self.i = 0
   1554     def __iter__(self):
   1555         for val in self.seqn:
   1556             yield val
   1557 
   1558 class X:
   1559     'Missing __getitem__ and __iter__'
   1560     def __init__(self, seqn):
   1561         self.seqn = seqn
   1562         self.i = 0
   1563     def next(self):
   1564         if self.i >= len(self.seqn): raise StopIteration
   1565         v = self.seqn[self.i]
   1566         self.i += 1
   1567         return v
   1568 
   1569 class N:
   1570     'Iterator missing next()'
   1571     def __init__(self, seqn):
   1572         self.seqn = seqn
   1573         self.i = 0
   1574     def __iter__(self):
   1575         return self
   1576 
   1577 class E:
   1578     'Test propagation of exceptions'
   1579     def __init__(self, seqn):
   1580         self.seqn = seqn
   1581         self.i = 0
   1582     def __iter__(self):
   1583         return self
   1584     def next(self):
   1585         3 // 0
   1586 
   1587 class S:
   1588     'Test immediate stop'
   1589     def __init__(self, seqn):
   1590         pass
   1591     def __iter__(self):
   1592         return self
   1593     def next(self):
   1594         raise StopIteration
   1595 
   1596 from itertools import chain, imap
   1597 def L(seqn):
   1598     'Test multiple tiers of iterators'
   1599     return chain(imap(lambda x:x, R(Ig(G(seqn)))))
   1600 
   1601 class TestVariousIteratorArgs(unittest.TestCase):
   1602 
   1603     def test_constructor(self):
   1604         for cons in (set, frozenset):
   1605             for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
   1606                 for g in (G, I, Ig, S, L, R):
   1607                     self.assertSetEqual(cons(g(s)), set(g(s)))
   1608                 self.assertRaises(TypeError, cons , X(s))
   1609                 self.assertRaises(TypeError, cons , N(s))
   1610                 self.assertRaises(ZeroDivisionError, cons , E(s))
   1611 
   1612     def test_inline_methods(self):
   1613         s = set('november')
   1614         for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
   1615             for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
   1616                 for g in (G, I, Ig, L, R):
   1617                     expected = meth(data)
   1618                     actual = meth(G(data))
   1619                     if isinstance(expected, bool):
   1620                         self.assertEqual(actual, expected)
   1621                     else:
   1622                         self.assertSetEqual(actual, expected)
   1623                 self.assertRaises(TypeError, meth, X(s))
   1624                 self.assertRaises(TypeError, meth, N(s))
   1625                 self.assertRaises(ZeroDivisionError, meth, E(s))
   1626 
   1627     def test_inplace_methods(self):
   1628         for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
   1629             for methname in ('update', 'intersection_update',
   1630                              'difference_update', 'symmetric_difference_update'):
   1631                 for g in (G, I, Ig, S, L, R):
   1632                     s = set('january')
   1633                     t = s.copy()
   1634                     getattr(s, methname)(list(g(data)))
   1635                     getattr(t, methname)(g(data))
   1636                     self.assertSetEqual(s, t)
   1637 
   1638                 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
   1639                 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
   1640                 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
   1641 
   1642 class bad_eq:
   1643     def __eq__(self, other):
   1644         if be_bad:
   1645             set2.clear()
   1646             raise ZeroDivisionError
   1647         return self is other
   1648     def __hash__(self):
   1649         return 0
   1650 
   1651 class bad_dict_clear:
   1652     def __eq__(self, other):
   1653         if be_bad:
   1654             dict2.clear()
   1655         return self is other
   1656     def __hash__(self):
   1657         return 0
   1658 
   1659 class TestWeirdBugs(unittest.TestCase):
   1660     def test_8420_set_merge(self):
   1661         # This used to segfault
   1662         global be_bad, set2, dict2
   1663         be_bad = False
   1664         set1 = {bad_eq()}
   1665         set2 = {bad_eq() for i in range(75)}
   1666         be_bad = True
   1667         self.assertRaises(ZeroDivisionError, set1.update, set2)
   1668 
   1669         be_bad = False
   1670         set1 = {bad_dict_clear()}
   1671         dict2 = {bad_dict_clear(): None}
   1672         be_bad = True
   1673         set1.symmetric_difference_update(dict2)
   1674 
   1675 # Application tests (based on David Eppstein's graph recipes ====================================
   1676 
   1677 def powerset(U):
   1678     """Generates all subsets of a set or sequence U."""
   1679     U = iter(U)
   1680     try:
   1681         x = frozenset([U.next()])
   1682         for S in powerset(U):
   1683             yield S
   1684             yield S | x
   1685     except StopIteration:
   1686         yield frozenset()
   1687 
   1688 def cube(n):
   1689     """Graph of n-dimensional hypercube."""
   1690     singletons = [frozenset([x]) for x in range(n)]
   1691     return dict([(x, frozenset([x^s for s in singletons]))
   1692                  for x in powerset(range(n))])
   1693 
   1694 def linegraph(G):
   1695     """Graph, the vertices of which are edges of G,
   1696     with two vertices being adjacent iff the corresponding
   1697     edges share a vertex."""
   1698     L = {}
   1699     for x in G:
   1700         for y in G[x]:
   1701             nx = [frozenset([x,z]) for z in G[x] if z != y]
   1702             ny = [frozenset([y,z]) for z in G[y] if z != x]
   1703             L[frozenset([x,y])] = frozenset(nx+ny)
   1704     return L
   1705 
   1706 def faces(G):
   1707     'Return a set of faces in G.  Where a face is a set of vertices on that face'
   1708     # currently limited to triangles,squares, and pentagons
   1709     f = set()
   1710     for v1, edges in G.items():
   1711         for v2 in edges:
   1712             for v3 in G[v2]:
   1713                 if v1 == v3:
   1714                     continue
   1715                 if v1 in G[v3]:
   1716                     f.add(frozenset([v1, v2, v3]))
   1717                 else:
   1718                     for v4 in G[v3]:
   1719                         if v4 == v2:
   1720                             continue
   1721                         if v1 in G[v4]:
   1722                             f.add(frozenset([v1, v2, v3, v4]))
   1723                         else:
   1724                             for v5 in G[v4]:
   1725                                 if v5 == v3 or v5 == v2:
   1726                                     continue
   1727                                 if v1 in G[v5]:
   1728                                     f.add(frozenset([v1, v2, v3, v4, v5]))
   1729     return f
   1730 
   1731 
   1732 class TestGraphs(unittest.TestCase):
   1733 
   1734     def test_cube(self):
   1735 
   1736         g = cube(3)                             # vert --> {v1, v2, v3}
   1737         vertices1 = set(g)
   1738         self.assertEqual(len(vertices1), 8)     # eight vertices
   1739         for edge in g.values():
   1740             self.assertEqual(len(edge), 3)      # each vertex connects to three edges
   1741         vertices2 = set(v for edges in g.values() for v in edges)
   1742         self.assertEqual(vertices1, vertices2)  # edge vertices in original set
   1743 
   1744         cubefaces = faces(g)
   1745         self.assertEqual(len(cubefaces), 6)     # six faces
   1746         for face in cubefaces:
   1747             self.assertEqual(len(face), 4)      # each face is a square
   1748 
   1749     def test_cuboctahedron(self):
   1750 
   1751         # http://en.wikipedia.org/wiki/Cuboctahedron
   1752         # 8 triangular faces and 6 square faces
   1753         # 12 indentical vertices each connecting a triangle and square
   1754 
   1755         g = cube(3)
   1756         cuboctahedron = linegraph(g)            # V( --> {V1, V2, V3, V4}
   1757         self.assertEqual(len(cuboctahedron), 12)# twelve vertices
   1758 
   1759         vertices = set(cuboctahedron)
   1760         for edges in cuboctahedron.values():
   1761             self.assertEqual(len(edges), 4)     # each vertex connects to four other vertices
   1762         othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
   1763         self.assertEqual(vertices, othervertices)   # edge vertices in original set
   1764 
   1765         cubofaces = faces(cuboctahedron)
   1766         facesizes = collections.defaultdict(int)
   1767         for face in cubofaces:
   1768             facesizes[len(face)] += 1
   1769         self.assertEqual(facesizes[3], 8)       # eight triangular faces
   1770         self.assertEqual(facesizes[4], 6)       # six square faces
   1771 
   1772         for vertex in cuboctahedron:
   1773             edge = vertex                       # Cuboctahedron vertices are edges in Cube
   1774             self.assertEqual(len(edge), 2)      # Two cube vertices define an edge
   1775             for cubevert in edge:
   1776                 self.assertIn(cubevert, g)
   1777 
   1778 
   1779 #==============================================================================
   1780 
   1781 def test_main(verbose=None):
   1782     test_classes = (
   1783         TestSet,
   1784         TestSetSubclass,
   1785         TestSetSubclassWithKeywordArgs,
   1786         TestFrozenSet,
   1787         TestFrozenSetSubclass,
   1788         TestSetOfSets,
   1789         TestExceptionPropagation,
   1790         TestBasicOpsEmpty,
   1791         TestBasicOpsSingleton,
   1792         TestBasicOpsTuple,
   1793         TestBasicOpsTriple,
   1794         TestBinaryOps,
   1795         TestUpdateOps,
   1796         TestMutate,
   1797         TestSubsetEqualEmpty,
   1798         TestSubsetEqualNonEmpty,
   1799         TestSubsetEmptyNonEmpty,
   1800         TestSubsetPartial,
   1801         TestSubsetNonOverlap,
   1802         TestOnlySetsNumeric,
   1803         TestOnlySetsDict,
   1804         TestOnlySetsOperator,
   1805         TestOnlySetsTuple,
   1806         TestOnlySetsString,
   1807         TestOnlySetsGenerator,
   1808         TestCopyingEmpty,
   1809         TestCopyingSingleton,
   1810         TestCopyingTriple,
   1811         TestCopyingTuple,
   1812         TestCopyingNested,
   1813         TestIdentities,
   1814         TestVariousIteratorArgs,
   1815         TestGraphs,
   1816         TestWeirdBugs,
   1817         )
   1818 
   1819     test_support.run_unittest(*test_classes)
   1820 
   1821     # verify reference counting
   1822     if verbose and hasattr(sys, "gettotalrefcount"):
   1823         import gc
   1824         counts = [None] * 5
   1825         for i in xrange(len(counts)):
   1826             test_support.run_unittest(*test_classes)
   1827             gc.collect()
   1828             counts[i] = sys.gettotalrefcount()
   1829         print counts
   1830 
   1831 if __name__ == "__main__":
   1832     test_main(verbose=True)
   1833