Skip to content

Commit 3fde8f3

Browse files
sapsalianyouknowone
authored andcommitted
update string_tests.py from python 3.11.2
1 parent 1795740 commit 3fde8f3

File tree

1 file changed

+61
-8
lines changed

1 file changed

+61
-8
lines changed

Lib/test/string_tests.py

+61-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
import unittest, string, sys, struct
66
from test import support
7+
from test.support import import_helper
78
from collections import UserList
9+
import random
810

911
class Sequence:
1012
def __init__(self, seq='wxyz'): self.seq = seq
@@ -79,12 +81,14 @@ class subtype(self.__class__.type2test):
7981
self.assertIsNot(obj, realresult)
8082

8183
# check that obj.method(*args) raises exc
82-
def checkraises(self, exc, obj, methodname, *args):
84+
def checkraises(self, exc, obj, methodname, *args, expected_msg=None):
8385
obj = self.fixtype(obj)
8486
args = self.fixtype(args)
8587
with self.assertRaises(exc) as cm:
8688
getattr(obj, methodname)(*args)
8789
self.assertNotEqual(str(cm.exception), '')
90+
if expected_msg is not None:
91+
self.assertEqual(str(cm.exception), expected_msg)
8892

8993
# call obj.method(*args) without any checks
9094
def checkcall(self, obj, methodname, *args):
@@ -317,6 +321,44 @@ def test_rindex(self):
317321
else:
318322
self.checkraises(TypeError, 'hello', 'rindex', 42)
319323

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+
return -1
331+
332+
rr = random.randrange
333+
choices = random.choices
334+
for _ in range(1000):
335+
p0 = ''.join(choices('abcde', k=rr(10))) * rr(10, 20)
336+
p = p0[:len(p0) - rr(10)] # pop off some characters
337+
left = ''.join(choices('abcdef', k=rr(2000)))
338+
right = ''.join(choices('abcdef', k=rr(2000)))
339+
text = left + p + right
340+
with self.subTest(p=p, text=text):
341+
self.checkequal(reference_find(p, text),
342+
text, 'find', p)
343+
344+
def test_find_shift_table_overflow(self):
345+
"""When the table of 8-bit shifts overflows."""
346+
N = 2**8 + 100
347+
348+
# first check the periodic case
349+
# here, the shift for 'b' is N + 1.
350+
pattern1 = 'a' * N + 'b' + 'a' * N
351+
text1 = 'babbaa' * N + pattern1
352+
self.checkequal(len(text1)-len(pattern1),
353+
text1, 'find', pattern1)
354+
355+
# now check the non-periodic case
356+
# here, the shift for 'd' is 3*(N+1)+1
357+
pattern2 = 'ddd' + 'abc' * N + "eee"
358+
text2 = pattern2[:-1] + "ddeede" * 2 * N + pattern2 + "de" * N
359+
self.checkequal(len(text2) - N*len("de") - len(pattern2),
360+
text2, 'find', pattern2)
361+
320362
def test_lower(self):
321363
self.checkequal('hello', 'HeLLo', 'lower')
322364
self.checkequal('hello', 'hello', 'lower')
@@ -428,6 +470,11 @@ def test_split(self):
428470
self.checkraises(ValueError, 'hello', 'split', '', 0)
429471

430472
def test_rsplit(self):
473+
# without arg
474+
self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit')
475+
self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit')
476+
self.checkequal([], '', 'rsplit')
477+
431478
# by a char
432479
self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|')
433480
self.checkequal(['a|b|c', 'd'], 'a|b|c|d', 'rsplit', '|', 1)
@@ -481,6 +528,9 @@ def test_rsplit(self):
481528

482529
# with keyword args
483530
self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', sep='|')
531+
self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', sep=None)
532+
self.checkequal(['a b c', 'd'],
533+
'a b c d', 'rsplit', sep=None, maxsplit=1)
484534
self.checkequal(['a|b|c', 'd'],
485535
'a|b|c|d', 'rsplit', '|', maxsplit=1)
486536
self.checkequal(['a|b|c', 'd'],
@@ -506,6 +556,7 @@ def test_replace(self):
506556
EQ("", "", "replace", "A", "")
507557
EQ("", "", "replace", "A", "A")
508558
EQ("", "", "replace", "", "", 100)
559+
EQ("A", "", "replace", "", "A", 100)
509560
EQ("", "", "replace", "", "", sys.maxsize)
510561

511562
# interleave (from=="", 'to' gets inserted everywhere)
@@ -1162,6 +1213,10 @@ def test_subscript(self):
11621213

11631214
self.checkraises(TypeError, 'abc', '__getitem__', 'def')
11641215

1216+
for idx_type in ('def', object()):
1217+
expected_msg = "string indices must be integers, not '{}'".format(type(idx_type).__name__)
1218+
self.checkraises(TypeError, 'abc', '__getitem__', idx_type, expected_msg=expected_msg)
1219+
11651220
def test_slice(self):
11661221
self.checkequal('abc', 'abc', '__getitem__', slice(0, 1000))
11671222
self.checkequal('abc', 'abc', '__getitem__', slice(0, 3))
@@ -1188,8 +1243,6 @@ def test_extended_getslice(self):
11881243
slice(start, stop, step))
11891244

11901245
def test_mul(self):
1191-
self.assertTrue("('' * 3) is ''");
1192-
self.assertTrue("('a' * 0) is ''");
11931246
self.checkequal('', 'abc', '__mul__', -1)
11941247
self.checkequal('', 'abc', '__mul__', 0)
11951248
self.checkequal('abc', 'abc', '__mul__', 1)
@@ -1291,17 +1344,17 @@ class X(object): pass
12911344

12921345
@support.cpython_only
12931346
def test_formatting_c_limits(self):
1294-
from _testcapi import PY_SSIZE_T_MAX, INT_MAX, UINT_MAX
1295-
SIZE_MAX = (1 << (PY_SSIZE_T_MAX.bit_length() + 1)) - 1
1347+
_testcapi = import_helper.import_module('_testcapi')
1348+
SIZE_MAX = (1 << (_testcapi.PY_SSIZE_T_MAX.bit_length() + 1)) - 1
12961349
self.checkraises(OverflowError, '%*s', '__mod__',
1297-
(PY_SSIZE_T_MAX + 1, ''))
1350+
(_testcapi.PY_SSIZE_T_MAX + 1, ''))
12981351
self.checkraises(OverflowError, '%.*f', '__mod__',
1299-
(INT_MAX + 1, 1. / 7))
1352+
(_testcapi.INT_MAX + 1, 1. / 7))
13001353
# Issue 15989
13011354
self.checkraises(OverflowError, '%*s', '__mod__',
13021355
(SIZE_MAX + 1, ''))
13031356
self.checkraises(OverflowError, '%.*f', '__mod__',
1304-
(UINT_MAX + 1, 1. / 7))
1357+
(_testcapi.UINT_MAX + 1, 1. / 7))
13051358

13061359
def test_floatformatting(self):
13071360
# float formatting

0 commit comments

Comments
 (0)