~bzr-pqm/bzr/bzr.dev

4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2009, 2010 Canonical Ltd
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
17
"""Tests for the StaticTuple type."""
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
18
4759.2.16 by Matt Nordhoff
Add a test
19
import cPickle
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
20
import gc
4679.3.2 by John Arbash Meinel
Add a get_key() function, which then returns tuples for the given items.
21
import sys
22
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
23
from bzrlib import (
4679.3.40 by John Arbash Meinel
Switch away from the name Key instead start branding as StaticTuple.
24
    _static_tuple_py,
4668.3.1 by John Arbash Meinel
Fix bug #471193, allow tuples into the CHK code.
25
    debug,
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
26
    errors,
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
27
    osutils,
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
28
    static_tuple,
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
29
    tests,
30
    )
31
32
33
def load_tests(standard_tests, module, loader):
34
    """Parameterize tests for all versions of groupcompress."""
4913.3.1 by John Arbash Meinel
Implement a permute_for_extension helper.
35
    global compiled_static_tuple_feature
36
    suite, compiled_static_tuple_feature = tests.permute_tests_for_extension(
37
        standard_tests, loader, 'bzrlib._static_tuple_py',
38
        'bzrlib._static_tuple_c')
39
    return suite
4679.3.1 by John Arbash Meinel
Start working on a Keys type.
40
41
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
42
class _Meliae(tests.Feature):
43
44
    def _probe(self):
45
        try:
46
            from meliae import scanner
47
        except ImportError:
48
            return False
49
        return True
50
51
    def feature_name(self):
52
        return "Meliae - python memory debugger"
53
54
Meliae = _Meliae()
55
56
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
57
class TestStaticTuple(tests.TestCase):
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
58
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
59
    def assertRefcount(self, count, obj):
60
        """Assert that the refcount for obj is what we expect.
61
62
        Note that this automatically adjusts for the fact that calling
63
        assertRefcount actually creates a new pointer, as does calling
64
        sys.getrefcount. So pass the expected value *before* the call.
65
        """
66
        # I don't understand why it is getrefcount()-3 here, but it seems to be
67
        # correct. If I check in the calling function, with:
68
        # self.assertEqual(count, sys.getrefcount(obj)-1)
69
        # Then it works fine. Something about passing it to assertRefcount is
70
        # actually double-incrementing (and decrementing) the refcount
71
        self.assertEqual(count, sys.getrefcount(obj)-3)
