1"""
2Common tests shared by test_str, test_unicode, test_userstring and test_string.
3"""
4
5import unittest, string, sys, struct
6from test import test_support
7from UserList import UserList
8
9class Sequence:
10    def __init__(self, seq='wxyz'): self.seq = seq
11    def __len__(self): return len(self.seq)
12    def __getitem__(self, i): return self.seq[i]
13
14class BadSeq1(Sequence):
15    def __init__(self): self.seq = [7, 'hello', 123L]
16
17class BadSeq2(Sequence):
18    def __init__(self): self.seq = ['a', 'b', 'c']
19    def __len__(self): return 8
20
21class CommonTest(unittest.TestCase):
22    # This testcase contains test that can be used in all
23    # stringlike classes. Currently this is str, unicode
24    # UserString and the string module.
25
26    # The type to be tested
27    # Change in subclasses to change the behaviour of fixtesttype()
28    type2test = None
29
30    # All tests pass their arguments to the testing methods
31    # as str objects. fixtesttype() can be used to propagate
32    # these arguments to the appropriate type
33    def fixtype(self, obj):
34        if isinstance(obj, str):
35            return self.__class__.type2test(obj)
36        elif isinstance(obj, list):
37            return [self.fixtype(x) for x in obj]
38        elif isinstance(obj, tuple):
39            return tuple([self.fixtype(x) for x in obj])
40        elif isinstance(obj, dict):
41            return dict([
42               (self.fixtype(key), self.fixtype(value))
43               for (key, value) in obj.iteritems()
44            ])
45        else:
46            return obj
47
48    def test_fixtype(self):
49        self.assertIs(type(self.fixtype("123")), self.type2test)
50
51    # check that object.method(*args) returns result
52    def checkequal(self, result, object, methodname, *args):
53        result = self.fixtype(result)
54        object = self.fixtype(object)
55        args = self.fixtype(args)
56        realresult = getattr(object, methodname)(*args)
57        self.assertEqual(
58            result,
59            realresult
60        )
61        # if the original is returned make sure that
62        # this doesn't happen with subclasses
63        if object == realresult:
64            class subtype(self.__class__.type2test):
65                pass
66            object = subtype(object)
67            realresult = getattr(object, methodname)(*args)
68            self.assertTrue(object is not realresult)
69
70    # check that object.method(*args) raises exc
71    def checkraises(self, exc, obj, methodname, *args):
72        obj = self.fixtype(obj)
73        args = self.fixtype(args)
74        with self.assertRaises(exc) as cm:
75            getattr(obj, methodname)(*args)
76        self.assertNotEqual(cm.exception.args[0], '')
77
78    # call object.method(*args) without any checks
79    def checkcall(self, object, methodname, *args):
80        object = self.fixtype(object)
81        args = self.fixtype(args)
82        getattr(object, methodname)(*args)
83
84    def test_hash(self):
85        # SF bug 1054139:  += optimization was not invalidating cached hash value
86        a = self.type2test('DNSSEC')
87        b = self.type2test('')
88        for c in a:
89            b += c
90            hash(b)
91        self.assertEqual(hash(a), hash(b))
92
93    def test_capitalize(self):
94        self.checkequal(' hello ', ' hello ', 'capitalize')
95        self.checkequal('Hello ', 'Hello ','capitalize')
96        self.checkequal('Hello ', 'hello ','capitalize')
97        self.checkequal('Aaaa', 'aaaa', 'capitalize')
98        self.checkequal('Aaaa', 'AaAa', 'capitalize')
99
100        self.checkraises(TypeError, 'hello', 'capitalize', 42)
101
102    def test_count(self):
103        self.checkequal(3, 'aaa', 'count', 'a')
104        self.checkequal(0, 'aaa', 'count', 'b')
105        self.checkequal(3, 'aaa', 'count', 'a')
106        self.checkequal(0, 'aaa', 'count', 'b')
107        self.checkequal(3, 'aaa', 'count', 'a')
108        self.checkequal(0, 'aaa', 'count', 'b')
109        self.checkequal(0, 'aaa', 'count', 'b')
110        self.checkequal(2, 'aaa', 'count', 'a', 1)
111        self.checkequal(0, 'aaa', 'count', 'a', 10)
112        self.checkequal(1, 'aaa', 'count', 'a', -1)
113        self.checkequal(3, 'aaa', 'count', 'a', -10)
114        self.checkequal(1, 'aaa', 'count', 'a', 0, 1)
115        self.checkequal(3, 'aaa', 'count', 'a', 0, 10)
116        self.checkequal(2, 'aaa', 'count', 'a', 0, -1)
117        self.checkequal(0, 'aaa', 'count', 'a', 0, -10)
118        self.checkequal(3, 'aaa', 'count', '', 1)
119        self.checkequal(1, 'aaa', 'count', '', 3)
120        self.checkequal(0, 'aaa', 'count', '', 10)
121        self.checkequal(2, 'aaa', 'count', '', -1)
122        self.checkequal(4, 'aaa', 'count', '', -10)
123
124        self.checkequal(1, '', 'count', '')
125        self.checkequal(0, '', 'count', '', 1, 1)
126        self.checkequal(0, '', 'count', '', sys.maxint, 0)
127
128        self.checkequal(0, '', 'count', 'xx')
129        self.checkequal(0, '', 'count', 'xx', 1, 1)
130        self.checkequal(0, '', 'count', 'xx', sys.maxint, 0)
131
132        self.checkraises(TypeError, 'hello', 'count')
133        self.checkraises(TypeError, 'hello', 'count', 42)
134
135        # For a variety of combinations,
136        #    verify that str.count() matches an equivalent function
137        #    replacing all occurrences and then differencing the string lengths
138        charset = ['', 'a', 'b']
139        digits = 7
140        base = len(charset)
141        teststrings = set()
142        for i in xrange(base ** digits):
143            entry = []
144            for j in xrange(digits):
145                i, m = divmod(i, base)
146                entry.append(charset[m])
147            teststrings.add(''.join(entry))
148        teststrings = list(teststrings)
149        for i in teststrings:
150            i = self.fixtype(i)
151            n = len(i)
152            for j in teststrings:
153                r1 = i.count(j)
154                if j:
155                    r2, rem = divmod(n - len(i.replace(j, '')), len(j))
156                else:
157                    r2, rem = len(i)+1, 0
158                if rem or r1 != r2:
159                    self.assertEqual(rem, 0, '%s != 0 for %s' % (rem, i))
160                    self.assertEqual(r1, r2, '%s != %s for %s' % (r1, r2, i))
161
162    def test_find(self):
163        self.checkequal(0, 'abcdefghiabc', 'find', 'abc')
164        self.checkequal(9, 'abcdefghiabc', 'find', 'abc', 1)
165        self.checkequal(-1, 'abcdefghiabc', 'find', 'def', 4)
166
167        self.checkequal(0, 'abc', 'find', '', 0)
168        self.checkequal(3, 'abc', 'find', '', 3)
169        self.checkequal(-1, 'abc', 'find', '', 4)
170
171        # to check the ability to pass None as defaults
172        self.checkequal( 2, 'rrarrrrrrrrra', 'find', 'a')
173        self.checkequal(12, 'rrarrrrrrrrra', 'find', 'a', 4)
174        self.checkequal(-1, 'rrarrrrrrrrra', 'find', 'a', 4, 6)
175        self.checkequal(12, 'rrarrrrrrrrra', 'find', 'a', 4, None)
176        self.checkequal( 2, 'rrarrrrrrrrra', 'find', 'a', None, 6)
177
178        self.checkraises(TypeError, 'hello', 'find')
179        self.checkraises(TypeError, 'hello', 'find', 42)
180
181        self.checkequal(0, '', 'find', '')
182        self.checkequal(-1, '', 'find', '', 1, 1)
183        self.checkequal(-1, '', 'find', '', sys.maxint, 0)
184
185        self.checkequal(-1, '', 'find', 'xx')
186        self.checkequal(-1, '', 'find', 'xx', 1, 1)
187        self.checkequal(-1, '', 'find', 'xx', sys.maxint, 0)
188
189        # issue 7458
190        self.checkequal(-1, 'ab', 'find', 'xxx', sys.maxsize + 1, 0)
191
192        # For a variety of combinations,
193        #    verify that str.find() matches __contains__
194        #    and that the found substring is really at that location
195        charset = ['', 'a', 'b', 'c']
196        digits = 5
197        base = len(charset)
198        teststrings = set()
199        for i in xrange(base ** digits):
200            entry = []
201            for j in xrange(digits):
202                i, m = divmod(i, base)
203                entry.append(charset[m])
204            teststrings.add(''.join(entry))
205        teststrings = list(teststrings)
206        for i in teststrings:
207            i = self.fixtype(i)
208            for j in teststrings:
209                loc = i.find(j)
210                r1 = (loc != -1)
211                r2 = j in i
212                self.assertEqual(r1, r2)
213                if loc != -1:
214                    self.assertEqual(i[loc:loc+len(j)], j)
215
216    def test_rfind(self):
217        self.checkequal(9,  'abcdefghiabc', 'rfind', 'abc')
218        self.checkequal(12, 'abcdefghiabc', 'rfind', '')
219        self.checkequal(0, 'abcdefghiabc', 'rfind', 'abcd')
220        self.checkequal(-1, 'abcdefghiabc', 'rfind', 'abcz')
221
222        self.checkequal(3, 'abc', 'rfind', '', 0)
223        self.checkequal(3, 'abc', 'rfind', '', 3)
224        self.checkequal(-1, 'abc', 'rfind', '', 4)
225
226        # to check the ability to pass None as defaults
227        self.checkequal(12, 'rrarrrrrrrrra', 'rfind', 'a')
228        self.checkequal(12, 'rrarrrrrrrrra', 'rfind', 'a', 4)
229        self.checkequal(-1, 'rrarrrrrrrrra', 'rfind', 'a', 4, 6)
230        self.checkequal(12, 'rrarrrrrrrrra', 'rfind', 'a', 4, None)
231        self.checkequal( 2, 'rrarrrrrrrrra', 'rfind', 'a', None, 6)
232
233        self.checkraises(TypeError, 'hello', 'rfind')
234        self.checkraises(TypeError, 'hello', 'rfind', 42)
235
236        # For a variety of combinations,
237        #    verify that str.rfind() matches __contains__
238        #    and that the found substring is really at that location
239        charset = ['', 'a', 'b', 'c']
240        digits = 5
241        base = len(charset)
242        teststrings = set()
243        for i in xrange(base ** digits):
244            entry = []
245            for j in xrange(digits):
246                i, m = divmod(i, base)
247                entry.append(charset[m])
248            teststrings.add(''.join(entry))
249        teststrings = list(teststrings)
250        for i in teststrings:
251            i = self.fixtype(i)
252            for j in teststrings:
253                loc = i.rfind(j)
254                r1 = (loc != -1)
255                r2 = j in i
256                self.assertEqual(r1, r2)
257                if loc != -1:
258                    self.assertEqual(i[loc:loc+len(j)], self.fixtype(j))
259
260        # issue 7458
261        self.checkequal(-1, 'ab', 'rfind', 'xxx', sys.maxsize + 1, 0)
262
263    def test_index(self):
264        self.checkequal(0, 'abcdefghiabc', 'index', '')
265        self.checkequal(3, 'abcdefghiabc', 'index', 'def')
266        self.checkequal(0, 'abcdefghiabc', 'index', 'abc')
267        self.checkequal(9, 'abcdefghiabc', 'index', 'abc', 1)
268
269        self.checkraises(ValueError, 'abcdefghiabc', 'index', 'hib')
270        self.checkraises(ValueError, 'abcdefghiab', 'index', 'abc', 1)
271        self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', 8)
272        self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', -1)
273
274        # to check the ability to pass None as defaults
275        self.checkequal( 2, 'rrarrrrrrrrra', 'index', 'a')
276        self.checkequal(12, 'rrarrrrrrrrra', 'index', 'a', 4)
277        self.checkraises(ValueError, 'rrarrrrrrrrra', 'index', 'a', 4, 6)
278        self.checkequal(12, 'rrarrrrrrrrra', 'index', 'a', 4, None)
279        self.checkequal( 2, 'rrarrrrrrrrra', 'index', 'a', None, 6)
280
281        self.checkraises(TypeError, 'hello', 'index')
282        self.checkraises(TypeError, 'hello', 'index', 42)
283
284    def test_rindex(self):
285        self.checkequal(12, 'abcdefghiabc', 'rindex', '')
286        self.checkequal(3,  'abcdefghiabc', 'rindex', 'def')
287        self.checkequal(9,  'abcdefghiabc', 'rindex', 'abc')
288        self.checkequal(0,  'abcdefghiabc', 'rindex', 'abc', 0, -1)
289
290        self.checkraises(ValueError, 'abcdefghiabc', 'rindex', 'hib')
291        self.checkraises(ValueError, 'defghiabc', 'rindex', 'def', 1)
292        self.checkraises(ValueError, 'defghiabc', 'rindex', 'abc', 0, -1)
293        self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, 8)
294        self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, -1)
295
296        # to check the ability to pass None as defaults
297        self.checkequal(12, 'rrarrrrrrrrra', 'rindex', 'a')
298        self.checkequal(12, 'rrarrrrrrrrra', 'rindex', 'a', 4)
299        self.checkraises(ValueError, 'rrarrrrrrrrra', 'rindex', 'a', 4, 6)
300        self.checkequal(12, 'rrarrrrrrrrra', 'rindex', 'a', 4, None)
301        self.checkequal( 2, 'rrarrrrrrrrra', 'rindex', 'a', None, 6)
302
303        self.checkraises(TypeError, 'hello', 'rindex')
304        self.checkraises(TypeError, 'hello', 'rindex', 42)
305
306    def test_lower(self):
307        self.checkequal('hello', 'HeLLo', 'lower')
308        self.checkequal('hello', 'hello', 'lower')
309        self.checkraises(TypeError, 'hello', 'lower', 42)
310
311    def test_upper(self):
312        self.checkequal('HELLO', 'HeLLo', 'upper')
313        self.checkequal('HELLO', 'HELLO', 'upper')
314        self.checkraises(TypeError, 'hello', 'upper', 42)
315
316    def test_expandtabs(self):
317        self.checkequal('abc\rab      def\ng       hi', 'abc\rab\tdef\ng\thi', 'expandtabs')
318        self.checkequal('abc\rab      def\ng       hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 8)
319        self.checkequal('abc\rab  def\ng   hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 4)
320        self.checkequal('abc\r\nab  def\ng   hi', 'abc\r\nab\tdef\ng\thi', 'expandtabs', 4)
321        self.checkequal('abc\rab      def\ng       hi', 'abc\rab\tdef\ng\thi', 'expandtabs')
322        self.checkequal('abc\rab      def\ng       hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 8)
323        self.checkequal('abc\r\nab\r\ndef\ng\r\nhi', 'abc\r\nab\r\ndef\ng\r\nhi', 'expandtabs', 4)
324        self.checkequal('  a\n b', ' \ta\n\tb', 'expandtabs', 1)
325
326        self.checkraises(TypeError, 'hello', 'expandtabs', 42, 42)
327        # This test is only valid when sizeof(int) == sizeof(void*) == 4.
328        if sys.maxint < (1 << 32) and struct.calcsize('P') == 4:
329            self.checkraises(OverflowError,
330                             '\ta\n\tb', 'expandtabs', sys.maxint)
331
332    def test_split(self):
333        self.checkequal(['this', 'is', 'the', 'split', 'function'],
334            'this is the split function', 'split')
335
336        # by whitespace
337        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d ', 'split')
338        self.checkequal(['a', 'b c d'], 'a b c d', 'split', None, 1)
339        self.checkequal(['a', 'b', 'c d'], 'a b c d', 'split', None, 2)
340        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'split', None, 3)
341        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'split', None, 4)
342        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'split', None,
343                        sys.maxint-1)
344        self.checkequal(['a b c d'], 'a b c d', 'split', None, 0)
345        self.checkequal(['a b c d'], '  a b c d', 'split', None, 0)
346        self.checkequal(['a', 'b', 'c  d'], 'a  b  c  d', 'split', None, 2)
347
348        self.checkequal([], '         ', 'split')
349        self.checkequal(['a'], '  a    ', 'split')
350        self.checkequal(['a', 'b'], '  a    b   ', 'split')
351        self.checkequal(['a', 'b   '], '  a    b   ', 'split', None, 1)
352        self.checkequal(['a    b   c   '], '  a    b   c   ', 'split', None, 0)
353        self.checkequal(['a', 'b   c   '], '  a    b   c   ', 'split', None, 1)
354        self.checkequal(['a', 'b', 'c   '], '  a    b   c   ', 'split', None, 2)
355        self.checkequal(['a', 'b', 'c'], '  a    b   c   ', 'split', None, 3)
356        self.checkequal(['a', 'b'], '\n\ta \t\r b \v ', 'split')
357        aaa = ' a '*20
358        self.checkequal(['a']*20, aaa, 'split')
359        self.checkequal(['a'] + [aaa[4:]], aaa, 'split', None, 1)
360        self.checkequal(['a']*19 + ['a '], aaa, 'split', None, 19)
361
362        for b in ('arf\tbarf', 'arf\nbarf', 'arf\rbarf',
363                  'arf\fbarf', 'arf\vbarf'):
364            self.checkequal(['arf', 'barf'], b, 'split')
365            self.checkequal(['arf', 'barf'], b, 'split', None)
366            self.checkequal(['arf', 'barf'], b, 'split', None, 2)
367
368        # by a char
369        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|')
370        self.checkequal(['a|b|c|d'], 'a|b|c|d', 'split', '|', 0)
371        self.checkequal(['a', 'b|c|d'], 'a|b|c|d', 'split', '|', 1)
372        self.checkequal(['a', 'b', 'c|d'], 'a|b|c|d', 'split', '|', 2)
373        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|', 3)
374        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|', 4)
375        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|',
376                        sys.maxint-2)
377        self.checkequal(['a|b|c|d'], 'a|b|c|d', 'split', '|', 0)
378        self.checkequal(['a', '', 'b||c||d'], 'a||b||c||d', 'split', '|', 2)
379        self.checkequal(['abcd'], 'abcd', 'split', '|')
380        self.checkequal([''], '', 'split', '|')
381        self.checkequal(['endcase ', ''], 'endcase |', 'split', '|')
382        self.checkequal(['', ' startcase'], '| startcase', 'split', '|')
383        self.checkequal(['', 'bothcase', ''], '|bothcase|', 'split', '|')
384        self.checkequal(['a', '', 'b\x00c\x00d'], 'a\x00\x00b\x00c\x00d', 'split', '\x00', 2)
385
386        self.checkequal(['a']*20, ('a|'*20)[:-1], 'split', '|')
387        self.checkequal(['a']*15 +['a|a|a|a|a'],
388                                   ('a|'*20)[:-1], 'split', '|', 15)
389
390        # by string
391        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//')
392        self.checkequal(['a', 'b//c//d'], 'a//b//c//d', 'split', '//', 1)
393        self.checkequal(['a', 'b', 'c//d'], 'a//b//c//d', 'split', '//', 2)
394        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//', 3)
395        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//', 4)
396        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//',
397                        sys.maxint-10)
398        self.checkequal(['a//b//c//d'], 'a//b//c//d', 'split', '//', 0)
399        self.checkequal(['a', '', 'b////c////d'], 'a////b////c////d', 'split', '//', 2)
400        self.checkequal(['endcase ', ''], 'endcase test', 'split', 'test')
401        self.checkequal(['', ' begincase'], 'test begincase', 'split', 'test')
402        self.checkequal(['', ' bothcase ', ''], 'test bothcase test',
403                        'split', 'test')
404        self.checkequal(['a', 'bc'], 'abbbc', 'split', 'bb')
405        self.checkequal(['', ''], 'aaa', 'split', 'aaa')
406        self.checkequal(['aaa'], 'aaa', 'split', 'aaa', 0)
407        self.checkequal(['ab', 'ab'], 'abbaab', 'split', 'ba')
408        self.checkequal(['aaaa'], 'aaaa', 'split', 'aab')
409        self.checkequal([''], '', 'split', 'aaa')
410        self.checkequal(['aa'], 'aa', 'split', 'aaa')
411        self.checkequal(['A', 'bobb'], 'Abbobbbobb', 'split', 'bbobb')
412        self.checkequal(['A', 'B', ''], 'AbbobbBbbobb', 'split', 'bbobb')
413
414        self.checkequal(['a']*20, ('aBLAH'*20)[:-4], 'split', 'BLAH')
415        self.checkequal(['a']*20, ('aBLAH'*20)[:-4], 'split', 'BLAH', 19)
416        self.checkequal(['a']*18 + ['aBLAHa'], ('aBLAH'*20)[:-4],
417                        'split', 'BLAH', 18)
418
419        # mixed use of str and unicode
420        if self.type2test is not bytearray:
421            result = [u'a', u'b', u'c d']
422            self.checkequal(result, 'a b c d', 'split', u' ', 2)
423
424        # argument type
425        self.checkraises(TypeError, 'hello', 'split', 42, 42, 42)
426
427        # null case
428        self.checkraises(ValueError, 'hello', 'split', '')
429        self.checkraises(ValueError, 'hello', 'split', '', 0)
430
431    def test_rsplit(self):
432        self.checkequal(['this', 'is', 'the', 'rsplit', 'function'],
433                         'this is the rsplit function', 'rsplit')
434
435        # by whitespace
436        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d ', 'rsplit')
437        self.checkequal(['a b c', 'd'], 'a b c d', 'rsplit', None, 1)
438        self.checkequal(['a b', 'c', 'd'], 'a b c d', 'rsplit', None, 2)
439        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None, 3)
440        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None, 4)
441        self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None,
442                        sys.maxint-20)
443        self.checkequal(['a b c d'], 'a b c d', 'rsplit', None, 0)
444        self.checkequal(['a b c d'], 'a b c d  ', 'rsplit', None, 0)
445        self.checkequal(['a  b', 'c', 'd'], 'a  b  c  d', 'rsplit', None, 2)
446
447        self.checkequal([], '         ', 'rsplit')
448        self.checkequal(['a'], '  a    ', 'rsplit')
449        self.checkequal(['a', 'b'], '  a    b   ', 'rsplit')
450        self.checkequal(['  a', 'b'], '  a    b   ', 'rsplit', None, 1)
451        self.checkequal(['  a    b   c'], '  a    b   c   ', 'rsplit',
452                        None, 0)
453        self.checkequal(['  a    b','c'], '  a    b   c   ', 'rsplit',
454                        None, 1)
455        self.checkequal(['  a', 'b', 'c'], '  a    b   c   ', 'rsplit',
456                        None, 2)
457        self.checkequal(['a', 'b', 'c'], '  a    b   c   ', 'rsplit',
458                        None, 3)
459        self.checkequal(['a', 'b'], '\n\ta \t\r b \v ', 'rsplit', None, 88)
460        aaa = ' a '*20
461        self.checkequal(['a']*20, aaa, 'rsplit')
462        self.checkequal([aaa[:-4]] + ['a'], aaa, 'rsplit', None, 1)
463        self.checkequal([' a  a'] + ['a']*18, aaa, 'rsplit', None, 18)
464
465        for b in ('arf\tbarf', 'arf\nbarf', 'arf\rbarf',
466                  'arf\fbarf', 'arf\vbarf'):
467            self.checkequal(['arf', 'barf'], b, 'rsplit')
468            self.checkequal(['arf', 'barf'], b, 'rsplit', None)
469            self.checkequal(['arf', 'barf'], b, 'rsplit', None, 2)
470
471        # by a char
472        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|')
473        self.checkequal(['a|b|c', 'd'], 'a|b|c|d', 'rsplit', '|', 1)
474        self.checkequal(['a|b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|', 2)
475        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|', 3)
476        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|', 4)
477        self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|',
478                        sys.maxint-100)
479        self.checkequal(['a|b|c|d'], 'a|b|c|d', 'rsplit', '|', 0)
480        self.checkequal(['a||b||c', '', 'd'], 'a||b||c||d', 'rsplit', '|', 2)
481        self.checkequal(['abcd'], 'abcd', 'rsplit', '|')
482        self.checkequal([''], '', 'rsplit', '|')
483        self.checkequal(['', ' begincase'], '| begincase', 'rsplit', '|')
484        self.checkequal(['endcase ', ''], 'endcase |', 'rsplit', '|')
485        self.checkequal(['', 'bothcase', ''], '|bothcase|', 'rsplit', '|')
486
487        self.checkequal(['a\x00\x00b', 'c', 'd'], 'a\x00\x00b\x00c\x00d', 'rsplit', '\x00', 2)
488
489        self.checkequal(['a']*20, ('a|'*20)[:-1], 'rsplit', '|')
490        self.checkequal(['a|a|a|a|a']+['a']*15,
491                        ('a|'*20)[:-1], 'rsplit', '|', 15)
492
493        # by string
494        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//')
495        self.checkequal(['a//b//c', 'd'], 'a//b//c//d', 'rsplit', '//', 1)
496        self.checkequal(['a//b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//', 2)
497        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//', 3)
498        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//', 4)
499        self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//',
500                        sys.maxint-5)
501        self.checkequal(['a//b//c//d'], 'a//b//c//d', 'rsplit', '//', 0)
502        self.checkequal(['a////b////c', '', 'd'], 'a////b////c////d', 'rsplit', '//', 2)
503        self.checkequal(['', ' begincase'], 'test begincase', 'rsplit', 'test')
504        self.checkequal(['endcase ', ''], 'endcase test', 'rsplit', 'test')
505        self.checkequal(['', ' bothcase ', ''], 'test bothcase test',
506                        'rsplit', 'test')
507        self.checkequal(['ab', 'c'], 'abbbc', 'rsplit', 'bb')
508        self.checkequal(['', ''], 'aaa', 'rsplit', 'aaa')
509        self.checkequal(['aaa'], 'aaa', 'rsplit', 'aaa', 0)
510        self.checkequal(['ab', 'ab'], 'abbaab', 'rsplit', 'ba')
511        self.checkequal(['aaaa'], 'aaaa', 'rsplit', 'aab')
512        self.checkequal([''], '', 'rsplit', 'aaa')
513        self.checkequal(['aa'], 'aa', 'rsplit', 'aaa')
514        self.checkequal(['bbob', 'A'], 'bbobbbobbA', 'rsplit', 'bbobb')
515        self.checkequal(['', 'B', 'A'], 'bbobbBbbobbA', 'rsplit', 'bbobb')
516
517        self.checkequal(['a']*20, ('aBLAH'*20)[:-4], 'rsplit', 'BLAH')
518        self.checkequal(['a']*20, ('aBLAH'*20)[:-4], 'rsplit', 'BLAH', 19)
519        self.checkequal(['aBLAHa'] + ['a']*18, ('aBLAH'*20)[:-4],
520                        'rsplit', 'BLAH', 18)
521
522        # mixed use of str and unicode
523        if self.type2test is not bytearray:
524            result = [u'a b', u'c', u'd']
525            self.checkequal(result, 'a b c d', 'rsplit', u' ', 2)
526
527        # argument type
528        self.checkraises(TypeError, 'hello', 'rsplit', 42, 42, 42)
529
530        # null case
531        self.checkraises(ValueError, 'hello', 'rsplit', '')
532        self.checkraises(ValueError, 'hello', 'rsplit', '', 0)
533
534    def test_strip_whitespace(self):
535        self.checkequal('hello', '   hello   ', 'strip')
536        self.checkequal('hello   ', '   hello   ', 'lstrip')
537        self.checkequal('   hello', '   hello   ', 'rstrip')
538        self.checkequal('hello', 'hello', 'strip')
539
540        b = ' \t\n\r\f\vabc \t\n\r\f\v'
541        self.checkequal('abc', b, 'strip')
542        self.checkequal('abc \t\n\r\f\v', b, 'lstrip')
543        self.checkequal(' \t\n\r\f\vabc', b, 'rstrip')
544
545        # strip/lstrip/rstrip with None arg
546        self.checkequal('hello', '   hello   ', 'strip', None)
547        self.checkequal('hello   ', '   hello   ', 'lstrip', None)
548        self.checkequal('   hello', '   hello   ', 'rstrip', None)
549        self.checkequal('hello', 'hello', 'strip', None)
550
551    def test_strip(self):
552        # strip/lstrip/rstrip with str arg
553        self.checkequal('hello', 'xyzzyhelloxyzzy', 'strip', 'xyz')
554        self.checkequal('helloxyzzy', 'xyzzyhelloxyzzy', 'lstrip', 'xyz')
555        self.checkequal('xyzzyhello', 'xyzzyhelloxyzzy', 'rstrip', 'xyz')
556        self.checkequal('hello', 'hello', 'strip', 'xyz')
557        self.checkequal('', 'mississippi', 'strip', 'mississippi')
558
559        # only trims the start and end, does not strip internal characters
560        self.checkequal('mississipp', 'mississippi', 'strip', 'i')
561
562        # strip/lstrip/rstrip with unicode arg
563        if self.type2test is not bytearray and test_support.have_unicode:
564            self.checkequal(unicode('hello', 'ascii'), 'xyzzyhelloxyzzy',
565                 'strip', unicode('xyz', 'ascii'))
566            self.checkequal(unicode('helloxyzzy', 'ascii'), 'xyzzyhelloxyzzy',
567                 'lstrip', unicode('xyz', 'ascii'))
568            self.checkequal(unicode('xyzzyhello', 'ascii'), 'xyzzyhelloxyzzy',
569                 'rstrip', unicode('xyz', 'ascii'))
570            # XXX
571            #self.checkequal(unicode('hello', 'ascii'), 'hello',
572            #     'strip', unicode('xyz', 'ascii'))
573
574        self.checkraises(TypeError, 'hello', 'strip', 42, 42)
575        self.checkraises(TypeError, 'hello', 'lstrip', 42, 42)
576        self.checkraises(TypeError, 'hello', 'rstrip', 42, 42)
577
578    def test_ljust(self):
579        self.checkequal('abc       ', 'abc', 'ljust', 10)
580        self.checkequal('abc   ', 'abc', 'ljust', 6)
581        self.checkequal('abc', 'abc', 'ljust', 3)
582        self.checkequal('abc', 'abc', 'ljust', 2)
583        if self.type2test is bytearray:
584            # Special case because bytearray argument is not accepted
585            self.assertEqual(b'abc*******', bytearray(b'abc').ljust(10, '*'))
586        else:
587            self.checkequal('abc*******', 'abc', 'ljust', 10, '*')
588        self.checkraises(TypeError, 'abc', 'ljust')
589
590    def test_rjust(self):
591        self.checkequal('       abc', 'abc', 'rjust', 10)
592        self.checkequal('   abc', 'abc', 'rjust', 6)
593        self.checkequal('abc', 'abc', 'rjust', 3)
594        self.checkequal('abc', 'abc', 'rjust', 2)
595        if self.type2test is bytearray:
596            # Special case because bytearray argument is not accepted
597            self.assertEqual(b'*******abc', bytearray(b'abc').rjust(10, '*'))
598        else:
599            self.checkequal('*******abc', 'abc', 'rjust', 10, '*')
600        self.checkraises(TypeError, 'abc', 'rjust')
601
602    def test_center(self):
603        self.checkequal('   abc    ', 'abc', 'center', 10)
604        self.checkequal(' abc  ', 'abc', 'center', 6)
605        self.checkequal('abc', 'abc', 'center', 3)
606        self.checkequal('abc', 'abc', 'center', 2)
607        if self.type2test is bytearray:
608            # Special case because bytearray argument is not accepted
609            result = bytearray(b'abc').center(10, '*')
610            self.assertEqual(b'***abc****', result)
611        else:
612            self.checkequal('***abc****', 'abc', 'center', 10, '*')
613        self.checkraises(TypeError, 'abc', 'center')
614
615    def test_swapcase(self):
616        self.checkequal('hEllO CoMPuTErS', 'HeLLo cOmpUteRs', 'swapcase')
617
618        self.checkraises(TypeError, 'hello', 'swapcase', 42)
619
620    def test_replace(self):
621        EQ = self.checkequal
622
623        # Operations on the empty string
624        EQ("", "", "replace", "", "")
625        EQ("A", "", "replace", "", "A")
626        EQ("", "", "replace", "A", "")
627        EQ("", "", "replace", "A", "A")
628        EQ("", "", "replace", "", "", 100)
629        EQ("", "", "replace", "", "", sys.maxint)
630
631        # interleave (from=="", 'to' gets inserted everywhere)
632        EQ("A", "A", "replace", "", "")
633        EQ("*A*", "A", "replace", "", "*")
634        EQ("*1A*1", "A", "replace", "", "*1")
635        EQ("*-#A*-#", "A", "replace", "", "*-#")
636        EQ("*-A*-A*-", "AA", "replace", "", "*-")
637        EQ("*-A*-A*-", "AA", "replace", "", "*-", -1)
638        EQ("*-A*-A*-", "AA", "replace", "", "*-", sys.maxint)
639        EQ("*-A*-A*-", "AA", "replace", "", "*-", 4)
640        EQ("*-A*-A*-", "AA", "replace", "", "*-", 3)
641        EQ("*-A*-A", "AA", "replace", "", "*-", 2)
642        EQ("*-AA", "AA", "replace", "", "*-", 1)
643        EQ("AA", "AA", "replace", "", "*-", 0)
644
645        # single character deletion (from=="A", to=="")
646        EQ("", "A", "replace", "A", "")
647        EQ("", "AAA", "replace", "A", "")
648        EQ("", "AAA", "replace", "A", "", -1)
649        EQ("", "AAA", "replace", "A", "", sys.maxint)
650        EQ("", "AAA", "replace", "A", "", 4)
651        EQ("", "AAA", "replace", "A", "", 3)
652        EQ("A", "AAA", "replace", "A", "", 2)
653        EQ("AA", "AAA", "replace", "A", "", 1)
654        EQ("AAA", "AAA", "replace", "A", "", 0)
655        EQ("", "AAAAAAAAAA", "replace", "A", "")
656        EQ("BCD", "ABACADA", "replace", "A", "")
657        EQ("BCD", "ABACADA", "replace", "A", "", -1)
658        EQ("BCD", "ABACADA", "replace", "A", "", sys.maxint)
659        EQ("BCD", "ABACADA", "replace", "A", "", 5)
660        EQ("BCD", "ABACADA", "replace", "A", "", 4)
661        EQ("BCDA", "ABACADA", "replace", "A", "", 3)
662        EQ("BCADA", "ABACADA", "replace", "A", "", 2)
663        EQ("BACADA", "ABACADA", "replace", "A", "", 1)
664        EQ("ABACADA", "ABACADA", "replace", "A", "", 0)
665        EQ("BCD", "ABCAD", "replace", "A", "")
666        EQ("BCD", "ABCADAA", "replace", "A", "")
667        EQ("BCD", "BCD", "replace", "A", "")
668        EQ("*************", "*************", "replace", "A", "")
669        EQ("^A^", "^"+"A"*1000+"^", "replace", "A", "", 999)
670
671        # substring deletion (from=="the", to=="")
672        EQ("", "the", "replace", "the", "")
673        EQ("ater", "theater", "replace", "the", "")
674        EQ("", "thethe", "replace", "the", "")
675        EQ("", "thethethethe", "replace", "the", "")
676        EQ("aaaa", "theatheatheathea", "replace", "the", "")
677        EQ("that", "that", "replace", "the", "")
678        EQ("thaet", "thaet", "replace", "the", "")
679        EQ("here and re", "here and there", "replace", "the", "")
680        EQ("here and re and re", "here and there and there",
681           "replace", "the", "", sys.maxint)
682        EQ("here and re and re", "here and there and there",
683           "replace", "the", "", -1)
684        EQ("here and re and re", "here and there and there",
685           "replace", "the", "", 3)
686        EQ("here and re and re", "here and there and there",
687           "replace", "the", "", 2)
688        EQ("here and re and there", "here and there and there",
689           "replace", "the", "", 1)
690        EQ("here and there and there", "here and there and there",
691           "replace", "the", "", 0)
692        EQ("here and re and re", "here and there and there", "replace", "the", "")
693
694        EQ("abc", "abc", "replace", "the", "")
695        EQ("abcdefg", "abcdefg", "replace", "the", "")
696
697        # substring deletion (from=="bob", to=="")
698        EQ("bob", "bbobob", "replace", "bob", "")
699        EQ("bobXbob", "bbobobXbbobob", "replace", "bob", "")
700        EQ("aaaaaaa", "aaaaaaabob", "replace", "bob", "")
701        EQ("aaaaaaa", "aaaaaaa", "replace", "bob", "")
702
703        # single character replace in place (len(from)==len(to)==1)
704        EQ("Who goes there?", "Who goes there?", "replace", "o", "o")
705        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O")
706        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", sys.maxint)
707        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", -1)
708        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", 3)
709        EQ("WhO gOes there?", "Who goes there?", "replace", "o", "O", 2)
710        EQ("WhO goes there?", "Who goes there?", "replace", "o", "O", 1)
711        EQ("Who goes there?", "Who goes there?", "replace", "o", "O", 0)
712
713        EQ("Who goes there?", "Who goes there?", "replace", "a", "q")
714        EQ("who goes there?", "Who goes there?", "replace", "W", "w")
715        EQ("wwho goes there?ww", "WWho goes there?WW", "replace", "W", "w")
716        EQ("Who goes there!", "Who goes there?", "replace", "?", "!")
717        EQ("Who goes there!!", "Who goes there??", "replace", "?", "!")
718
719        EQ("Who goes there?", "Who goes there?", "replace", ".", "!")
720
721        # substring replace in place (len(from)==len(to) > 1)
722        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**")
723        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", sys.maxint)
724        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", -1)
725        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", 4)
726        EQ("Th** ** a t**sue", "This is a tissue", "replace", "is", "**", 3)
727        EQ("Th** ** a tissue", "This is a tissue", "replace", "is", "**", 2)
728        EQ("Th** is a tissue", "This is a tissue", "replace", "is", "**", 1)
729        EQ("This is a tissue", "This is a tissue", "replace", "is", "**", 0)
730        EQ("cobob", "bobob", "replace", "bob", "cob")
731        EQ("cobobXcobocob", "bobobXbobobob", "replace", "bob", "cob")
732        EQ("bobob", "bobob", "replace", "bot", "bot")
733
734        # replace single character (len(from)==1, len(to)>1)
735        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK")
736        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK", -1)
737        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK", sys.maxint)
738        EQ("ReyKKjaviKK", "Reykjavik", "replace", "k", "KK", 2)
739        EQ("ReyKKjavik", "Reykjavik", "replace", "k", "KK", 1)
740        EQ("Reykjavik", "Reykjavik", "replace", "k", "KK", 0)
741        EQ("A----B----C----", "A.B.C.", "replace", ".", "----")
742
743        EQ("Reykjavik", "Reykjavik", "replace", "q", "KK")
744
745        # replace substring (len(from)>1, len(to)!=len(from))
746        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
747           "replace", "spam", "ham")
748        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
749           "replace", "spam", "ham", sys.maxint)
750        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
751           "replace", "spam", "ham", -1)
752        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
753           "replace", "spam", "ham", 4)
754        EQ("ham, ham, eggs and ham", "spam, spam, eggs and spam",
755           "replace", "spam", "ham", 3)
756        EQ("ham, ham, eggs and spam", "spam, spam, eggs and spam",
757           "replace", "spam", "ham", 2)
758        EQ("ham, spam, eggs and spam", "spam, spam, eggs and spam",
759           "replace", "spam", "ham", 1)
760        EQ("spam, spam, eggs and spam", "spam, spam, eggs and spam",
761           "replace", "spam", "ham", 0)
762
763        EQ("bobob", "bobobob", "replace", "bobob", "bob")
764        EQ("bobobXbobob", "bobobobXbobobob", "replace", "bobob", "bob")
765        EQ("BOBOBOB", "BOBOBOB", "replace", "bob", "bobby")
766
767        with test_support.check_py3k_warnings():
768            ba = buffer('a')
769            bb = buffer('b')
770        EQ("bbc", "abc", "replace", ba, bb)
771        EQ("aac", "abc", "replace", bb, ba)
772
773        #
774        self.checkequal('one@two!three!', 'one!two!three!', 'replace', '!', '@', 1)
775        self.checkequal('onetwothree', 'one!two!three!', 'replace', '!', '')
776        self.checkequal('one@two@three!', 'one!two!three!', 'replace', '!', '@', 2)
777        self.checkequal('one@two@three@', 'one!two!three!', 'replace', '!', '@', 3)
778        self.checkequal('one@two@three@', 'one!two!three!', 'replace', '!', '@', 4)
779        self.checkequal('one!two!three!', 'one!two!three!', 'replace', '!', '@', 0)
780        self.checkequal('one@two@three@', 'one!two!three!', 'replace', '!', '@')
781        self.checkequal('one!two!three!', 'one!two!three!', 'replace', 'x', '@')
782        self.checkequal('one!two!three!', 'one!two!three!', 'replace', 'x', '@', 2)
783        self.checkequal('-a-b-c-', 'abc', 'replace', '', '-')
784        self.checkequal('-a-b-c', 'abc', 'replace', '', '-', 3)
785        self.checkequal('abc', 'abc', 'replace', '', '-', 0)
786        self.checkequal('', '', 'replace', '', '')
787        self.checkequal('abc', 'abc', 'replace', 'ab', '--', 0)
788        self.checkequal('abc', 'abc', 'replace', 'xy', '--')
789        # Next three for SF bug 422088: [OSF1 alpha] string.replace(); died with
790        # MemoryError due to empty result (platform malloc issue when requesting
791        # 0 bytes).
792        self.checkequal('', '123', 'replace', '123', '')
793        self.checkequal('', '123123', 'replace', '123', '')
794        self.checkequal('x', '123x123', 'replace', '123', '')
795
796        self.checkraises(TypeError, 'hello', 'replace')
797        self.checkraises(TypeError, 'hello', 'replace', 42)
798        self.checkraises(TypeError, 'hello', 'replace', 42, 'h')
799        self.checkraises(TypeError, 'hello', 'replace', 'h', 42)
800
801    @unittest.skipIf(sys.maxint > (1 << 32) or struct.calcsize('P') != 4,
802                     'only applies to 32-bit platforms')
803    def test_replace_overflow(self):
804        # Check for overflow checking on 32 bit machines
805        A2_16 = "A" * (2**16)
806        self.checkraises(OverflowError, A2_16, "replace", "", A2_16)
807        self.checkraises(OverflowError, A2_16, "replace", "A", A2_16)
808        self.checkraises(OverflowError, A2_16, "replace", "AA", A2_16+A2_16)
809
810    def test_zfill(self):
811        self.checkequal('123', '123', 'zfill', 2)
812        self.checkequal('123', '123', 'zfill', 3)
813        self.checkequal('0123', '123', 'zfill', 4)
814        self.checkequal('+123', '+123', 'zfill', 3)
815        self.checkequal('+123', '+123', 'zfill', 4)
816        self.checkequal('+0123', '+123', 'zfill', 5)
817        self.checkequal('-123', '-123', 'zfill', 3)
818        self.checkequal('-123', '-123', 'zfill', 4)
819        self.checkequal('-0123', '-123', 'zfill', 5)
820        self.checkequal('000', '', 'zfill', 3)
821        self.checkequal('34', '34', 'zfill', 1)
822        self.checkequal('0034', '34', 'zfill', 4)
823
824        self.checkraises(TypeError, '123', 'zfill')
825
826
827class NonStringModuleTest:
828    # additional test cases for all string classes from bytearray to
829    # UserString, but not valid for the "string" module
830
831    def test_islower(self):
832        self.checkequal(False, '', 'islower')
833        self.checkequal(True, 'a', 'islower')
834        self.checkequal(False, 'A', 'islower')
835        self.checkequal(False, '\n', 'islower')
836        self.checkequal(True, 'abc', 'islower')
837        self.checkequal(False, 'aBc', 'islower')
838        self.checkequal(True, 'abc\n', 'islower')
839        self.checkraises(TypeError, 'abc', 'islower', 42)
840
841    def test_isupper(self):
842        self.checkequal(False, '', 'isupper')
843        self.checkequal(False, 'a', 'isupper')
844        self.checkequal(True, 'A', 'isupper')
845        self.checkequal(False, '\n', 'isupper')
846        self.checkequal(True, 'ABC', 'isupper')
847        self.checkequal(False, 'AbC', 'isupper')
848        self.checkequal(True, 'ABC\n', 'isupper')
849        self.checkraises(TypeError, 'abc', 'isupper', 42)
850
851    def test_istitle(self):
852        self.checkequal(False, '', 'istitle')
853        self.checkequal(False, 'a', 'istitle')
854        self.checkequal(True, 'A', 'istitle')
855        self.checkequal(False, '\n', 'istitle')
856        self.checkequal(True, 'A Titlecased Line', 'istitle')
857        self.checkequal(True, 'A\nTitlecased Line', 'istitle')
858        self.checkequal(True, 'A Titlecased, Line', 'istitle')
859        self.checkequal(False, 'Not a capitalized String', 'istitle')
860        self.checkequal(False, 'Not\ta Titlecase String', 'istitle')
861        self.checkequal(False, 'Not--a Titlecase String', 'istitle')
862        self.checkequal(False, 'NOT', 'istitle')
863        self.checkraises(TypeError, 'abc', 'istitle', 42)
864
865    def test_isspace(self):
866        self.checkequal(False, '', 'isspace')
867        self.checkequal(False, 'a', 'isspace')
868        self.checkequal(True, ' ', 'isspace')
869        self.checkequal(True, '\t', 'isspace')
870        self.checkequal(True, '\r', 'isspace')
871        self.checkequal(True, '\n', 'isspace')
872        self.checkequal(True, ' \t\r\n', 'isspace')
873        self.checkequal(False, ' \t\r\na', 'isspace')
874        self.checkraises(TypeError, 'abc', 'isspace', 42)
875
876    def test_isalpha(self):
877        self.checkequal(False, '', 'isalpha')
878        self.checkequal(True, 'a', 'isalpha')
879        self.checkequal(True, 'A', 'isalpha')
880        self.checkequal(False, '\n', 'isalpha')
881        self.checkequal(True, 'abc', 'isalpha')
882        self.checkequal(False, 'aBc123', 'isalpha')
883        self.checkequal(False, 'abc\n', 'isalpha')
884        self.checkraises(TypeError, 'abc', 'isalpha', 42)
885
886    def test_isalnum(self):
887        self.checkequal(False, '', 'isalnum')
888        self.checkequal(True, 'a', 'isalnum')
889        self.checkequal(True, 'A', 'isalnum')
890        self.checkequal(False, '\n', 'isalnum')
891        self.checkequal(True, '123abc456', 'isalnum')
892        self.checkequal(True, 'a1b3c', 'isalnum')
893        self.checkequal(False, 'aBc000 ', 'isalnum')
894        self.checkequal(False, 'abc\n', 'isalnum')
895        self.checkraises(TypeError, 'abc', 'isalnum', 42)
896
897    def test_isdigit(self):
898        self.checkequal(False, '', 'isdigit')
899        self.checkequal(False, 'a', 'isdigit')
900        self.checkequal(True, '0', 'isdigit')
901        self.checkequal(True, '0123456789', 'isdigit')
902        self.checkequal(False, '0123456789a', 'isdigit')
903
904        self.checkraises(TypeError, 'abc', 'isdigit', 42)
905
906    def test_title(self):
907        self.checkequal(' Hello ', ' hello ', 'title')
908        self.checkequal('Hello ', 'hello ', 'title')
909        self.checkequal('Hello ', 'Hello ', 'title')
910        self.checkequal('Format This As Title String', "fOrMaT thIs aS titLe String", 'title')
911        self.checkequal('Format,This-As*Title;String', "fOrMaT,thIs-aS*titLe;String", 'title', )
912        self.checkequal('Getint', "getInt", 'title')
913        self.checkraises(TypeError, 'hello', 'title', 42)
914
915    def test_splitlines(self):
916        self.checkequal(['abc', 'def', '', 'ghi'], "abc\ndef\n\rghi", 'splitlines')
917        self.checkequal(['abc', 'def', '', 'ghi'], "abc\ndef\n\r\nghi", 'splitlines')
918        self.checkequal(['abc', 'def', 'ghi'], "abc\ndef\r\nghi", 'splitlines')
919        self.checkequal(['abc', 'def', 'ghi'], "abc\ndef\r\nghi\n", 'splitlines')
920        self.checkequal(['abc', 'def', 'ghi', ''], "abc\ndef\r\nghi\n\r", 'splitlines')
921        self.checkequal(['', 'abc', 'def', 'ghi', ''], "\nabc\ndef\r\nghi\n\r", 'splitlines')
922        self.checkequal(['\n', 'abc\n', 'def\r\n', 'ghi\n', '\r'], "\nabc\ndef\r\nghi\n\r", 'splitlines', 1)
923
924        self.checkraises(TypeError, 'abc', 'splitlines', 42, 42)
925
926
927class MixinStrUnicodeUserStringTest(NonStringModuleTest):
928    # additional tests that only work for
929    # stringlike objects, i.e. str, unicode, UserString
930    # (but not the string module)
931
932    def test_startswith(self):
933        self.checkequal(True, 'hello', 'startswith', 'he')
934        self.checkequal(True, 'hello', 'startswith', 'hello')
935        self.checkequal(False, 'hello', 'startswith', 'hello world')
936        self.checkequal(True, 'hello', 'startswith', '')
937        self.checkequal(False, 'hello', 'startswith', 'ello')
938        self.checkequal(True, 'hello', 'startswith', 'ello', 1)
939        self.checkequal(True, 'hello', 'startswith', 'o', 4)
940        self.checkequal(False, 'hello', 'startswith', 'o', 5)
941        self.checkequal(True, 'hello', 'startswith', '', 5)
942        self.checkequal(False, 'hello', 'startswith', 'lo', 6)
943        self.checkequal(True, 'helloworld', 'startswith', 'lowo', 3)
944        self.checkequal(True, 'helloworld', 'startswith', 'lowo', 3, 7)
945        self.checkequal(False, 'helloworld', 'startswith', 'lowo', 3, 6)
946
947        # test negative indices
948        self.checkequal(True, 'hello', 'startswith', 'he', 0, -1)
949        self.checkequal(True, 'hello', 'startswith', 'he', -53, -1)
950        self.checkequal(False, 'hello', 'startswith', 'hello', 0, -1)
951        self.checkequal(False, 'hello', 'startswith', 'hello world', -1, -10)
952        self.checkequal(False, 'hello', 'startswith', 'ello', -5)
953        self.checkequal(True, 'hello', 'startswith', 'ello', -4)
954        self.checkequal(False, 'hello', 'startswith', 'o', -2)
955        self.checkequal(True, 'hello', 'startswith', 'o', -1)
956        self.checkequal(True, 'hello', 'startswith', '', -3, -3)
957        self.checkequal(False, 'hello', 'startswith', 'lo', -9)
958
959        self.checkraises(TypeError, 'hello', 'startswith')
960        self.checkraises(TypeError, 'hello', 'startswith', 42)
961
962        # test tuple arguments
963        self.checkequal(True, 'hello', 'startswith', ('he', 'ha'))
964        self.checkequal(False, 'hello', 'startswith', ('lo', 'llo'))
965        self.checkequal(True, 'hello', 'startswith', ('hellox', 'hello'))
966        self.checkequal(False, 'hello', 'startswith', ())
967        self.checkequal(True, 'helloworld', 'startswith', ('hellowo',
968                                                           'rld', 'lowo'), 3)
969        self.checkequal(False, 'helloworld', 'startswith', ('hellowo', 'ello',
970                                                            'rld'), 3)
971        self.checkequal(True, 'hello', 'startswith', ('lo', 'he'), 0, -1)
972        self.checkequal(False, 'hello', 'startswith', ('he', 'hel'), 0, 1)
973        self.checkequal(True, 'hello', 'startswith', ('he', 'hel'), 0, 2)
974
975        self.checkraises(TypeError, 'hello', 'startswith', (42,))
976
977    def test_endswith(self):
978        self.checkequal(True, 'hello', 'endswith', 'lo')
979        self.checkequal(False, 'hello', 'endswith', 'he')
980        self.checkequal(True, 'hello', 'endswith', '')
981        self.checkequal(False, 'hello', 'endswith', 'hello world')
982        self.checkequal(False, 'helloworld', 'endswith', 'worl')
983        self.checkequal(True, 'helloworld', 'endswith', 'worl', 3, 9)
984        self.checkequal(True, 'helloworld', 'endswith', 'world', 3, 12)
985        self.checkequal(True, 'helloworld', 'endswith', 'lowo', 1, 7)
986        self.checkequal(True, 'helloworld', 'endswith', 'lowo', 2, 7)
987        self.checkequal(True, 'helloworld', 'endswith', 'lowo', 3, 7)
988        self.checkequal(False, 'helloworld', 'endswith', 'lowo', 4, 7)
989        self.checkequal(False, 'helloworld', 'endswith', 'lowo', 3, 8)
990        self.checkequal(False, 'ab', 'endswith', 'ab', 0, 1)
991        self.checkequal(False, 'ab', 'endswith', 'ab', 0, 0)
992
993        # test negative indices
994        self.checkequal(True, 'hello', 'endswith', 'lo', -2)
995        self.checkequal(False, 'hello', 'endswith', 'he', -2)
996        self.checkequal(True, 'hello', 'endswith', '', -3, -3)
997        self.checkequal(False, 'hello', 'endswith', 'hello world', -10, -2)
998        self.checkequal(False, 'helloworld', 'endswith', 'worl', -6)
999        self.checkequal(True, 'helloworld', 'endswith', 'worl', -5, -1)
1000        self.checkequal(True, 'helloworld', 'endswith', 'worl', -5, 9)
1001        self.checkequal(True, 'helloworld', 'endswith', 'world', -7, 12)
1002        self.checkequal(True, 'helloworld', 'endswith', 'lowo', -99, -3)
1003        self.checkequal(True, 'helloworld', 'endswith', 'lowo', -8, -3)
1004        self.checkequal(True, 'helloworld', 'endswith', 'lowo', -7, -3)
1005        self.checkequal(False, 'helloworld', 'endswith', 'lowo', 3, -4)
1006        self.checkequal(False, 'helloworld', 'endswith', 'lowo', -8, -2)
1007
1008        self.checkraises(TypeError, 'hello', 'endswith')
1009        self.checkraises(TypeError, 'hello', 'endswith', 42)
1010
1011        # test tuple arguments
1012        self.checkequal(False, 'hello', 'endswith', ('he', 'ha'))
1013        self.checkequal(True, 'hello', 'endswith', ('lo', 'llo'))
1014        self.checkequal(True, 'hello', 'endswith', ('hellox', 'hello'))
1015        self.checkequal(False, 'hello', 'endswith', ())
1016        self.checkequal(True, 'helloworld', 'endswith', ('hellowo',
1017                                                           'rld', 'lowo'), 3)
1018        self.checkequal(False, 'helloworld', 'endswith', ('hellowo', 'ello',
1019                                                            'rld'), 3, -1)
1020        self.checkequal(True, 'hello', 'endswith', ('hell', 'ell'), 0, -1)
1021        self.checkequal(False, 'hello', 'endswith', ('he', 'hel'), 0, 1)
1022        self.checkequal(True, 'hello', 'endswith', ('he', 'hell'), 0, 4)
1023
1024        self.checkraises(TypeError, 'hello', 'endswith', (42,))
1025
1026    def test___contains__(self):
1027        self.checkequal(True, '', '__contains__', '')
1028        self.checkequal(True, 'abc', '__contains__', '')
1029        self.checkequal(False, 'abc', '__contains__', '\0')
1030        self.checkequal(True, '\0abc', '__contains__', '\0')
1031        self.checkequal(True, 'abc\0', '__contains__', '\0')
1032        self.checkequal(True, '\0abc', '__contains__', 'a')
1033        self.checkequal(True, 'asdf', '__contains__', 'asdf')
1034        self.checkequal(False, 'asd', '__contains__', 'asdf')
1035        self.checkequal(False, '', '__contains__', 'asdf')
1036
1037    def test_subscript(self):
1038        self.checkequal(u'a', 'abc', '__getitem__', 0)
1039        self.checkequal(u'c', 'abc', '__getitem__', -1)
1040        self.checkequal(u'a', 'abc', '__getitem__', 0L)
1041        self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 3))
1042        self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 1000))
1043        self.checkequal(u'a', 'abc', '__getitem__', slice(0, 1))
1044        self.checkequal(u'', 'abc', '__getitem__', slice(0, 0))
1045
1046        self.checkraises(TypeError, 'abc', '__getitem__', 'def')
1047
1048    def test_slice(self):
1049        self.checkequal('abc', 'abc', '__getslice__', 0, 1000)
1050        self.checkequal('abc', 'abc', '__getslice__', 0, 3)
1051        self.checkequal('ab', 'abc', '__getslice__', 0, 2)
1052        self.checkequal('bc', 'abc', '__getslice__', 1, 3)
1053        self.checkequal('b', 'abc', '__getslice__', 1, 2)
1054        self.checkequal('', 'abc', '__getslice__', 2, 2)
1055        self.checkequal('', 'abc', '__getslice__', 1000, 1000)
1056        self.checkequal('', 'abc', '__getslice__', 2000, 1000)
1057        self.checkequal('', 'abc', '__getslice__', 2, 1)
1058
1059        self.checkraises(TypeError, 'abc', '__getslice__', 'def')
1060
1061    def test_extended_getslice(self):
1062        # Test extended slicing by comparing with list slicing.
1063        s = string.ascii_letters + string.digits
1064        indices = (0, None, 1, 3, 41, -1, -2, -37)
1065        for start in indices:
1066            for stop in indices:
1067                # Skip step 0 (invalid)
1068                for step in indices[1:]:
1069                    L = list(s)[start:stop:step]
1070                    self.checkequal(u"".join(L), s, '__getitem__',
1071                                    slice(start, stop, step))
1072
1073    def test_mul(self):
1074        self.checkequal('', 'abc', '__mul__', -1)
1075        self.checkequal('', 'abc', '__mul__', 0)
1076        self.checkequal('abc', 'abc', '__mul__', 1)
1077        self.checkequal('abcabcabc', 'abc', '__mul__', 3)
1078        self.checkraises(TypeError, 'abc', '__mul__')
1079        self.checkraises(TypeError, 'abc', '__mul__', '')
1080        # XXX: on a 64-bit system, this doesn't raise an overflow error,
1081        # but either raises a MemoryError, or succeeds (if you have 54TiB)
1082        #self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000)
1083
1084    def test_join(self):
1085        # join now works with any sequence type
1086        # moved here, because the argument order is
1087        # different in string.join (see the test in
1088        # test.test_string.StringTest.test_join)
1089        self.checkequal('a b c d', ' ', 'join', ['a', 'b', 'c', 'd'])
1090        self.checkequal('abcd', '', 'join', ('a', 'b', 'c', 'd'))
1091        self.checkequal('bd', '', 'join', ('', 'b', '', 'd'))
1092        self.checkequal('ac', '', 'join', ('a', '', 'c', ''))
1093        self.checkequal('w x y z', ' ', 'join', Sequence())
1094        self.checkequal('abc', 'a', 'join', ('abc',))
1095        self.checkequal('z', 'a', 'join', UserList(['z']))
1096        if test_support.have_unicode:
1097            self.checkequal(unicode('a.b.c'), unicode('.'), 'join', ['a', 'b', 'c'])
1098            self.checkequal(unicode('a.b.c'), '.', 'join', [unicode('a'), 'b', 'c'])
1099            self.checkequal(unicode('a.b.c'), '.', 'join', ['a', unicode('b'), 'c'])
1100            self.checkequal(unicode('a.b.c'), '.', 'join', ['a', 'b', unicode('c')])
1101            self.checkraises(TypeError, '.', 'join', ['a', unicode('b'), 3])
1102        for i in [5, 25, 125]:
1103            self.checkequal(((('a' * i) + '-') * i)[:-1], '-', 'join',
1104                 ['a' * i] * i)
1105            self.checkequal(((('a' * i) + '-') * i)[:-1], '-', 'join',
1106                 ('a' * i,) * i)
1107
1108        self.checkraises(TypeError, ' ', 'join', BadSeq1())
1109        self.checkequal('a b c', ' ', 'join', BadSeq2())
1110
1111        self.checkraises(TypeError, ' ', 'join')
1112        self.checkraises(TypeError, ' ', 'join', None)
1113        self.checkraises(TypeError, ' ', 'join', 7)
1114        self.checkraises(TypeError, ' ', 'join', Sequence([7, 'hello', 123L]))
1115        try:
1116            def f():
1117                yield 4 + ""
1118            self.fixtype(' ').join(f())
1119        except TypeError, e:
1120            if '+' not in str(e):
1121                self.fail('join() ate exception message')
1122        else:
1123            self.fail('exception not raised')
1124
1125    def test_formatting(self):
1126        self.checkequal('+hello+', '+%s+', '__mod__', 'hello')
1127        self.checkequal('+10+', '+%d+', '__mod__', 10)
1128        self.checkequal('a', "%c", '__mod__', "a")
1129        self.checkequal('a', "%c", '__mod__', "a")
1130        self.checkequal('"', "%c", '__mod__', 34)
1131        self.checkequal('$', "%c", '__mod__', 36)
1132        self.checkequal('10', "%d", '__mod__', 10)
1133        self.checkequal('\x7f', "%c", '__mod__', 0x7f)
1134
1135        for ordinal in (-100, 0x200000):
1136            # unicode raises ValueError, str raises OverflowError
1137            self.checkraises((ValueError, OverflowError), '%c', '__mod__', ordinal)
1138
1139        longvalue = sys.maxint + 10L
1140        slongvalue = str(longvalue)
1141        if slongvalue[-1] in ("L","l"): slongvalue = slongvalue[:-1]
1142        self.checkequal(' 42', '%3ld', '__mod__', 42)
1143        self.checkequal('42', '%d', '__mod__', 42L)
1144        self.checkequal('42', '%d', '__mod__', 42.0)
1145        self.checkequal(slongvalue, '%d', '__mod__', longvalue)
1146        self.checkcall('%d', '__mod__', float(longvalue))
1147        self.checkequal('0042.00', '%07.2f', '__mod__', 42)
1148        self.checkequal('0042.00', '%07.2F', '__mod__', 42)
1149
1150        self.checkraises(TypeError, 'abc', '__mod__')
1151        self.checkraises(TypeError, '%(foo)s', '__mod__', 42)
1152        self.checkraises(TypeError, '%s%s', '__mod__', (42,))
1153        self.checkraises(TypeError, '%c', '__mod__', (None,))
1154        self.checkraises(ValueError, '%(foo', '__mod__', {})
1155        self.checkraises(TypeError, '%(foo)s %(bar)s', '__mod__', ('foo', 42))
1156        self.checkraises(TypeError, '%d', '__mod__', "42") # not numeric
1157        self.checkraises(TypeError, '%d', '__mod__', (42+0j)) # no int/long conversion provided
1158
1159        # argument names with properly nested brackets are supported
1160        self.checkequal('bar', '%((foo))s', '__mod__', {'(foo)': 'bar'})
1161
1162        # 100 is a magic number in PyUnicode_Format, this forces a resize
1163        self.checkequal(103*'a'+'x', '%sx', '__mod__', 103*'a')
1164
1165        self.checkraises(TypeError, '%*s', '__mod__', ('foo', 'bar'))
1166        self.checkraises(TypeError, '%10.*f', '__mod__', ('foo', 42.))
1167        self.checkraises(ValueError, '%10', '__mod__', (42,))
1168
1169        class X(object): pass
1170        self.checkraises(TypeError, 'abc', '__mod__', X())
1171        class X(Exception):
1172            def __getitem__(self, k):
1173                return k
1174        self.checkequal('melon apple', '%(melon)s %(apple)s', '__mod__', X())
1175
1176    @test_support.cpython_only
1177    def test_formatting_c_limits(self):
1178        from _testcapi import PY_SSIZE_T_MAX, INT_MAX, UINT_MAX
1179        SIZE_MAX = (1 << (PY_SSIZE_T_MAX.bit_length() + 1)) - 1
1180        width = int(PY_SSIZE_T_MAX + 1)
1181        if width <= sys.maxint:
1182            self.checkraises(OverflowError, '%*s', '__mod__', (width, ''))
1183        prec = int(INT_MAX + 1)
1184        if prec <= sys.maxint:
1185            self.checkraises(OverflowError, '%.*f', '__mod__', (prec, 1. / 7))
1186        # Issue 15989
1187        width = int(SIZE_MAX + 1)
1188        if width <= sys.maxint:
1189            self.checkraises(OverflowError, '%*s', '__mod__', (width, ''))
1190        prec = int(UINT_MAX + 1)
1191        if prec <= sys.maxint:
1192            self.checkraises(OverflowError, '%.*f', '__mod__', (prec, 1. / 7))
1193
1194    def test_floatformatting(self):
1195        # float formatting
1196        for prec in xrange(100):
1197            format = '%%.%if' % prec
1198            value = 0.01
1199            for x in xrange(60):
1200                value = value * 3.14159265359 / 3.0 * 10.0
1201                self.checkcall(format, "__mod__", value)
1202
1203    def test_inplace_rewrites(self):
1204        # Check that strings don't copy and modify cached single-character strings
1205        self.checkequal('a', 'A', 'lower')
1206        self.checkequal(True, 'A', 'isupper')
1207        self.checkequal('A', 'a', 'upper')
1208        self.checkequal(True, 'a', 'islower')
1209
1210        self.checkequal('a', 'A', 'replace', 'A', 'a')
1211        self.checkequal(True, 'A', 'isupper')
1212
1213        self.checkequal('A', 'a', 'capitalize')
1214        self.checkequal(True, 'a', 'islower')
1215
1216        self.checkequal('A', 'a', 'swapcase')
1217        self.checkequal(True, 'a', 'islower')
1218
1219        self.checkequal('A', 'a', 'title')
1220        self.checkequal(True, 'a', 'islower')
1221
1222    def test_partition(self):
1223
1224        self.checkequal(('this is the par', 'ti', 'tion method'),
1225            'this is the partition method', 'partition', 'ti')
1226
1227        # from raymond's original specification
1228        S = 'http://www.python.org'
1229        self.checkequal(('http', '://', 'www.python.org'), S, 'partition', '://')
1230        self.checkequal(('http://www.python.org', '', ''), S, 'partition', '?')
1231        self.checkequal(('', 'http://', 'www.python.org'), S, 'partition', 'http://')
1232        self.checkequal(('http://www.python.', 'org', ''), S, 'partition', 'org')
1233
1234        self.checkraises(ValueError, S, 'partition', '')
1235        self.checkraises(TypeError, S, 'partition', None)
1236
1237        # mixed use of str and unicode
1238        self.assertEqual('a/b/c'.partition(u'/'), ('a', '/', 'b/c'))
1239
1240    def test_rpartition(self):
1241
1242        self.checkequal(('this is the rparti', 'ti', 'on method'),
1243            'this is the rpartition method', 'rpartition', 'ti')
1244
1245        # from raymond's original specification
1246        S = 'http://www.python.org'
1247        self.checkequal(('http', '://', 'www.python.org'), S, 'rpartition', '://')
1248        self.checkequal(('', '', 'http://www.python.org'), S, 'rpartition', '?')
1249        self.checkequal(('', 'http://', 'www.python.org'), S, 'rpartition', 'http://')
1250        self.checkequal(('http://www.python.', 'org', ''), S, 'rpartition', 'org')
1251
1252        self.checkraises(ValueError, S, 'rpartition', '')
1253        self.checkraises(TypeError, S, 'rpartition', None)
1254
1255        # mixed use of str and unicode
1256        self.assertEqual('a/b/c'.rpartition(u'/'), ('a/b', '/', 'c'))
1257
1258    def test_none_arguments(self):
1259        # issue 11828
1260        s = 'hello'
1261        self.checkequal(2, s, 'find', 'l', None)
1262        self.checkequal(3, s, 'find', 'l', -2, None)
1263        self.checkequal(2, s, 'find', 'l', None, -2)
1264        self.checkequal(0, s, 'find', 'h', None, None)
1265
1266        self.checkequal(3, s, 'rfind', 'l', None)
1267        self.checkequal(3, s, 'rfind', 'l', -2, None)
1268        self.checkequal(2, s, 'rfind', 'l', None, -2)
1269        self.checkequal(0, s, 'rfind', 'h', None, None)
1270
1271        self.checkequal(2, s, 'index', 'l', None)
1272        self.checkequal(3, s, 'index', 'l', -2, None)
1273        self.checkequal(2, s, 'index', 'l', None, -2)
1274        self.checkequal(0, s, 'index', 'h', None, None)
1275
1276        self.checkequal(3, s, 'rindex', 'l', None)
1277        self.checkequal(3, s, 'rindex', 'l', -2, None)
1278        self.checkequal(2, s, 'rindex', 'l', None, -2)
1279        self.checkequal(0, s, 'rindex', 'h', None, None)
1280
1281        self.checkequal(2, s, 'count', 'l', None)
1282        self.checkequal(1, s, 'count', 'l', -2, None)
1283        self.checkequal(1, s, 'count', 'l', None, -2)
1284        self.checkequal(0, s, 'count', 'x', None, None)
1285
1286        self.checkequal(True, s, 'endswith', 'o', None)
1287        self.checkequal(True, s, 'endswith', 'lo', -2, None)
1288        self.checkequal(True, s, 'endswith', 'l', None, -2)
1289        self.checkequal(False, s, 'endswith', 'x', None, None)
1290
1291        self.checkequal(True, s, 'startswith', 'h', None)
1292        self.checkequal(True, s, 'startswith', 'l', -2, None)
1293        self.checkequal(True, s, 'startswith', 'h', None, -2)
1294        self.checkequal(False, s, 'startswith', 'x', None, None)
1295
1296    def test_find_etc_raise_correct_error_messages(self):
1297        # issue 11828
1298        s = 'hello'
1299        x = 'x'
1300        self.assertRaisesRegexp(TypeError, r'\bfind\b', s.find,
1301                                x, None, None, None)
1302        self.assertRaisesRegexp(TypeError, r'\brfind\b', s.rfind,
1303                                x, None, None, None)
1304        self.assertRaisesRegexp(TypeError, r'\bindex\b', s.index,
1305                                x, None, None, None)
1306        self.assertRaisesRegexp(TypeError, r'\brindex\b', s.rindex,
1307                                x, None, None, None)
1308        self.assertRaisesRegexp(TypeError, r'^count\(', s.count,
1309                                x, None, None, None)
1310        self.assertRaisesRegexp(TypeError, r'^startswith\(', s.startswith,
1311                                x, None, None, None)
1312        self.assertRaisesRegexp(TypeError, r'^endswith\(', s.endswith,
1313                                x, None, None, None)
1314
1315class MixinStrStringUserStringTest:
1316    # Additional tests for 8bit strings, i.e. str, UserString and
1317    # the string module
1318
1319    def test_maketrans(self):
1320        self.assertEqual(
1321           ''.join(map(chr, xrange(256))).replace('abc', 'xyz'),
1322           string.maketrans('abc', 'xyz')
1323        )
1324        self.assertRaises(ValueError, string.maketrans, 'abc', 'xyzw')
1325
1326    def test_translate(self):
1327        table = string.maketrans('abc', 'xyz')
1328        self.checkequal('xyzxyz', 'xyzabcdef', 'translate', table, 'def')
1329
1330        table = string.maketrans('a', 'A')
1331        self.checkequal('Abc', 'abc', 'translate', table)
1332        self.checkequal('xyz', 'xyz', 'translate', table)
1333        self.checkequal('yz', 'xyz', 'translate', table, 'x')
1334        self.checkequal('yx', 'zyzzx', 'translate', None, 'z')
1335        self.checkequal('zyzzx', 'zyzzx', 'translate', None, '')
1336        self.checkequal('zyzzx', 'zyzzx', 'translate', None)
1337        self.checkraises(ValueError, 'xyz', 'translate', 'too short', 'strip')
1338        self.checkraises(ValueError, 'xyz', 'translate', 'too short')
1339
1340
1341class MixinStrUserStringTest:
1342    # Additional tests that only work with
1343    # 8bit compatible object, i.e. str and UserString
1344
1345    @unittest.skipUnless(test_support.have_unicode, 'no unicode support')
1346    def test_encoding_decoding(self):
1347        codecs = [('rot13', 'uryyb jbeyq'),
1348                  ('base64', 'aGVsbG8gd29ybGQ=\n'),
1349                  ('hex', '68656c6c6f20776f726c64'),
1350                  ('uu', 'begin 666 <data>\n+:&5L;&\\@=V]R;&0 \n \nend\n')]
1351        for encoding, data in codecs:
1352            with test_support.check_py3k_warnings():
1353                self.checkequal(data, 'hello world', 'encode', encoding)
1354            with test_support.check_py3k_warnings():
1355                self.checkequal('hello world', data, 'decode', encoding)
1356        # zlib is optional, so we make the test optional too...
1357        try:
1358            import zlib
1359        except ImportError:
1360            pass
1361        else:
1362            data = 'x\x9c\xcbH\xcd\xc9\xc9W(\xcf/\xcaI\x01\x00\x1a\x0b\x04]'
1363            with test_support.check_py3k_warnings():
1364                self.checkequal(data, 'hello world', 'encode', 'zlib')
1365            with test_support.check_py3k_warnings():
1366                self.checkequal('hello world', data, 'decode', 'zlib')
1367
1368        self.checkraises(TypeError, 'xyz', 'decode', 42)
1369        self.checkraises(TypeError, 'xyz', 'encode', 42)
1370
1371
1372class MixinStrUnicodeTest:
1373    # Additional tests that only work with str and unicode.
1374
1375    def test_bug1001011(self):
1376        # Make sure join returns a NEW object for single item sequences
1377        # involving a subclass.
1378        # Make sure that it is of the appropriate type.
1379        # Check the optimisation still occurs for standard objects.
1380        t = self.type2test
1381        class subclass(t):
1382            pass
1383        s1 = subclass("abcd")
1384        s2 = t().join([s1])
1385        self.assertTrue(s1 is not s2)
1386        self.assertTrue(type(s2) is t)
1387
1388        s1 = t("abcd")
1389        s2 = t().join([s1])
1390        self.assertTrue(s1 is s2)
1391
1392        # Should also test mixed-type join.
1393        if t is unicode:
1394            s1 = subclass("abcd")
1395            s2 = "".join([s1])
1396            self.assertTrue(s1 is not s2)
1397            self.assertTrue(type(s2) is t)
1398
1399            s1 = t("abcd")
1400            s2 = "".join([s1])
1401            self.assertTrue(s1 is s2)
1402
1403        elif t is str:
1404            s1 = subclass("abcd")
1405            s2 = u"".join([s1])
1406            self.assertTrue(s1 is not s2)
1407            self.assertTrue(type(s2) is unicode) # promotes!
1408
1409            s1 = t("abcd")
1410            s2 = u"".join([s1])
1411            self.assertTrue(s1 is not s2)
1412            self.assertTrue(type(s2) is unicode) # promotes!
1413
1414        else:
1415            self.fail("unexpected type for MixinStrUnicodeTest %r" % t)
1416