2
from test import test_support
3
from weakref import proxy
8
from random import randrange, shuffle
12
class PassThru(Exception):
15
def check_pass_thru():
22
def __cmp__(self, other):
26
'Used to test self-referential repr() calls'
28
return repr(self.value)
30
class HashCountingInt(int):
31
'int-like object that counts the number of times __hash__ is called'
32
def __init__(self, *args):
36
return int.__hash__(self)
38
class TestJointOps(unittest.TestCase):
39
# Tests common to both set and frozenset
42
self.word = word = 'simsalabim'
43
self.otherword = 'madagascar'
44
self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
45
self.s = self.thetype(word)
46
self.d = dict.fromkeys(word)
48
def test_new_or_init(self):
49
self.assertRaises(TypeError, self.thetype, [], 2)
51
def test_uniquification(self):
52
actual = sorted(self.s)
53
expected = sorted(self.d)
54
self.assertEqual(actual, expected)
55
self.assertRaises(PassThru, self.thetype, check_pass_thru())
56
self.assertRaises(TypeError, self.thetype, [[]])
59
self.assertEqual(len(self.s), len(self.d))
61
def test_contains(self):
62
for c in self.letters:
63
self.assertEqual(c in self.s, c in self.d)
64
self.assertRaises(TypeError, self.s.__contains__, [[]])
65
s = self.thetype([frozenset(self.letters)])
66
self.assert_(self.thetype(self.letters) in s)
69
u = self.s.union(self.otherword)
70
for c in self.letters:
71
self.assertEqual(c in u, c in self.d or c in self.otherword)
72
self.assertEqual(self.s, self.thetype(self.word))
73
self.assertEqual(type(u), self.thetype)
74
self.assertRaises(PassThru, self.s.union, check_pass_thru())
75
self.assertRaises(TypeError, self.s.union, [[]])
76
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
77
self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
78
self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
79
self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
80
self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
81
self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
84
i = self.s.union(self.otherword)
85
self.assertEqual(self.s | set(self.otherword), i)
86
self.assertEqual(self.s | frozenset(self.otherword), i)
88
self.s | self.otherword
92
self.fail("s|t did not screen-out general iterables")
94
def test_intersection(self):
95
i = self.s.intersection(self.otherword)
96
for c in self.letters:
97
self.assertEqual(c in i, c in self.d and c in self.otherword)
98
self.assertEqual(self.s, self.thetype(self.word))
99
self.assertEqual(type(i), self.thetype)
100
self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
101
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
102
self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
103
self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
104
self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
105
self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
106
self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
107
s = self.thetype('abcba')
109
if self.thetype == frozenset():
110
self.assertEqual(id(s), id(z))
112
self.assertNotEqual(id(s), id(z))
114
def test_isdisjoint(self):
116
'Pure python equivalent of isdisjoint()'
117
return not set(s1).intersection(s2)
118
for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
119
s1 = self.thetype(larg)
120
for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
121
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
123
actual = s1.isdisjoint(s2)
125
self.assertEqual(actual, expected)
126
self.assert_(actual is True or actual is False)
129
i = self.s.intersection(self.otherword)
130
self.assertEqual(self.s & set(self.otherword), i)
131
self.assertEqual(self.s & frozenset(self.otherword), i)
133
self.s & self.otherword
137
self.fail("s&t did not screen-out general iterables")
139
def test_difference(self):
140
i = self.s.difference(self.otherword)
141
for c in self.letters:
142
self.assertEqual(c in i, c in self.d and c not in self.otherword)
143
self.assertEqual(self.s, self.thetype(self.word))
144
self.assertEqual(type(i), self.thetype)
145
self.assertRaises(PassThru, self.s.difference, check_pass_thru())
146
self.assertRaises(TypeError, self.s.difference, [[]])
147
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
148
self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
149
self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
150
self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
151
self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
152
self.assertEqual(self.thetype('abcba').difference(), set('abc'))
153
self.assertEqual(self.thetype('abcba').difference(C('a'), C('b')), set('c'))
156
i = self.s.difference(self.otherword)
157
self.assertEqual(self.s - set(self.otherword), i)
158
self.assertEqual(self.s - frozenset(self.otherword), i)
160
self.s - self.otherword
164
self.fail("s-t did not screen-out general iterables")
166
def test_symmetric_difference(self):
167
i = self.s.symmetric_difference(self.otherword)
168
for c in self.letters:
169
self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
170
self.assertEqual(self.s, self.thetype(self.word))
171
self.assertEqual(type(i), self.thetype)
172
self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
173
self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
174
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
175
self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
176
self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
177
self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
178
self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
181
i = self.s.symmetric_difference(self.otherword)
182
self.assertEqual(self.s ^ set(self.otherword), i)
183
self.assertEqual(self.s ^ frozenset(self.otherword), i)
185
self.s ^ self.otherword
189
self.fail("s^t did not screen-out general iterables")
191
def test_equality(self):
192
self.assertEqual(self.s, set(self.word))
193
self.assertEqual(self.s, frozenset(self.word))
194
self.assertEqual(self.s == self.word, False)
195
self.assertNotEqual(self.s, set(self.otherword))
196
self.assertNotEqual(self.s, frozenset(self.otherword))
197
self.assertEqual(self.s != self.word, True)
199
def test_setOfFrozensets(self):
200
t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
202
self.assertEqual(len(s), 3)
204
def test_compare(self):
205
self.assertRaises(TypeError, self.s.__cmp__, self.s)
207
def test_sub_and_super(self):
208
p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
218
self.assert_(set('a').issubset('abc'))
219
self.assert_(set('abc').issuperset('a'))
220
self.failIf(set('a').issubset('cbs'))
221
self.failIf(set('cbs').issuperset('a'))
223
def test_pickling(self):
225
p = pickle.dumps(self.s, i)
226
dup = pickle.loads(p)
227
self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
228
if type(self.s) not in (set, frozenset):
230
p = pickle.dumps(self.s)
231
dup = pickle.loads(p)
232
self.assertEqual(self.s.x, dup.x)
234
def test_deepcopy(self):
236
def __init__(self, value):
240
def __deepcopy__(self, memo=None):
241
return Tracer(self.value + 1)
243
s = self.thetype([t])
244
dup = copy.deepcopy(s)
245
self.assertNotEqual(id(s), id(dup))
248
self.assertNotEqual(id(t), id(newt))
249
self.assertEqual(t.value + 1, newt.value)
252
# Create a nest of cycles to exercise overall ref count check
255
s = set(A() for i in xrange(1000))
259
elem.set = set([elem])
261
def test_subclass_with_custom_hash(self):
263
class H(self.thetype):
265
return int(id(self) & 0x7fffffff)
274
def test_badcmp(self):
275
s = self.thetype([BadCmp()])
276
# Detect comparison errors during insertion and lookup
277
self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
278
self.assertRaises(RuntimeError, s.__contains__, BadCmp())
279
# Detect errors during mutating operations
280
if hasattr(s, 'add'):
281
self.assertRaises(RuntimeError, s.add, BadCmp())
282
self.assertRaises(RuntimeError, s.discard, BadCmp())
283
self.assertRaises(RuntimeError, s.remove, BadCmp())
285
def test_cyclical_repr(self):
287
s = self.thetype([w])
289
name = repr(s).partition('(')[0] # strip class name from repr string
290
self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
292
def test_cyclical_print(self):
294
s = self.thetype([w])
296
fo = open(test_support.TESTFN, "wb")
300
fo = open(test_support.TESTFN, "rb")
301
self.assertEqual(fo.read(), repr(s))
304
test_support.unlink(test_support.TESTFN)
306
def test_do_not_rehash_dict_keys(self):
308
d = dict.fromkeys(map(HashCountingInt, xrange(n)))
309
self.assertEqual(sum(elem.hash_count for elem in d), n)
311
self.assertEqual(sum(elem.hash_count for elem in d), n)
313
self.assertEqual(sum(elem.hash_count for elem in d), n)
314
if hasattr(s, 'symmetric_difference_update'):
315
s.symmetric_difference_update(d)
316
self.assertEqual(sum(elem.hash_count for elem in d), n)
317
d2 = dict.fromkeys(set(d))
318
self.assertEqual(sum(elem.hash_count for elem in d), n)
319
d3 = dict.fromkeys(frozenset(d))
320
self.assertEqual(sum(elem.hash_count for elem in d), n)
321
d3 = dict.fromkeys(frozenset(d), 123)
322
self.assertEqual(sum(elem.hash_count for elem in d), n)
323
self.assertEqual(d3, dict.fromkeys(d, 123))
325
class TestSet(TestJointOps):
330
s.__init__(self.word)
331
self.assertEqual(s, set(self.word))
332
s.__init__(self.otherword)
333
self.assertEqual(s, set(self.otherword))
334
self.assertRaises(TypeError, s.__init__, s, 2);
335
self.assertRaises(TypeError, s.__init__, 1);
337
def test_constructor_identity(self):
338
s = self.thetype(range(3))
340
self.assertNotEqual(id(s), id(t))
343
self.assertRaises(TypeError, hash, self.s)
345
def test_clear(self):
347
self.assertEqual(self.s, set())
348
self.assertEqual(len(self.s), 0)
352
self.assertEqual(self.s, dup)
353
self.assertNotEqual(id(self.s), id(dup))
357
self.assert_('Q' in self.s)
360
self.assertEqual(self.s, dup)
361
self.assertRaises(TypeError, self.s.add, [])
363
def test_remove(self):
365
self.assert_('a' not in self.s)
366
self.assertRaises(KeyError, self.s.remove, 'Q')
367
self.assertRaises(TypeError, self.s.remove, [])
368
s = self.thetype([frozenset(self.word)])
369
self.assert_(self.thetype(self.word) in s)
370
s.remove(self.thetype(self.word))
371
self.assert_(self.thetype(self.word) not in s)
372
self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
374
def test_remove_keyerror_unpacking(self):
375
# bug: www.python.org/sf/1576657
376
for v1 in ['Q', (1,)]:
381
self.assertEqual(v1, v2)
385
def test_remove_keyerror_set(self):
386
key = self.thetype([3, 4])
389
except KeyError as e:
390
self.assert_(e.args[0] is key,
391
"KeyError should be {0}, not {1}".format(key,
396
def test_discard(self):
398
self.assert_('a' not in self.s)
400
self.assertRaises(TypeError, self.s.discard, [])
401
s = self.thetype([frozenset(self.word)])
402
self.assert_(self.thetype(self.word) in s)
403
s.discard(self.thetype(self.word))
404
self.assert_(self.thetype(self.word) not in s)
405
s.discard(self.thetype(self.word))
408
for i in xrange(len(self.s)):
410
self.assert_(elem not in self.s)
411
self.assertRaises(KeyError, self.s.pop)
413
def test_update(self):
414
retval = self.s.update(self.otherword)
415
self.assertEqual(retval, None)
416
for c in (self.word + self.otherword):
417
self.assert_(c in self.s)
418
self.assertRaises(PassThru, self.s.update, check_pass_thru())
419
self.assertRaises(TypeError, self.s.update, [[]])
420
for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
421
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
422
s = self.thetype('abcba')
423
self.assertEqual(s.update(C(p)), None)
424
self.assertEqual(s, set(q))
425
for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
427
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
428
s = self.thetype('abcba')
429
self.assertEqual(s.update(C(p), C(q)), None)
430
self.assertEqual(s, set(s) | set(p) | set(q))
433
self.s |= set(self.otherword)
434
for c in (self.word + self.otherword):
435
self.assert_(c in self.s)
437
def test_intersection_update(self):
438
retval = self.s.intersection_update(self.otherword)
439
self.assertEqual(retval, None)
440
for c in (self.word + self.otherword):
441
if c in self.otherword and c in self.word:
442
self.assert_(c in self.s)
444
self.assert_(c not in self.s)
445
self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
446
self.assertRaises(TypeError, self.s.intersection_update, [[]])
447
for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
448
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
449
s = self.thetype('abcba')
450
self.assertEqual(s.intersection_update(C(p)), None)
451
self.assertEqual(s, set(q))
455
self.assertEqual(s.intersection_update(C(p), C(t)), None)
456
self.assertEqual(s, set('abcba')&set(p)&set(t))
459
self.s &= set(self.otherword)
460
for c in (self.word + self.otherword):
461
if c in self.otherword and c in self.word:
462
self.assert_(c in self.s)
464
self.assert_(c not in self.s)
466
def test_difference_update(self):
467
retval = self.s.difference_update(self.otherword)
468
self.assertEqual(retval, None)
469
for c in (self.word + self.otherword):
470
if c in self.word and c not in self.otherword:
471
self.assert_(c in self.s)
473
self.assert_(c not in self.s)
474
self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
475
self.assertRaises(TypeError, self.s.difference_update, [[]])
476
self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
477
for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
478
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
479
s = self.thetype('abcba')
480
self.assertEqual(s.difference_update(C(p)), None)
481
self.assertEqual(s, set(q))
483
s = self.thetype('abcdefghih')
484
s.difference_update()
485
self.assertEqual(s, self.thetype('abcdefghih'))
487
s = self.thetype('abcdefghih')
488
s.difference_update(C('aba'))
489
self.assertEqual(s, self.thetype('cdefghih'))
491
s = self.thetype('abcdefghih')
492
s.difference_update(C('cdc'), C('aba'))
493
self.assertEqual(s, self.thetype('efghih'))
496
self.s -= set(self.otherword)
497
for c in (self.word + self.otherword):
498
if c in self.word and c not in self.otherword:
499
self.assert_(c in self.s)
501
self.assert_(c not in self.s)
503
def test_symmetric_difference_update(self):
504
retval = self.s.symmetric_difference_update(self.otherword)
505
self.assertEqual(retval, None)
506
for c in (self.word + self.otherword):
507
if (c in self.word) ^ (c in self.otherword):
508
self.assert_(c in self.s)
510
self.assert_(c not in self.s)
511
self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
512
self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
513
for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
514
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
515
s = self.thetype('abcba')
516
self.assertEqual(s.symmetric_difference_update(C(p)), None)
517
self.assertEqual(s, set(q))
520
self.s ^= set(self.otherword)
521
for c in (self.word + self.otherword):
522
if (c in self.word) ^ (c in self.otherword):
523
self.assert_(c in self.s)
525
self.assert_(c not in self.s)
527
def test_inplace_on_self(self):
530
self.assertEqual(t, self.s)
532
self.assertEqual(t, self.s)
534
self.assertEqual(t, self.thetype())
537
self.assertEqual(t, self.thetype())
539
def test_weakref(self):
540
s = self.thetype('gallahad')
542
self.assertEqual(str(p), str(s))
544
self.assertRaises(ReferenceError, str, p)
546
# C API test only available in a debug build
547
if hasattr(set, "test_c_api"):
548
def test_c_api(self):
549
self.assertEqual(set('abc').test_c_api(), True)
551
class SetSubclass(set):
554
class TestSetSubclass(TestSet):
555
thetype = SetSubclass
557
class SetSubclassWithKeywordArgs(set):
558
def __init__(self, iterable=[], newarg=None):
559
set.__init__(self, iterable)
561
class TestSetSubclassWithKeywordArgs(TestSet):
563
def test_keywords_in_subclass(self):
564
'SF bug #1486663 -- this used to erroneously raise a TypeError'
565
SetSubclassWithKeywordArgs(newarg=1)
567
class TestFrozenSet(TestJointOps):
571
s = self.thetype(self.word)
572
s.__init__(self.otherword)
573
self.assertEqual(s, set(self.word))
575
def test_singleton_empty_frozenset(self):
577
efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
578
frozenset(), frozenset([]), frozenset(()), frozenset(''),
579
frozenset(xrange(0)), frozenset(frozenset()),
581
# All of the empty frozensets should have just one id()
582
self.assertEqual(len(set(map(id, efs))), 1)
584
def test_constructor_identity(self):
585
s = self.thetype(range(3))
587
self.assertEqual(id(s), id(t))
590
self.assertEqual(hash(self.thetype('abcdeb')),
591
hash(self.thetype('ebecda')))
593
# make sure that all permutations give the same hash value
595
seq = [randrange(n) for i in xrange(n)]
597
for i in xrange(200):
599
results.add(hash(self.thetype(seq)))
600
self.assertEqual(len(results), 1)
604
self.assertEqual(id(self.s), id(dup))
606
def test_frozen_as_dictkey(self):
607
seq = range(10) + list('abcdefg') + ['apple']
608
key1 = self.thetype(seq)
609
key2 = self.thetype(reversed(seq))
610
self.assertEqual(key1, key2)
611
self.assertNotEqual(id(key1), id(key2))
614
self.assertEqual(d[key2], 42)
616
def test_hash_caching(self):
617
f = self.thetype('abcdcda')
618
self.assertEqual(hash(f), hash(f))
620
def test_hash_effectiveness(self):
623
addhashvalue = hashvalues.add
624
elemmasks = [(i+1, 1<<i) for i in range(n)]
625
for i in xrange(2**n):
626
addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
627
self.assertEqual(len(hashvalues), 2**n)
629
class FrozenSetSubclass(frozenset):
632
class TestFrozenSetSubclass(TestFrozenSet):
633
thetype = FrozenSetSubclass
635
def test_constructor_identity(self):
636
s = self.thetype(range(3))
638
self.assertNotEqual(id(s), id(t))
642
self.assertNotEqual(id(self.s), id(dup))
644
def test_nested_empty_constructor(self):
647
self.assertEqual(s, t)
649
def test_singleton_empty_frozenset(self):
650
Frozenset = self.thetype
653
efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
654
Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
655
Frozenset(xrange(0)), Frozenset(Frozenset()),
656
Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
657
# All empty frozenset subclass instances should have different ids
658
self.assertEqual(len(set(map(id, efs))), len(efs))
660
# Tests taken from test_sets.py =============================================
664
#==============================================================================
666
class TestBasicOps(unittest.TestCase):
669
if self.repr is not None:
670
self.assertEqual(repr(self.set), self.repr)
672
def test_print(self):
673
fo = open(test_support.TESTFN, "wb")
675
print >> fo, self.set,
677
fo = open(test_support.TESTFN, "rb")
678
self.assertEqual(fo.read(), repr(self.set))
681
test_support.unlink(test_support.TESTFN)
683
def test_length(self):
684
self.assertEqual(len(self.set), self.length)
686
def test_self_equality(self):
687
self.assertEqual(self.set, self.set)
689
def test_equivalent_equality(self):
690
self.assertEqual(self.set, self.dup)
693
self.assertEqual(self.set.copy(), self.dup)
695
def test_self_union(self):
696
result = self.set | self.set
697
self.assertEqual(result, self.dup)
699
def test_empty_union(self):
700
result = self.set | empty_set
701
self.assertEqual(result, self.dup)
703
def test_union_empty(self):
704
result = empty_set | self.set
705
self.assertEqual(result, self.dup)
707
def test_self_intersection(self):
708
result = self.set & self.set
709
self.assertEqual(result, self.dup)
711
def test_empty_intersection(self):
712
result = self.set & empty_set
713
self.assertEqual(result, empty_set)
715
def test_intersection_empty(self):
716
result = empty_set & self.set
717
self.assertEqual(result, empty_set)
719
def test_self_isdisjoint(self):
720
result = self.set.isdisjoint(self.set)
721
self.assertEqual(result, not self.set)
723
def test_empty_isdisjoint(self):
724
result = self.set.isdisjoint(empty_set)
725
self.assertEqual(result, True)
727
def test_isdisjoint_empty(self):
728
result = empty_set.isdisjoint(self.set)
729
self.assertEqual(result, True)
731
def test_self_symmetric_difference(self):
732
result = self.set ^ self.set
733
self.assertEqual(result, empty_set)
735
def checkempty_symmetric_difference(self):
736
result = self.set ^ empty_set
737
self.assertEqual(result, self.set)
739
def test_self_difference(self):
740
result = self.set - self.set
741
self.assertEqual(result, empty_set)
743
def test_empty_difference(self):
744
result = self.set - empty_set
745
self.assertEqual(result, self.dup)
747
def test_empty_difference_rev(self):
748
result = empty_set - self.set
749
self.assertEqual(result, empty_set)
751
def test_iteration(self):
753
self.assert_(v in self.values)
754
setiter = iter(self.set)
755
# note: __length_hint__ is an internal undocumented API,
756
# don't rely on it in your own programs
757
self.assertEqual(setiter.__length_hint__(), len(self.set))
759
def test_pickling(self):
760
p = pickle.dumps(self.set)
761
copy = pickle.loads(p)
762
self.assertEqual(self.set, copy,
763
"%s != %s" % (self.set, copy))
765
#------------------------------------------------------------------------------
767
class TestBasicOpsEmpty(TestBasicOps):
769
self.case = "empty set"
771
self.set = set(self.values)
772
self.dup = set(self.values)
774
self.repr = "set([])"
776
#------------------------------------------------------------------------------
778
class TestBasicOpsSingleton(TestBasicOps):
780
self.case = "unit set (number)"
782
self.set = set(self.values)
783
self.dup = set(self.values)
785
self.repr = "set([3])"
788
self.failUnless(3 in self.set)
790
def test_not_in(self):
791
self.failUnless(2 not in self.set)
793
#------------------------------------------------------------------------------
795
class TestBasicOpsTuple(TestBasicOps):
797
self.case = "unit set (tuple)"
798
self.values = [(0, "zero")]
799
self.set = set(self.values)
800
self.dup = set(self.values)
802
self.repr = "set([(0, 'zero')])"
805
self.failUnless((0, "zero") in self.set)
807
def test_not_in(self):
808
self.failUnless(9 not in self.set)
810
#------------------------------------------------------------------------------
812
class TestBasicOpsTriple(TestBasicOps):
814
self.case = "triple set"
815
self.values = [0, "zero", operator.add]
816
self.set = set(self.values)
817
self.dup = set(self.values)
821
#==============================================================================
830
class TestExceptionPropagation(unittest.TestCase):
831
"""SF 628246: Set constructor should not trap iterator TypeErrors"""
833
def test_instanceWithException(self):
834
self.assertRaises(TypeError, set, baditer())
836
def test_instancesWithoutException(self):
837
# All of these iterables should load without exception.
840
set({'one':1, 'two':2, 'three':3})
845
def test_changingSizeWhileIterating(self):
853
self.fail("no exception when changing size during iteration")
855
#==============================================================================
857
class TestSetOfSets(unittest.TestCase):
858
def test_constructor(self):
859
inner = frozenset([1])
861
element = outer.pop()
862
self.assertEqual(type(element), frozenset)
863
outer.add(inner) # Rebuild set of sets with .add method
865
self.assertEqual(outer, set()) # Verify that remove worked
866
outer.discard(inner) # Absence of KeyError indicates working fine
868
#==============================================================================
870
class TestBinaryOps(unittest.TestCase):
872
self.set = set((2, 4, 6))
874
def test_eq(self): # SF bug 643115
875
self.assertEqual(self.set, set({2:1,4:3,6:5}))
877
def test_union_subset(self):
878
result = self.set | set([2])
879
self.assertEqual(result, set((2, 4, 6)))
881
def test_union_superset(self):
882
result = self.set | set([2, 4, 6, 8])
883
self.assertEqual(result, set([2, 4, 6, 8]))
885
def test_union_overlap(self):
886
result = self.set | set([3, 4, 5])
887
self.assertEqual(result, set([2, 3, 4, 5, 6]))
889
def test_union_non_overlap(self):
890
result = self.set | set([8])
891
self.assertEqual(result, set([2, 4, 6, 8]))
893
def test_intersection_subset(self):
894
result = self.set & set((2, 4))
895
self.assertEqual(result, set((2, 4)))
897
def test_intersection_superset(self):
898
result = self.set & set([2, 4, 6, 8])
899
self.assertEqual(result, set([2, 4, 6]))
901
def test_intersection_overlap(self):
902
result = self.set & set([3, 4, 5])
903
self.assertEqual(result, set([4]))
905
def test_intersection_non_overlap(self):
906
result = self.set & set([8])
907
self.assertEqual(result, empty_set)
909
def test_isdisjoint_subset(self):
910
result = self.set.isdisjoint(set((2, 4)))
911
self.assertEqual(result, False)
913
def test_isdisjoint_superset(self):
914
result = self.set.isdisjoint(set([2, 4, 6, 8]))
915
self.assertEqual(result, False)
917
def test_isdisjoint_overlap(self):
918
result = self.set.isdisjoint(set([3, 4, 5]))
919
self.assertEqual(result, False)
921
def test_isdisjoint_non_overlap(self):
922
result = self.set.isdisjoint(set([8]))
923
self.assertEqual(result, True)
925
def test_sym_difference_subset(self):
926
result = self.set ^ set((2, 4))
927
self.assertEqual(result, set([6]))
929
def test_sym_difference_superset(self):
930
result = self.set ^ set((2, 4, 6, 8))
931
self.assertEqual(result, set([8]))
933
def test_sym_difference_overlap(self):
934
result = self.set ^ set((3, 4, 5))
935
self.assertEqual(result, set([2, 3, 5, 6]))
937
def test_sym_difference_non_overlap(self):
938
result = self.set ^ set([8])
939
self.assertEqual(result, set([2, 4, 6, 8]))
942
a, b = set('a'), set('b')
943
self.assertRaises(TypeError, cmp, a, b)
945
# You can view this as a buglet: cmp(a, a) does not raise TypeError,
946
# because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
947
# which Python thinks is good enough to synthesize a cmp() result
948
# without calling __cmp__.
949
self.assertEqual(cmp(a, a), 0)
951
self.assertRaises(TypeError, cmp, a, 12)
952
self.assertRaises(TypeError, cmp, "abc", a)
954
#==============================================================================
956
class TestUpdateOps(unittest.TestCase):
958
self.set = set((2, 4, 6))
960
def test_union_subset(self):
962
self.assertEqual(self.set, set((2, 4, 6)))
964
def test_union_superset(self):
965
self.set |= set([2, 4, 6, 8])
966
self.assertEqual(self.set, set([2, 4, 6, 8]))
968
def test_union_overlap(self):
969
self.set |= set([3, 4, 5])
970
self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
972
def test_union_non_overlap(self):
974
self.assertEqual(self.set, set([2, 4, 6, 8]))
976
def test_union_method_call(self):
977
self.set.update(set([3, 4, 5]))
978
self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
980
def test_intersection_subset(self):
981
self.set &= set((2, 4))
982
self.assertEqual(self.set, set((2, 4)))
984
def test_intersection_superset(self):
985
self.set &= set([2, 4, 6, 8])
986
self.assertEqual(self.set, set([2, 4, 6]))
988
def test_intersection_overlap(self):
989
self.set &= set([3, 4, 5])
990
self.assertEqual(self.set, set([4]))
992
def test_intersection_non_overlap(self):
994
self.assertEqual(self.set, empty_set)
996
def test_intersection_method_call(self):
997
self.set.intersection_update(set([3, 4, 5]))
998
self.assertEqual(self.set, set([4]))
1000
def test_sym_difference_subset(self):
1001
self.set ^= set((2, 4))
1002
self.assertEqual(self.set, set([6]))
1004
def test_sym_difference_superset(self):
1005
self.set ^= set((2, 4, 6, 8))
1006
self.assertEqual(self.set, set([8]))
1008
def test_sym_difference_overlap(self):
1009
self.set ^= set((3, 4, 5))
1010
self.assertEqual(self.set, set([2, 3, 5, 6]))
1012
def test_sym_difference_non_overlap(self):
1013
self.set ^= set([8])
1014
self.assertEqual(self.set, set([2, 4, 6, 8]))
1016
def test_sym_difference_method_call(self):
1017
self.set.symmetric_difference_update(set([3, 4, 5]))
1018
self.assertEqual(self.set, set([2, 3, 5, 6]))
1020
def test_difference_subset(self):
1021
self.set -= set((2, 4))
1022
self.assertEqual(self.set, set([6]))
1024
def test_difference_superset(self):
1025
self.set -= set((2, 4, 6, 8))
1026
self.assertEqual(self.set, set([]))
1028
def test_difference_overlap(self):
1029
self.set -= set((3, 4, 5))
1030
self.assertEqual(self.set, set([2, 6]))
1032
def test_difference_non_overlap(self):
1033
self.set -= set([8])
1034
self.assertEqual(self.set, set([2, 4, 6]))
1036
def test_difference_method_call(self):
1037
self.set.difference_update(set([3, 4, 5]))
1038
self.assertEqual(self.set, set([2, 6]))
1040
#==============================================================================
1042
class TestMutate(unittest.TestCase):
1044
self.values = ["a", "b", "c"]
1045
self.set = set(self.values)
1047
def test_add_present(self):
1049
self.assertEqual(self.set, set("abc"))
1051
def test_add_absent(self):
1053
self.assertEqual(self.set, set("abcd"))
1055
def test_add_until_full(self):
1058
for v in self.values:
1061
self.assertEqual(len(tmp), expected_len)
1062
self.assertEqual(tmp, self.set)
1064
def test_remove_present(self):
1065
self.set.remove("b")
1066
self.assertEqual(self.set, set("ac"))
1068
def test_remove_absent(self):
1070
self.set.remove("d")
1071
self.fail("Removing missing element should have raised LookupError")
1075
def test_remove_until_empty(self):
1076
expected_len = len(self.set)
1077
for v in self.values:
1080
self.assertEqual(len(self.set), expected_len)
1082
def test_discard_present(self):
1083
self.set.discard("c")
1084
self.assertEqual(self.set, set("ab"))
1086
def test_discard_absent(self):
1087
self.set.discard("d")
1088
self.assertEqual(self.set, set("abc"))
1090
def test_clear(self):
1092
self.assertEqual(len(self.set), 0)
1097
popped[self.set.pop()] = None
1098
self.assertEqual(len(popped), len(self.values))
1099
for v in self.values:
1100
self.failUnless(v in popped)
1102
def test_update_empty_tuple(self):
1104
self.assertEqual(self.set, set(self.values))
1106
def test_update_unit_tuple_overlap(self):
1107
self.set.update(("a",))
1108
self.assertEqual(self.set, set(self.values))
1110
def test_update_unit_tuple_non_overlap(self):
1111
self.set.update(("a", "z"))
1112
self.assertEqual(self.set, set(self.values + ["z"]))
1114
#==============================================================================
1116
class TestSubsets(unittest.TestCase):
1118
case2method = {"<=": "issubset",
1122
reverse = {"==": "==",
1130
def test_issubset(self):
1133
for case in "!=", "==", "<", "<=", ">", ">=":
1134
expected = case in self.cases
1135
# Test the binary infix spelling.
1136
result = eval("x" + case + "y", locals())
1137
self.assertEqual(result, expected)
1138
# Test the "friendly" method-name spelling, if one exists.
1139
if case in TestSubsets.case2method:
1140
method = getattr(x, TestSubsets.case2method[case])
1142
self.assertEqual(result, expected)
1144
# Now do the same for the operands reversed.
1145
rcase = TestSubsets.reverse[case]
1146
result = eval("y" + rcase + "x", locals())
1147
self.assertEqual(result, expected)
1148
if rcase in TestSubsets.case2method:
1149
method = getattr(y, TestSubsets.case2method[rcase])
1151
self.assertEqual(result, expected)
1152
#------------------------------------------------------------------------------
1154
class TestSubsetEqualEmpty(TestSubsets):
1158
cases = "==", "<=", ">="
1160
#------------------------------------------------------------------------------
1162
class TestSubsetEqualNonEmpty(TestSubsets):
1166
cases = "==", "<=", ">="
1168
#------------------------------------------------------------------------------
1170
class TestSubsetEmptyNonEmpty(TestSubsets):
1173
name = "one empty, one non-empty"
1174
cases = "!=", "<", "<="
1176
#------------------------------------------------------------------------------
1178
class TestSubsetPartial(TestSubsets):
1181
name = "one a non-empty proper subset of other"
1182
cases = "!=", "<", "<="
1184
#------------------------------------------------------------------------------
1186
class TestSubsetNonOverlap(TestSubsets):
1189
name = "neither empty, neither contains"
1192
#==============================================================================
1194
class TestOnlySetsInBinaryOps(unittest.TestCase):
1196
def test_eq_ne(self):
1197
# Unlike the others, this is testing that == and != *are* allowed.
1198
self.assertEqual(self.other == self.set, False)
1199
self.assertEqual(self.set == self.other, False)
1200
self.assertEqual(self.other != self.set, True)
1201
self.assertEqual(self.set != self.other, True)
1203
def test_ge_gt_le_lt(self):
1204
self.assertRaises(TypeError, lambda: self.set < self.other)
1205
self.assertRaises(TypeError, lambda: self.set <= self.other)
1206
self.assertRaises(TypeError, lambda: self.set > self.other)
1207
self.assertRaises(TypeError, lambda: self.set >= self.other)
1209
self.assertRaises(TypeError, lambda: self.other < self.set)
1210
self.assertRaises(TypeError, lambda: self.other <= self.set)
1211
self.assertRaises(TypeError, lambda: self.other > self.set)
1212
self.assertRaises(TypeError, lambda: self.other >= self.set)
1214
def test_update_operator(self):
1216
self.set |= self.other
1220
self.fail("expected TypeError")
1222
def test_update(self):
1223
if self.otherIsIterable:
1224
self.set.update(self.other)
1226
self.assertRaises(TypeError, self.set.update, self.other)
1228
def test_union(self):
1229
self.assertRaises(TypeError, lambda: self.set | self.other)
1230
self.assertRaises(TypeError, lambda: self.other | self.set)
1231
if self.otherIsIterable:
1232
self.set.union(self.other)
1234
self.assertRaises(TypeError, self.set.union, self.other)
1236
def test_intersection_update_operator(self):
1238
self.set &= self.other
1242
self.fail("expected TypeError")
1244
def test_intersection_update(self):
1245
if self.otherIsIterable:
1246
self.set.intersection_update(self.other)
1248
self.assertRaises(TypeError,
1249
self.set.intersection_update,
1252
def test_intersection(self):
1253
self.assertRaises(TypeError, lambda: self.set & self.other)
1254
self.assertRaises(TypeError, lambda: self.other & self.set)
1255
if self.otherIsIterable:
1256
self.set.intersection(self.other)
1258
self.assertRaises(TypeError, self.set.intersection, self.other)
1260
def test_sym_difference_update_operator(self):
1262
self.set ^= self.other
1266
self.fail("expected TypeError")
1268
def test_sym_difference_update(self):
1269
if self.otherIsIterable:
1270
self.set.symmetric_difference_update(self.other)
1272
self.assertRaises(TypeError,
1273
self.set.symmetric_difference_update,
1276
def test_sym_difference(self):
1277
self.assertRaises(TypeError, lambda: self.set ^ self.other)
1278
self.assertRaises(TypeError, lambda: self.other ^ self.set)
1279
if self.otherIsIterable:
1280
self.set.symmetric_difference(self.other)
1282
self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1284
def test_difference_update_operator(self):
1286
self.set -= self.other
1290
self.fail("expected TypeError")
1292
def test_difference_update(self):
1293
if self.otherIsIterable:
1294
self.set.difference_update(self.other)
1296
self.assertRaises(TypeError,
1297
self.set.difference_update,
1300
def test_difference(self):
1301
self.assertRaises(TypeError, lambda: self.set - self.other)
1302
self.assertRaises(TypeError, lambda: self.other - self.set)
1303
if self.otherIsIterable:
1304
self.set.difference(self.other)
1306
self.assertRaises(TypeError, self.set.difference, self.other)
1308
#------------------------------------------------------------------------------
1310
class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1312
self.set = set((1, 2, 3))
1314
self.otherIsIterable = False
1316
#------------------------------------------------------------------------------
1318
class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1320
self.set = set((1, 2, 3))
1321
self.other = {1:2, 3:4}
1322
self.otherIsIterable = True
1324
#------------------------------------------------------------------------------
1326
class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1328
self.set = set((1, 2, 3))
1329
self.other = operator.add
1330
self.otherIsIterable = False
1332
#------------------------------------------------------------------------------
1334
class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1336
self.set = set((1, 2, 3))
1337
self.other = (2, 4, 6)
1338
self.otherIsIterable = True
1340
#------------------------------------------------------------------------------
1342
class TestOnlySetsString(TestOnlySetsInBinaryOps):
1344
self.set = set((1, 2, 3))
1346
self.otherIsIterable = True
1348
#------------------------------------------------------------------------------
1350
class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1353
for i in xrange(0, 10, 2):
1355
self.set = set((1, 2, 3))
1357
self.otherIsIterable = True
1359
#==============================================================================
1361
class TestCopying(unittest.TestCase):
1363
def test_copy(self):
1364
dup = self.set.copy()
1365
dup_list = list(dup); dup_list.sort()
1366
set_list = list(self.set); set_list.sort()
1367
self.assertEqual(len(dup_list), len(set_list))
1368
for i in range(len(dup_list)):
1369
self.failUnless(dup_list[i] is set_list[i])
1371
def test_deep_copy(self):
1372
dup = copy.deepcopy(self.set)
1373
##print type(dup), repr(dup)
1374
dup_list = list(dup); dup_list.sort()
1375
set_list = list(self.set); set_list.sort()
1376
self.assertEqual(len(dup_list), len(set_list))
1377
for i in range(len(dup_list)):
1378
self.assertEqual(dup_list[i], set_list[i])
1380
#------------------------------------------------------------------------------
1382
class TestCopyingEmpty(TestCopying):
1386
#------------------------------------------------------------------------------
1388
class TestCopyingSingleton(TestCopying):
1390
self.set = set(["hello"])
1392
#------------------------------------------------------------------------------
1394
class TestCopyingTriple(TestCopying):
1396
self.set = set(["zero", 0, None])
1398
#------------------------------------------------------------------------------
1400
class TestCopyingTuple(TestCopying):
1402
self.set = set([(1, 2)])
1404
#------------------------------------------------------------------------------
1406
class TestCopyingNested(TestCopying):
1408
self.set = set([((1, 2), (3, 4))])
1410
#==============================================================================
1412
class TestIdentities(unittest.TestCase):
1414
self.a = set('abracadabra')
1415
self.b = set('alacazam')
1417
def test_binopsVsSubsets(self):
1418
a, b = self.a, self.b
1419
self.assert_(a - b < a)
1420
self.assert_(b - a < b)
1421
self.assert_(a & b < a)
1422
self.assert_(a & b < b)
1423
self.assert_(a | b > a)
1424
self.assert_(a | b > b)
1425
self.assert_(a ^ b < a | b)
1427
def test_commutativity(self):
1428
a, b = self.a, self.b
1429
self.assertEqual(a&b, b&a)
1430
self.assertEqual(a|b, b|a)
1431
self.assertEqual(a^b, b^a)
1433
self.assertNotEqual(a-b, b-a)
1435
def test_summations(self):
1436
# check that sums of parts equal the whole
1437
a, b = self.a, self.b
1438
self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1439
self.assertEqual((a&b)|(a^b), a|b)
1440
self.assertEqual(a|(b-a), a|b)
1441
self.assertEqual((a-b)|b, a|b)
1442
self.assertEqual((a-b)|(a&b), a)
1443
self.assertEqual((b-a)|(a&b), b)
1444
self.assertEqual((a-b)|(b-a), a^b)
1446
def test_exclusion(self):
1447
# check that inverse operations show non-overlap
1448
a, b, zero = self.a, self.b, set()
1449
self.assertEqual((a-b)&b, zero)
1450
self.assertEqual((b-a)&a, zero)
1451
self.assertEqual((a&b)&(a^b), zero)
1453
# Tests derived from test_itertools.py =======================================
1461
'Sequence using __getitem__'
1462
def __init__(self, seqn):
1464
def __getitem__(self, i):
1468
'Sequence using iterator protocol'
1469
def __init__(self, seqn):
1475
if self.i >= len(self.seqn): raise StopIteration
1476
v = self.seqn[self.i]
1481
'Sequence using iterator protocol defined with a generator'
1482
def __init__(self, seqn):
1486
for val in self.seqn:
1490
'Missing __getitem__ and __iter__'
1491
def __init__(self, seqn):
1495
if self.i >= len(self.seqn): raise StopIteration
1496
v = self.seqn[self.i]
1501
'Iterator missing next()'
1502
def __init__(self, seqn):
1509
'Test propagation of exceptions'
1510
def __init__(self, seqn):
1519
'Test immediate stop'
1520
def __init__(self, seqn):
1527
from itertools import chain, imap
1529
'Test multiple tiers of iterators'
1530
return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1532
class TestVariousIteratorArgs(unittest.TestCase):
1534
def test_constructor(self):
1535
for cons in (set, frozenset):
1536
for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1537
for g in (G, I, Ig, S, L, R):
1538
self.assertEqual(sorted(cons(g(s))), sorted(g(s)))
1539
self.assertRaises(TypeError, cons , X(s))
1540
self.assertRaises(TypeError, cons , N(s))
1541
self.assertRaises(ZeroDivisionError, cons , E(s))
1543
def test_inline_methods(self):
1545
for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
1546
for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
1547
for g in (G, I, Ig, L, R):
1548
expected = meth(data)
1549
actual = meth(G(data))
1550
if isinstance(expected, bool):
1551
self.assertEqual(actual, expected)
1553
self.assertEqual(sorted(actual), sorted(expected))
1554
self.assertRaises(TypeError, meth, X(s))
1555
self.assertRaises(TypeError, meth, N(s))
1556
self.assertRaises(ZeroDivisionError, meth, E(s))
1558
def test_inplace_methods(self):
1559
for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
1560
for methname in ('update', 'intersection_update',
1561
'difference_update', 'symmetric_difference_update'):
1562
for g in (G, I, Ig, S, L, R):
1565
getattr(s, methname)(list(g(data)))
1566
getattr(t, methname)(g(data))
1567
self.assertEqual(sorted(s), sorted(t))
1569
self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1570
self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1571
self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1573
# Application tests (based on David Eppstein's graph recipes ====================================
1576
"""Generates all subsets of a set or sequence U."""
1579
x = frozenset([U.next()])
1580
for S in powerset(U):
1583
except StopIteration:
1587
"""Graph of n-dimensional hypercube."""
1588
singletons = [frozenset([x]) for x in range(n)]
1589
return dict([(x, frozenset([x^s for s in singletons]))
1590
for x in powerset(range(n))])
1593
"""Graph, the vertices of which are edges of G,
1594
with two vertices being adjacent iff the corresponding
1595
edges share a vertex."""
1599
nx = [frozenset([x,z]) for z in G[x] if z != y]
1600
ny = [frozenset([y,z]) for z in G[y] if z != x]
1601
L[frozenset([x,y])] = frozenset(nx+ny)
1605
'Return a set of faces in G. Where a face is a set of vertices on that face'
1606
# currently limited to triangles,squares, and pentagons
1608
for v1, edges in G.items():
1614
f.add(frozenset([v1, v2, v3]))
1620
f.add(frozenset([v1, v2, v3, v4]))
1623
if v5 == v3 or v5 == v2:
1626
f.add(frozenset([v1, v2, v3, v4, v5]))
1630
class TestGraphs(unittest.TestCase):
1632
def test_cube(self):
1634
g = cube(3) # vert --> {v1, v2, v3}
1636
self.assertEqual(len(vertices1), 8) # eight vertices
1637
for edge in g.values():
1638
self.assertEqual(len(edge), 3) # each vertex connects to three edges
1639
vertices2 = set(v for edges in g.values() for v in edges)
1640
self.assertEqual(vertices1, vertices2) # edge vertices in original set
1642
cubefaces = faces(g)
1643
self.assertEqual(len(cubefaces), 6) # six faces
1644
for face in cubefaces:
1645
self.assertEqual(len(face), 4) # each face is a square
1647
def test_cuboctahedron(self):
1649
# http://en.wikipedia.org/wiki/Cuboctahedron
1650
# 8 triangular faces and 6 square faces
1651
# 12 indentical vertices each connecting a triangle and square
1654
cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1655
self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1657
vertices = set(cuboctahedron)
1658
for edges in cuboctahedron.values():
1659
self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1660
othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1661
self.assertEqual(vertices, othervertices) # edge vertices in original set
1663
cubofaces = faces(cuboctahedron)
1664
facesizes = collections.defaultdict(int)
1665
for face in cubofaces:
1666
facesizes[len(face)] += 1
1667
self.assertEqual(facesizes[3], 8) # eight triangular faces
1668
self.assertEqual(facesizes[4], 6) # six square faces
1670
for vertex in cuboctahedron:
1671
edge = vertex # Cuboctahedron vertices are edges in Cube
1672
self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1673
for cubevert in edge:
1674
self.assert_(cubevert in g)
1677
#==============================================================================
1679
def test_main(verbose=None):
1680
from test import test_sets
1684
TestSetSubclassWithKeywordArgs,
1686
TestFrozenSetSubclass,
1688
TestExceptionPropagation,
1690
TestBasicOpsSingleton,
1696
TestSubsetEqualEmpty,
1697
TestSubsetEqualNonEmpty,
1698
TestSubsetEmptyNonEmpty,
1700
TestSubsetNonOverlap,
1701
TestOnlySetsNumeric,
1703
TestOnlySetsOperator,
1706
TestOnlySetsGenerator,
1708
TestCopyingSingleton,
1713
TestVariousIteratorArgs,
1717
test_support.run_unittest(*test_classes)
1719
# verify reference counting
1720
if verbose and hasattr(sys, "gettotalrefcount"):
1723
for i in xrange(len(counts)):
1724
test_support.run_unittest(*test_classes)
1726
counts[i] = sys.gettotalrefcount()
1729
if __name__ == "__main__":
1730
test_main(verbose=True)