72
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
73
    def test_create(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
74
        k = self.module.StaticTuple('foo')
75
        k = self.module.StaticTuple('foo', 'bar')
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
76
77
    def test_create_bad_args(self):
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
78
        args_256 = ['a']*256
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
79
        # too many args
4763.2.2 by Matt Nordhoff
Oops, really commit the test changes this time
80
        self.assertRaises(TypeError, self.module.StaticTuple, *args_256)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
81
        args_300 = ['a']*300
4763.2.2 by Matt Nordhoff
Oops, really commit the test changes this time
82
        self.assertRaises(TypeError, self.module.StaticTuple, *args_300)
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
83
        # not a string
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
84
        self.assertRaises(TypeError, self.module.StaticTuple, object())
4759.2.2 by John Arbash Meinel
Update _static_tuple_py.py with the same concatenation behavior
85
86
    def test_concat(self):
87
        st1 = self.module.StaticTuple('foo')
88
        st2 = self.module.StaticTuple('bar')
89
        st3 = self.module.StaticTuple('foo', 'bar')
90
        st4 = st1 + st2
91
        self.assertEqual(st3, st4)
92
        self.assertIsInstance(st4, self.module.StaticTuple)
93
94
    def test_concat_with_tuple(self):
95
        st1 = self.module.StaticTuple('foo')
96
        t2 = ('bar',)
97
        st3 = self.module.StaticTuple('foo', 'bar')
98
        st4 = self.module.StaticTuple('bar', 'foo')
99
        st5 = st1 + t2
100
        st6 = t2 + st1
101
        self.assertEqual(st3, st5)
102
        self.assertIsInstance(st5, self.module.StaticTuple)
103
        self.assertEqual(st4, st6)
104
        if self.module is _static_tuple_py:
105
            # _static_tuple_py has StaticTuple(tuple), so tuple thinks it
106
            # already knows how to concatenate, as such we can't "inject" our
107
            # own concatenation...
108
            self.assertIsInstance(st6, tuple)
109
        else:
110
            self.assertIsInstance(st6, self.module.StaticTuple)
111
112
    def test_concat_with_bad_tuple(self):
113
        st1 = self.module.StaticTuple('foo')
114
        t2 = (object(),)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
115
        # Using st1.__add__ doesn't give the same results as doing the '+' form
116
        self.assertRaises(TypeError, lambda: st1 + t2)
4759.2.5 by John Arbash Meinel
Add a bit more tests.
117
118
    def test_concat_with_non_tuple(self):
119
        st1 = self.module.StaticTuple('foo')
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
120
        self.assertRaises(TypeError, lambda: st1 + 10)
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
121
        
122
    def test_as_tuple(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
123
        k = self.module.StaticTuple('foo')
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
124
        t = k.as_tuple()
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
125
        self.assertEqual(('foo',), t)
4789.28.3 by John Arbash Meinel
Add a static_tuple.as_tuples() helper.
126
        self.assertIsInstance(t, tuple)
127
        self.assertFalse(isinstance(t, self.module.StaticTuple))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
128
        k = self.module.StaticTuple('foo', 'bar')
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
129
        t = k.as_tuple()
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
130
        self.assertEqual(('foo', 'bar'), t)
4789.28.3 by John Arbash Meinel
Add a static_tuple.as_tuples() helper.
131
        k2 = self.module.StaticTuple(1, k)
132
        t = k2.as_tuple()
133
        self.assertIsInstance(t, tuple)
134
        # For pickling to work, we need to keep the sub-items as StaticTuple so
135
        # that it knows that they also need to be converted.
136
        self.assertIsInstance(t[1], self.module.StaticTuple)
137
        self.assertEqual((1, ('foo', 'bar')), t)
138
139
    def test_as_tuples(self):
140
        k1 = self.module.StaticTuple('foo', 'bar')
141
        t = static_tuple.as_tuples(k1)
142
        self.assertIsInstance(t, tuple)
143
        self.assertEqual(('foo', 'bar'), t)
144
        k2 = self.module.StaticTuple(1, k1)
145
        t = static_tuple.as_tuples(k2)
146
        self.assertIsInstance(t, tuple)
147
        self.assertIsInstance(t[1], tuple)
148
        self.assertEqual((1, ('foo', 'bar')), t)
149
        mixed = (1, k1)
150
        t = static_tuple.as_tuples(mixed)
151
        self.assertIsInstance(t, tuple)
152
        self.assertIsInstance(t[1], tuple)
153
        self.assertEqual((1, ('foo', 'bar')), t)
4679.3.16 by John Arbash Meinel
Initial work for a Key class.
154
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
155
    def test_len(self):
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
156
        k = self.module.StaticTuple()
157
        self.assertEqual(0, len(k))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
158
        k = self.module.StaticTuple('foo')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
159
        self.assertEqual(1, len(k))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
160
        k = self.module.StaticTuple('foo', 'bar')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
161
        self.assertEqual(2, len(k))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
162
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'b')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
163
        self.assertEqual(7, len(k))
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
164
        args = ['foo']*255
165
        k = self.module.StaticTuple(*args)
166
        self.assertEqual(255, len(k))
167
168
    def test_hold_other_static_tuples(self):
169
        k = self.module.StaticTuple('foo', 'bar')
170
        k2 = self.module.StaticTuple(k, k)
171
        self.assertEqual(2, len(k2))
172
        self.assertIs(k, k2[0])
173
        self.assertIs(k, k2[1])
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
174
175
    def test_getitem(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
176
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'z')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
177
        self.assertEqual('foo', k[0])
178
        self.assertEqual('foo', k[0])
179
        self.assertEqual('foo', k[0])
180
        self.assertEqual('z', k[6])
181
        self.assertEqual('z', k[-1])
4679.5.5 by John Arbash Meinel
Review feedback from Andrew Bennetts.
182
        self.assertRaises(IndexError, k.__getitem__, 7)
183
        self.assertRaises(IndexError, k.__getitem__, 256+7)
184
        self.assertRaises(IndexError, k.__getitem__, 12024)
185
        # Python's [] resolver handles the negative arguments, so we can't
186
        # really test StaticTuple_item() with negative values.
187
        self.assertRaises(TypeError, k.__getitem__, 'not-an-int')
188
        self.assertRaises(TypeError, k.__getitem__, '5')
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
189
190
    def test_refcount(self):
191
        f = 'fo' + 'oo'
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
192
        num_refs = sys.getrefcount(f) - 1 #sys.getrefcount() adds one
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
193
        k = self.module.StaticTuple(f)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
194
        self.assertRefcount(num_refs + 1, f)
195
        b = k[0]
196
        self.assertRefcount(num_refs + 2, f)
197
        b = k[0]
198
        self.assertRefcount(num_refs + 2, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
199
        c = k[0]
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
200
        self.assertRefcount(num_refs + 3, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
201
        del b, c
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
202
        self.assertRefcount(num_refs + 1, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
203
        del k
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
204
        self.assertRefcount(num_refs, f)
4679.3.17 by John Arbash Meinel
Implement some of the sequence items.
205
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
206
    def test__repr__(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
207
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
4679.3.79 by John Arbash Meinel
Change the repr to print out 'StaticTuple'
208
        self.assertEqual("StaticTuple('foo', 'bar', 'baz', 'bing')", repr(k))
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
209
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
210
    def assertCompareEqual(self, k1, k2):
211
        self.assertTrue(k1 == k2)
212
        self.assertTrue(k1 <= k2)
213
        self.assertTrue(k1 >= k2)
214
        self.assertFalse(k1 != k2)
215
        self.assertFalse(k1 < k2)
216
        self.assertFalse(k1 > k2)
217
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
218
    def test_holds_None(self):
219
        k1 = self.module.StaticTuple(None)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
220
        # You cannot subclass None anyway
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
221
222
    def test_holds_int(self):
223
        k1 = self.module.StaticTuple(1)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
224
        class subint(int):
225
            pass
226
        # But not a subclass, because subint could introduce refcycles
227
        self.assertRaises(TypeError, self.module.StaticTuple, subint(2))
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
228
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
229
    def test_holds_long(self):
230
        k1 = self.module.StaticTuple(2L**65)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
231
        class sublong(long):
232
            pass
233
        # But not a subclass
234
        self.assertRaises(TypeError, self.module.StaticTuple, sublong(1))
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
235
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
236
    def test_holds_float(self):
237
        k1 = self.module.StaticTuple(1.2)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
238
        class subfloat(float):
239
            pass
240
        self.assertRaises(TypeError, self.module.StaticTuple, subfloat(1.5))
241
242
    def test_holds_str(self):
243
        k1 = self.module.StaticTuple('astring')
244
        class substr(str):
245
            pass
246
        self.assertRaises(TypeError, self.module.StaticTuple, substr('a'))
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
247
248
    def test_holds_unicode(self):
249
        k1 = self.module.StaticTuple(u'\xb5')
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
250
        class subunicode(unicode):
251
            pass
252
        self.assertRaises(TypeError, self.module.StaticTuple,
253
                          subunicode(u'\xb5'))
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
254
255
    def test_hold_bool(self):
256
        k1 = self.module.StaticTuple(True)
257
        k2 = self.module.StaticTuple(False)
4759.2.11 by John Arbash Meinel
Review feedback from Andrew.
258
        # Cannot subclass bool
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
259
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
260
    def test_compare_same_obj(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
261
        k1 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
262
        self.assertCompareEqual(k1, k1)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
263
        k2 = self.module.StaticTuple(k1, k1)
264
        self.assertCompareEqual(k2, k2)
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
265
        k3 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
266
                                     k1)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
267
        self.assertCompareEqual(k3, k3)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
268
269
    def test_compare_equivalent_obj(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
270
        k1 = self.module.StaticTuple('foo', 'bar')
271
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
272
        self.assertCompareEqual(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
273
        k3 = self.module.StaticTuple(k1, k2)
274
        k4 = self.module.StaticTuple(k2, k1)
275
        self.assertCompareEqual(k1, k2)
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
276
        k5 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
277
                                     k1)
278
        k6 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
279
                                     k1)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
280
        self.assertCompareEqual(k5, k6)
281
        k7 = self.module.StaticTuple(None)
282
        k8 = self.module.StaticTuple(None)
283
        self.assertCompareEqual(k7, k8)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
284
285
    def test_compare_similar_obj(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
286
        k1 = self.module.StaticTuple('foo' + ' bar', 'bar' + ' baz')
287
        k2 = self.module.StaticTuple('fo' + 'o bar', 'ba' + 'r baz')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
288
        self.assertCompareEqual(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
289
        k3 = self.module.StaticTuple('foo ' + 'bar', 'bar ' + 'baz')
290
        k4 = self.module.StaticTuple('f' + 'oo bar', 'b' + 'ar baz')
291
        k5 = self.module.StaticTuple(k1, k2)
292
        k6 = self.module.StaticTuple(k3, k4)
293
        self.assertCompareEqual(k5, k6)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
294
295
    def assertCompareDifferent(self, k_small, k_big):
296
        self.assertFalse(k_small == k_big)
297
        self.assertFalse(k_small >= k_big)
298
        self.assertFalse(k_small > k_big)
299
        self.assertTrue(k_small != k_big)
300
        self.assertTrue(k_small <= k_big)
301
        self.assertTrue(k_small < k_big)
302
4679.5.8 by John Arbash Meinel
Add some tests that we *can* compare to strings, even if we don't care
303
    def assertCompareNoRelation(self, k1, k2):
304
        """Run the comparison operators, make sure they do something.
305
306
        However, we don't actually care what comes first or second. This is
307
        stuff like cross-class comparisons. We don't want to segfault/raise an
308
        exception, but we don't care about the sort order.
309
        """
310
        self.assertFalse(k1 == k2)
311
        self.assertTrue(k1 != k2)
312
        # Do the comparison, but we don't care about the result
313
        k1 >= k2
314
        k1 > k2
315
        k1 <= k2
316
        k1 < k2
317
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
318
    def test_compare_vs_none(self):
319
        k1 = self.module.StaticTuple('baz', 'bing')
320
        self.assertCompareDifferent(None, k1)
4679.5.8 by John Arbash Meinel
Add some tests that we *can* compare to strings, even if we don't care
321
    
322
    def test_compare_cross_class(self):
323
        k1 = self.module.StaticTuple('baz', 'bing')
324
        self.assertCompareNoRelation(10, k1)
325
        self.assertCompareNoRelation('baz', k1)
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
326
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
327
    def test_compare_all_different_same_width(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
328
        k1 = self.module.StaticTuple('baz', 'bing')
329
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
330
        self.assertCompareDifferent(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
331
        k3 = self.module.StaticTuple(k1, k2)
332
        k4 = self.module.StaticTuple(k2, k1)
333
        self.assertCompareDifferent(k3, k4)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
334
        k5 = self.module.StaticTuple(1)
335
        k6 = self.module.StaticTuple(2)
336
        self.assertCompareDifferent(k5, k6)
337
        k7 = self.module.StaticTuple(1.2)
338
        k8 = self.module.StaticTuple(2.4)
339
        self.assertCompareDifferent(k7, k8)
340
        k9 = self.module.StaticTuple(u's\xb5')
341
        k10 = self.module.StaticTuple(u's\xe5')
342
        self.assertCompareDifferent(k9, k10)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
343
344
    def test_compare_some_different(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
345
        k1 = self.module.StaticTuple('foo', 'bar')
346
        k2 = self.module.StaticTuple('foo', 'zzz')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
347
        self.assertCompareDifferent(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
348
        k3 = self.module.StaticTuple(k1, k1)
349
        k4 = self.module.StaticTuple(k1, k2)
350
        self.assertCompareDifferent(k3, k4)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
351
        k5 = self.module.StaticTuple('foo', None)
352
        self.assertCompareDifferent(k5, k1)
353
        self.assertCompareDifferent(k5, k2)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
354
355
    def test_compare_diff_width(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
356
        k1 = self.module.StaticTuple('foo')
357
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
358
        self.assertCompareDifferent(k1, k2)
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
359
        k3 = self.module.StaticTuple(k1)
360
        k4 = self.module.StaticTuple(k1, k2)
361
        self.assertCompareDifferent(k3, k4)
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
362
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
363
    def test_compare_different_types(self):
364
        k1 = self.module.StaticTuple('foo', 'bar')
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
365
        k2 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
366
                                     k1)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
367
        self.assertCompareNoRelation(k1, k2)
368
        k3 = self.module.StaticTuple('foo')
369
        self.assertCompareDifferent(k3, k1)
370
        k4 = self.module.StaticTuple(None)
371
        self.assertCompareDifferent(k4, k1)
372
        k5 = self.module.StaticTuple(1)
373
        self.assertCompareNoRelation(k1, k5)
374
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
375
    def test_compare_to_tuples(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
376
        k1 = self.module.StaticTuple('foo')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
377
        self.assertCompareEqual(k1, ('foo',))
378
        self.assertCompareEqual(('foo',), k1)
379
        self.assertCompareDifferent(k1, ('foo', 'bar'))
380
        self.assertCompareDifferent(k1, ('foo', 10))
381
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
382
        k2 = self.module.StaticTuple('foo', 'bar')
4679.3.21 by John Arbash Meinel
Implement Key_richcompare directly, rather than thunking to tuples.
383
        self.assertCompareEqual(k2, ('foo', 'bar'))
384
        self.assertCompareEqual(('foo', 'bar'), k2)
385
        self.assertCompareDifferent(k2, ('foo', 'zzz'))
386
        self.assertCompareDifferent(('foo',), k2)
387
        self.assertCompareDifferent(('foo', 'aaa'), k2)
388
        self.assertCompareDifferent(('baz', 'bing'), k2)
389
        self.assertCompareDifferent(('foo', 10), k2)
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
390
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
391
        k3 = self.module.StaticTuple(k1, k2)
392
        self.assertCompareEqual(k3, (('foo',), ('foo', 'bar')))
393
        self.assertCompareEqual((('foo',), ('foo', 'bar')), k3)
394
        self.assertCompareEqual(k3, (k1, ('foo', 'bar')))
395
        self.assertCompareEqual((k1, ('foo', 'bar')), k3)
396
4679.8.11 by John Arbash Meinel
Handle the case where the recursive call ends up returning NotImplemented.
397
    def test_compare_mixed_depths(self):
398
        stuple = self.module.StaticTuple
4679.8.13 by John Arbash Meinel
clean up the test case a little bit.
399
        k1 = stuple(stuple('a',), stuple('b',))
400
        k2 = stuple(stuple(stuple('c',), stuple('d',)),
401
                    stuple('b',))
4679.8.11 by John Arbash Meinel
Handle the case where the recursive call ends up returning NotImplemented.
402
        # This requires comparing a StaticTuple to a 'string', and then
403
        # interpreting that value in the next higher StaticTuple. This used to
404
        # generate a PyErr_BadIternalCall. We now fall back to *something*.
405
        self.assertCompareNoRelation(k1, k2)
406
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
407
    def test_hash(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
408
        k = self.module.StaticTuple('foo')
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
409
        self.assertEqual(hash(k), hash(('foo',)))
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
410
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
4679.3.18 by John Arbash Meinel
Copy the hash and richcompare implementations, and add some tests.
411
        as_tuple = ('foo', 'bar', 'baz', 'bing')
412
        self.assertEqual(hash(k), hash(as_tuple))
413
        x = {k: 'foo'}
414
        # Because k == , it replaces the slot, rather than having both
415
        # present in the dict.
416
        self.assertEqual('foo', x[as_tuple])
417
        x[as_tuple] = 'bar'
418
        self.assertEqual({as_tuple: 'bar'}, x)
419
4679.3.42 by John Arbash Meinel
Implement comparison support when using nested StaticTuple objects.
420
        k2 = self.module.StaticTuple(k)
421
        as_tuple2 = (('foo', 'bar', 'baz', 'bing'),)
422
        self.assertEqual(hash(k2), hash(as_tuple2))
423
4759.2.9 by John Arbash Meinel
Implement support for lots of types.
424
        k3 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
425
                                     k)
426
        as_tuple3 = ('foo', 1, None, u'\xb5', 1.2, 2**65, True, k)
4759.2.8 by John Arbash Meinel
Set up a test suite for hash() and richcompare against lots of acceptable types.
427
        self.assertEqual(hash(as_tuple3), hash(k3))
428
4679.3.19 by John Arbash Meinel
implement slicing as a tuple thunk.
429
    def test_slice(self):
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
430
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
4679.3.19 by John Arbash Meinel
implement slicing as a tuple thunk.
431
        self.assertEqual(('foo', 'bar'), k[:2])
432
        self.assertEqual(('baz',), k[2:-1])
4679.5.5 by John Arbash Meinel
Review feedback from Andrew Bennetts.
433
        try:
434
            val = k[::2]
435
        except TypeError:
436
            # C implementation raises a TypeError, we don't need the
437
            # implementation yet, so allow this to pass
438
            pass
439
        else:
440
            # Python implementation uses a regular Tuple, so make sure it gives
441
            # the right result
442
            self.assertEqual(('foo', 'baz'), val)
4679.3.19 by John Arbash Meinel
implement slicing as a tuple thunk.
443
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
444
    def test_referents(self):
445
        # We implement tp_traverse so that things like 'meliae' can measure the
446
        # amount of referenced memory. Unfortunately gc.get_referents() first
4679.5.5 by John Arbash Meinel
Review feedback from Andrew Bennetts.
447
        # checks the IS_GC flag before it traverses anything. We could write a
448
        # helper func, but that won't work for the generic implementation...
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
449
        self.requireFeature(Meliae)
450
        from meliae import scanner
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
451
        strs = ['foo', 'bar', 'baz', 'bing']
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
452
        k = self.module.StaticTuple(*strs)
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
453
        if self.module is _static_tuple_py:
4679.3.78 by John Arbash Meinel
Change the pure-python version of StaticTuple
454
            refs = strs + [self.module.StaticTuple]
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
455
        else:
4679.3.78 by John Arbash Meinel
Change the pure-python version of StaticTuple
456
            refs = strs
457
        self.assertEqual(sorted(refs), sorted(scanner.get_referents(k)))
4679.3.20 by John Arbash Meinel
Implement tp_traverse, and add a soft dependency on meliae to test it.
458
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
459
    def test_nested_referents(self):
460
        self.requireFeature(Meliae)
4679.3.78 by John Arbash Meinel
Change the pure-python version of StaticTuple
461
        from meliae import scanner
462
        strs = ['foo', 'bar', 'baz', 'bing']
463
        k1 = self.module.StaticTuple(*strs[:2])
464
        k2 = self.module.StaticTuple(*strs[2:])
465
        k3 = self.module.StaticTuple(k1, k2)
466
        refs = [k1, k2]
467
        if self.module is _static_tuple_py:
468
            refs.append(self.module.StaticTuple)
469
        self.assertEqual(sorted(refs),
470
                         sorted(scanner.get_referents(k3)))
4679.3.45 by John Arbash Meinel
Do some work to handle comparison to object that aren't tuples or strings.
471
4679.3.44 by John Arbash Meinel
Special case the empty tuple as a singleton.
472
    def test_empty_is_singleton(self):
473
        key = self.module.StaticTuple()
474
        self.assertIs(key, self.module._empty_tuple)
475
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
476
    def test_intern(self):
477
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
478
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
479
        key = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
480
        self.assertFalse(key in self.module._interned_tuples)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
481
        key2 = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
482
        self.assertEqual(key, key2)
483
        self.assertIsNot(key, key2)
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
484
        key3 = key.intern()
485
        self.assertIs(key, key3)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
486
        self.assertTrue(key in self.module._interned_tuples)
487
        self.assertEqual(key, self.module._interned_tuples[key])
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
488
        key2 = key2.intern()
489
        self.assertIs(key, key2)
4679.3.29 by John Arbash Meinel
Start work on implementing a Key.intern() function.
490
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
491
    def test__c_intern_handles_refcount(self):
4679.3.40 by John Arbash Meinel
Switch away from the name Key instead start branding as StaticTuple.
492
        if self.module is _static_tuple_py:
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
493
            return # Not applicable
494
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
495
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
496
        key = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
497
        self.assertRefcount(1, key)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
498
        self.assertFalse(key in self.module._interned_tuples)
4679.3.35 by John Arbash Meinel
Work on making intern() not generate immortal Key objects.
499
        self.assertFalse(key._is_interned())
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
500
        key2 = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
501
        self.assertRefcount(1, key)
502
        self.assertRefcount(1, key2)
4679.3.33 by John Arbash Meinel
Change Key away from being a PyVarObject.
503
        self.assertEqual(key, key2)
504
        self.assertIsNot(key, key2)
4679.3.30 by John Arbash Meinel
Interning with a regular 'dict' is a tradeoff for bzr.dev of:
505
506
        key3 = key.intern()
507
        self.assertIs(key, key3)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
508
        self.assertTrue(key in self.module._interned_tuples)
509
        self.assertEqual(key, self.module._interned_tuples[key])
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
510
        # key and key3, but we 'hide' the one in _interned_tuples
511
        self.assertRefcount(2, key)
4679.3.30 by John Arbash Meinel
Interning with a regular 'dict' is a tradeoff for bzr.dev of:
512
        del key3
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
513
        self.assertRefcount(1, key)
4679.3.35 by John Arbash Meinel
Work on making intern() not generate immortal Key objects.
514
        self.assertTrue(key._is_interned())
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
515
        self.assertRefcount(1, key2)
516
        key3 = key2.intern()
517
        # key3 now points to key as well, and *not* to key2
518
        self.assertRefcount(2, key)
519
        self.assertRefcount(1, key2)
520
        self.assertIs(key, key3)
521
        self.assertIsNot(key3, key2)
522
        del key2
523
        del key3
524
        self.assertRefcount(1, key)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
525
526
    def test__c_keys_are_not_immortal(self):
4679.3.40 by John Arbash Meinel
Switch away from the name Key instead start branding as StaticTuple.
527
        if self.module is _static_tuple_py:
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
528
            return # Not applicable
529
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
530
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
531
        key = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
532
        self.assertFalse(key in self.module._interned_tuples)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
533
        self.assertRefcount(1, key)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
534
        key = key.intern()
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
535
        self.assertRefcount(1, key)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
536
        self.assertTrue(key in self.module._interned_tuples)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
537
        self.assertTrue(key._is_interned())
538
        del key
539
        # Create a new entry, which would point to the same location
4679.3.41 by John Arbash Meinel
Finish switching the naming to StaticTuple.
540
        key = self.module.StaticTuple(unique_str1, unique_str2)
4679.3.81 by John Arbash Meinel
Fix up _simple_set_pyx.pyx to be compatible with pyrex again.
541
        self.assertRefcount(1, key)
4679.3.51 by John Arbash Meinel
Add a _static_tuple_c.pxd file to define the C api to pyrex code.
542
        # This old entry in _interned_tuples should be gone
543
        self.assertFalse(key in self.module._interned_tuples)
4679.3.38 by John Arbash Meinel
add a test that Key.intern() doesn't create an immortal object.
544
        self.assertFalse(key._is_interned())
4679.3.47 by John Arbash Meinel
Work out how to expose the C api using the Python PyCObject interface.
545
546
    def test__c_has_C_API(self):
547
        if self.module is _static_tuple_py:
548
            return
549
        self.assertIsNot(None, self.module._C_API)
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
550
4739.4.1 by John Arbash Meinel
Implement StaticTuple.from_sequence()
551
    def test_from_sequence_tuple(self):
552
        st = self.module.StaticTuple.from_sequence(('foo', 'bar'))
553
        self.assertIsInstance(st, self.module.StaticTuple)
554
        self.assertEqual(('foo', 'bar'), st)
555
556
    def test_from_sequence_str(self):
557
        st = self.module.StaticTuple.from_sequence('foo')
558
        self.assertIsInstance(st, self.module.StaticTuple)
559
        self.assertEqual(('f', 'o', 'o'), st)
560
561
    def test_from_sequence_list(self):
562
        st = self.module.StaticTuple.from_sequence(['foo', 'bar'])
563
        self.assertIsInstance(st, self.module.StaticTuple)
564
        self.assertEqual(('foo', 'bar'), st)
565
566
    def test_from_sequence_static_tuple(self):
567
        st = self.module.StaticTuple('foo', 'bar')
568
        st2 = self.module.StaticTuple.from_sequence(st)
569
        # If the source is a StaticTuple already, we return the exact object
570
        self.assertIs(st, st2)
571
572
    def test_from_sequence_not_sequence(self):
573
        self.assertRaises(TypeError,
574
                          self.module.StaticTuple.from_sequence, object())
4771.2.2 by John Arbash Meinel
Clean up the C code a bit, using a goto.
575
        self.assertRaises(TypeError,
576
                          self.module.StaticTuple.from_sequence, 10)
4739.4.1 by John Arbash Meinel
Implement StaticTuple.from_sequence()
577
578
    def test_from_sequence_incorrect_args(self):
579
        self.assertRaises(TypeError,
580
                          self.module.StaticTuple.from_sequence, object(), 'a')
581
        self.assertRaises(TypeError,
582
                          self.module.StaticTuple.from_sequence, foo='a')
4739.4.2 by John Arbash Meinel
Merge bzr.dev resolve test conflict.
583
4771.2.1 by Matt Nordhoff
_static_tuple_c.StaticTuple.from_sequence() now supports arbitrary iterables (by converting them to tuples first).
584
    def test_from_sequence_iterable(self):
4771.2.2 by John Arbash Meinel
Clean up the C code a bit, using a goto.
585
        st = self.module.StaticTuple.from_sequence(iter(['foo', 'bar']))
586
        self.assertIsInstance(st, self.module.StaticTuple)
587
        self.assertEqual(('foo', 'bar'), st)
588
589
    def test_from_sequence_generator(self):
590
        def generate_tuple():
591
            yield 'foo'
592
            yield 'bar'
593
        st = self.module.StaticTuple.from_sequence(generate_tuple())
4771.2.1 by Matt Nordhoff
_static_tuple_c.StaticTuple.from_sequence() now supports arbitrary iterables (by converting them to tuples first).
594
        self.assertIsInstance(st, self.module.StaticTuple)
595
        self.assertEqual(('foo', 'bar'), st)
596
4759.2.16 by Matt Nordhoff
Add a test
597
    def test_pickle(self):
598
        st = self.module.StaticTuple('foo', 'bar')
599
        pickled = cPickle.dumps(st)
600
        unpickled = cPickle.loads(pickled)
601
        self.assertEqual(unpickled, st)
4759.2.20 by Matt Nordhoff
Review: Add a Py_INCREF, and test pickling a nested StaticTuple.
602
603
    def test_pickle_empty(self):
4759.2.17 by Matt Nordhoff
Test pickling the empty StaticTuple too
604
        st = self.module.StaticTuple()
605
        pickled = cPickle.dumps(st)
606
        unpickled = cPickle.loads(pickled)
607
        self.assertIs(st, unpickled)
4759.2.16 by Matt Nordhoff
Add a test
608
4759.2.20 by Matt Nordhoff
Review: Add a Py_INCREF, and test pickling a nested StaticTuple.
609
    def test_pickle_nested(self):
610
        st = self.module.StaticTuple('foo', self.module.StaticTuple('bar'))
611
        pickled = cPickle.dumps(st)
612
        unpickled = cPickle.loads(pickled)
613
        self.assertEqual(unpickled, st)
614
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
615
    def test_static_tuple_thunk(self):
616
        # Make sure the right implementation is available from
617
        # bzrlib.static_tuple.StaticTuple.
618
        if self.module is _static_tuple_py:
4913.2.20 by John Arbash Meinel
Change all of the compiled_foo to compiled_foo_feature
619
            if compiled_static_tuple_feature.available():
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
620
                # We will be using the C version
621
                return
4739.4.2 by John Arbash Meinel
Merge bzr.dev resolve test conflict.
622
        self.assertIs(static_tuple.StaticTuple,
4679.8.3 by John Arbash Meinel
Expose bzrlib.static_tuple.StaticTuple as a thunk
623
                      self.module.StaticTuple)
4668.3.1 by John Arbash Meinel
Fix bug #471193, allow tuples into the CHK code.
624
625
626
class TestEnsureStaticTuple(tests.TestCase):
627
628
    def test_is_static_tuple(self):
629
        st = static_tuple.StaticTuple('foo')
630
        st2 = static_tuple.expect_static_tuple(st)
631
        self.assertIs(st, st2)
632
633
    def test_is_tuple(self):
634
        t = ('foo',)
635
        st = static_tuple.expect_static_tuple(t)
636
        self.assertIsInstance(st, static_tuple.StaticTuple)
637
        self.assertEqual(t, st)
638
639
    def test_flagged_is_static_tuple(self):
640
        debug.debug_flags.add('static_tuple')
641
        st = static_tuple.StaticTuple('foo')
642
        st2 = static_tuple.expect_static_tuple(st)
643
        self.assertIs(st, st2)
644
645
    def test_flagged_is_tuple(self):
646
        debug.debug_flags.add('static_tuple')
647
        t = ('foo',)
648
        self.assertRaises(TypeError, static_tuple.expect_static_tuple, t)