~ubuntu-branches/ubuntu/trusty/python3.4/trusty-proposed

« back to all changes in this revision

Viewing changes to Lib/test/test_tuple.py

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-25 09:44:27 UTC
  • Revision ID: package-import@ubuntu.com-20131125094427-lzxj8ap5w01lmo7f
Tags: upstream-3.4~b1
ImportĀ upstreamĀ versionĀ 3.4~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from test import support, seq_tests
 
2
 
 
3
import gc
 
4
import pickle
 
5
 
 
6
class TupleTest(seq_tests.CommonTest):
 
7
    type2test = tuple
 
8
 
 
9
    def test_constructors(self):
 
10
        super().test_constructors()
 
11
        # calling built-in types without argument must return empty
 
12
        self.assertEqual(tuple(), ())
 
13
        t0_3 = (0, 1, 2, 3)
 
14
        t0_3_bis = tuple(t0_3)
 
15
        self.assertTrue(t0_3 is t0_3_bis)
 
16
        self.assertEqual(tuple([]), ())
 
17
        self.assertEqual(tuple([0, 1, 2, 3]), (0, 1, 2, 3))
 
18
        self.assertEqual(tuple(''), ())
 
19
        self.assertEqual(tuple('spam'), ('s', 'p', 'a', 'm'))
 
20
 
 
21
    def test_truth(self):
 
22
        super().test_truth()
 
23
        self.assertTrue(not ())
 
24
        self.assertTrue((42, ))
 
25
 
 
26
    def test_len(self):
 
27
        super().test_len()
 
28
        self.assertEqual(len(()), 0)
 
29
        self.assertEqual(len((0,)), 1)
 
30
        self.assertEqual(len((0, 1, 2)), 3)
 
31
 
 
32
    def test_iadd(self):
 
33
        super().test_iadd()
 
34
        u = (0, 1)
 
35
        u2 = u
 
36
        u += (2, 3)
 
37
        self.assertTrue(u is not u2)
 
38
 
 
39
    def test_imul(self):
 
40
        super().test_imul()
 
41
        u = (0, 1)
 
42
        u2 = u
 
43
        u *= 3
 
44
        self.assertTrue(u is not u2)
 
45
 
 
46
    def test_tupleresizebug(self):
 
47
        # Check that a specific bug in _PyTuple_Resize() is squashed.
 
48
        def f():
 
49
            for i in range(1000):
 
50
                yield i
 
51
        self.assertEqual(list(tuple(f())), list(range(1000)))
 
52
 
 
53
    def test_hash(self):
 
54
        # See SF bug 942952:  Weakness in tuple hash
 
55
        # The hash should:
 
56
        #      be non-commutative
 
57
        #      should spread-out closely spaced values
 
58
        #      should not exhibit cancellation in tuples like (x,(x,y))
 
59
        #      should be distinct from element hashes:  hash(x)!=hash((x,))
 
60
        # This test exercises those cases.
 
61
        # For a pure random hash and N=50, the expected number of occupied
 
62
        #      buckets when tossing 252,600 balls into 2**32 buckets
 
63
        #      is 252,592.6, or about 7.4 expected collisions.  The
 
64
        #      standard deviation is 2.73.  On a box with 64-bit hash
 
65
        #      codes, no collisions are expected.  Here we accept no
 
66
        #      more than 15 collisions.  Any worse and the hash function
 
67
        #      is sorely suspect.
 
68
 
 
69
        N=50
 
70
        base = list(range(N))
 
71
        xp = [(i, j) for i in base for j in base]
 
72
        inps = base + [(i, j) for i in base for j in xp] + \
 
73
                     [(i, j) for i in xp for j in base] + xp + list(zip(base))
 
74
        collisions = len(inps) - len(set(map(hash, inps)))
 
75
        self.assertTrue(collisions <= 15)
 
76
 
 
77
    def test_repr(self):
 
78
        l0 = tuple()
 
79
        l2 = (0, 1, 2)
 
80
        a0 = self.type2test(l0)
 
81
        a2 = self.type2test(l2)
 
82
 
 
83
        self.assertEqual(str(a0), repr(l0))
 
84
        self.assertEqual(str(a2), repr(l2))
 
85
        self.assertEqual(repr(a0), "()")
 
86
        self.assertEqual(repr(a2), "(0, 1, 2)")
 
87
 
 
88
    def _not_tracked(self, t):
 
89
        # Nested tuples can take several collections to untrack
 
90
        gc.collect()
 
91
        gc.collect()
 
92
        self.assertFalse(gc.is_tracked(t), t)
 
93
 
 
94
    def _tracked(self, t):
 
95
        self.assertTrue(gc.is_tracked(t), t)
 
96
        gc.collect()
 
97
        gc.collect()
 
98
        self.assertTrue(gc.is_tracked(t), t)
 
