Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | import unittest |
2 | from test import test_support, seq_tests | |
3 | ||
4 | class TupleTest(seq_tests.CommonTest): | |
5 | type2test = tuple | |
6 | ||
7 | def test_constructors(self): | |
8 | super(TupleTest, self).test_len() | |
9 | # calling built-in types without argument must return empty | |
10 | self.assertEqual(tuple(), ()) | |
11 | ||
12 | def test_truth(self): | |
13 | super(TupleTest, self).test_truth() | |
14 | self.assert_(not ()) | |
15 | self.assert_((42, )) | |
16 | ||
17 | def test_len(self): | |
18 | super(TupleTest, self).test_len() | |
19 | self.assertEqual(len(()), 0) | |
20 | self.assertEqual(len((0,)), 1) | |
21 | self.assertEqual(len((0, 1, 2)), 3) | |
22 | ||
23 | def test_iadd(self): | |
24 | super(TupleTest, self).test_iadd() | |
25 | u = (0, 1) | |
26 | u2 = u | |
27 | u += (2, 3) | |
28 | self.assert_(u is not u2) | |
29 | ||
30 | def test_imul(self): | |
31 | super(TupleTest, self).test_imul() | |
32 | u = (0, 1) | |
33 | u2 = u | |
34 | u *= 3 | |
35 | self.assert_(u is not u2) | |
36 | ||
37 | def test_tupleresizebug(self): | |
38 | # Check that a specific bug in _PyTuple_Resize() is squashed. | |
39 | def f(): | |
40 | for i in range(1000): | |
41 | yield i | |
42 | self.assertEqual(list(tuple(f())), range(1000)) | |
43 | ||
44 | def test_hash(self): | |
45 | # See SF bug 942952: Weakness in tuple hash | |
46 | # The hash should: | |
47 | # be non-commutative | |
48 | # should spread-out closely spaced values | |
49 | # should not exhibit cancellation in tuples like (x,(x,y)) | |
50 | # should be distinct from element hashes: hash(x)!=hash((x,)) | |
51 | # This test exercises those cases. | |
52 | # For a pure random hash and N=50, the expected number of occupied | |
53 | # buckets when tossing 252,600 balls into 2**32 buckets | |
54 | # is 252,592.6, or about 7.4 expected collisions. The | |
55 | # standard deviation is 2.73. On a box with 64-bit hash | |
56 | # codes, no collisions are expected. Here we accept no | |
57 | # more than 15 collisions. Any worse and the hash function | |
58 | # is sorely suspect. | |
59 | ||
60 | N=50 | |
61 | base = range(N) | |
62 | xp = [(i, j) for i in base for j in base] | |
63 | inps = base + [(i, j) for i in base for j in xp] + \ | |
64 | [(i, j) for i in xp for j in base] + xp + zip(base) | |
65 | collisions = len(inps) - len(set(map(hash, inps))) | |
66 | self.assert_(collisions <= 15) | |
67 | ||
68 | def test_repr(self): | |
69 | l0 = tuple() | |
70 | l2 = (0, 1, 2) | |
71 | a0 = self.type2test(l0) | |
72 | a2 = self.type2test(l2) | |
73 | ||
74 | self.assertEqual(str(a0), repr(l0)) | |
75 | self.assertEqual(str(a2), repr(l2)) | |
76 | self.assertEqual(repr(a0), "()") | |
77 | self.assertEqual(repr(a2), "(0, 1, 2)") | |
78 | ||
79 | def test_main(): | |
80 | test_support.run_unittest(TupleTest) | |
81 | ||
82 | if __name__=="__main__": | |
83 | test_main() |