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