99
 
 
100
    @support.cpython_only
 
101
    def test_track_literals(self):
 
102
        # Test GC-optimization of tuple literals
 
103
        x, y, z = 1.5, "a", []
 
104
 
 
105
        self._not_tracked(())
 
106
        self._not_tracked((1,))
 
107
        self._not_tracked((1, 2))
 
108
        self._not_tracked((1, 2, "a"))
 
109
        self._not_tracked((1, 2, (None, True, False, ()), int))
 
110
        self._not_tracked((object(),))
 
111
        self._not_tracked(((1, x), y, (2, 3)))
 
112
 
 
113
        # Tuples with mutable elements are always tracked, even if those
 
114
        # elements are not tracked right now.
 
115
        self._tracked(([],))
 
116
        self._tracked(([1],))
 
117
        self._tracked(({},))
 
118
        self._tracked((set(),))
 
119
        self._tracked((x, y, z))
 
120
 
 
121
    def check_track_dynamic(self, tp, always_track):
 
122
        x, y, z = 1.5, "a", []
 
123
 
 
124
        check = self._tracked if always_track else self._not_tracked
 
125
        check(tp())
 
126
        check(tp([]))
 
127
        check(tp(set()))
 
128
        check(tp([1, x, y]))
 
129
        check(tp(obj for obj in [1, x, y]))
 
130
        check(tp(set([1, x, y])))
 
131
        check(tp(tuple([obj]) for obj in [1, x, y]))
 
132
        check(tuple(tp([obj]) for obj in [1, x, y]))
 
133
 
 
134
        self._tracked(tp([z]))
 
135
        self._tracked(tp([[x, y]]))
 
136
        self._tracked(tp([{x: y}]))
 
137
        self._tracked(tp(obj for obj in [x, y, z]))
 
138
        self._tracked(tp(tuple([obj]) for obj in [x, y, z]))
 
139
        self._tracked(tuple(tp([obj]) for obj in [x, y, z]))
 
140
 
 
141
    @support.cpython_only
 
142
    def test_track_dynamic(self):
 
143
        # Test GC-optimization of dynamically constructed tuples.
 
144
        self.check_track_dynamic(tuple, False)
 
145
 
 
146
    @support.cpython_only
 
147
    def test_track_subtypes(self):
 
148
        # Tuple subtypes must always be tracked
 
149
        class MyTuple(tuple):
 
150
            pass
 
151
        self.check_track_dynamic(MyTuple, True)
 
152
 
 
153
    @support.cpython_only
 
154
    def test_bug7466(self):
 
155
        # Trying to untrack an unfinished tuple could crash Python
 
156
        self._not_tracked(tuple(gc.collect() for i in range(101)))
 
157
 
 
158
    def test_repr_large(self):
 
159
        # Check the repr of large list objects
 
160
        def check(n):
 
161
            l = (0,) * n
 
162
            s = repr(l)
 
163
            self.assertEqual(s,
 
164
                '(' + ', '.join(['0'] * n) + ')')
 
165
        check(10)       # check our checking code
 
166
        check(1000000)
 
167
 
 
168
    def test_iterator_pickle(self):
 
169
        # Userlist iterators don't support pickling yet since
 
170
        # they are based on generators.
 
171
        data = self.type2test([4, 5, 6, 7])
 
172
        itorg = iter(data)
 
173
        d = pickle.dumps(itorg)
 
174
        it = pickle.loads(d)
 
175
        self.assertEqual(type(itorg), type(it))
 
176
        self.assertEqual(self.type2test(it), self.type2test(data))
 
177
 
 
178
        it = pickle.loads(d)
 
179
        next(it)
 
180
        d = pickle.dumps(it)
 
181
        self.assertEqual(self.type2test(it), self.type2test(data)[1:])
 
182
 
 
183
    def test_reversed_pickle(self):
 
184
        data = self.type2test([4, 5, 6, 7])
 
185
        itorg = reversed(data)
 
186
        d = pickle.dumps(itorg)
 
187
        it = pickle.loads(d)
 
188
        self.assertEqual(type(itorg), type(it))
 
189
        self.assertEqual(self.type2test(it), self.type2test(reversed(data)))
 
190
 
 
191
        it = pickle.loads(d)
 
192
        next(it)
 
193
        d = pickle.dumps(it)
 
194
        self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:])
 
195
 
 
196
    def test_no_comdat_folding(self):
 
197
        # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding
 
198
        # optimization causes failures in code that relies on distinct
 
199
        # function addresses.
 
200
        class T(tuple): pass
 
201
        with self.assertRaises(TypeError):
 
202
            [3,] + T((1,2))
 
203
 
 
204
def test_main():
 
205
    support.run_unittest(TupleTest)
 
206
 
 
207
if __name__=="__main__":
 
208
    test_main()