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