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