python (3.11.7)

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