Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Lib/collections/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,8 @@ def format_map(self, mapping):
return self.data.format_map(mapping)

def index(self, sub, start=0, end=_sys.maxsize):
if isinstance(sub, UserString):
sub = sub.data
return self.data.index(sub, start, end)

def isalpha(self):
Expand Down Expand Up @@ -1610,6 +1612,8 @@ def rfind(self, sub, start=0, end=_sys.maxsize):
return self.data.rfind(sub, start, end)

def rindex(self, sub, start=0, end=_sys.maxsize):
if isinstance(sub, UserString):
sub = sub.data
return self.data.rindex(sub, start, end)

def rjust(self, width, *args):
Expand Down
80 changes: 53 additions & 27 deletions Lib/test/string_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ def checkcall(self, obj, methodname, *args):
args = self.fixtype(args)
getattr(obj, methodname)(*args)

def _get_teststrings(self, charset, digits):
base = len(charset)
teststrings = set()
for i in range(base ** digits):
entry = []
for j in range(digits):
i, m = divmod(i, base)
entry.append(charset[m])
teststrings.add(''.join(entry))
teststrings = [self.fixtype(ts) for ts in teststrings]
return teststrings

def test_count(self):
self.checkequal(3, 'aaa', 'count', 'a')
self.checkequal(0, 'aaa', 'count', 'b')
Expand Down Expand Up @@ -132,15 +144,7 @@ def test_count(self):
# replacing all occurrences and then differencing the string lengths
charset = ['', 'a', 'b']
digits = 7
base = len(charset)
teststrings = set()
for i in range(base ** digits):
entry = []
for j in range(digits):
i, m = divmod(i, base)
entry.append(charset[m])
teststrings.add(''.join(entry))
teststrings = [self.fixtype(ts) for ts in teststrings]
teststrings = self._get_teststrings(charset, digits)
for i in teststrings:
n = len(i)
for j in teststrings:
Expand Down Expand Up @@ -199,15 +203,7 @@ def test_find(self):
# and that the found substring is really at that location
charset = ['', 'a', 'b', 'c']
digits = 5
base = len(charset)
teststrings = set()
for i in range(base ** digits):
entry = []
for j in range(digits):
i, m = divmod(i, base)
entry.append(charset[m])
teststrings.add(''.join(entry))
teststrings = [self.fixtype(ts) for ts in teststrings]
teststrings = self._get_teststrings(charset, digits)
for i in teststrings:
for j in teststrings:
loc = i.find(j)
Expand Down Expand Up @@ -246,15 +242,7 @@ def test_rfind(self):
# and that the found substring is really at that location
charset = ['', 'a', 'b', 'c']
digits = 5
base = len(charset)
teststrings = set()
for i in range(base ** digits):
entry = []
for j in range(digits):
i, m = divmod(i, base)
entry.append(charset[m])
teststrings.add(''.join(entry))
teststrings = [self.fixtype(ts) for ts in teststrings]
teststrings = self._get_teststrings(charset, digits)
for i in teststrings:
for j in teststrings:
loc = i.rfind(j)
Expand Down Expand Up @@ -295,6 +283,25 @@ def test_index(self):
else:
self.checkraises(TypeError, 'hello', 'index', 42)

# For a variety of combinations,
# verify that str.index() matches __contains__
# and that the found substring is really at that location
charset = ['', 'a', 'b', 'c']
digits = 5
teststrings = self._get_teststrings(charset, digits)
for i in teststrings:
for j in teststrings:
if j in i:
loc = i.index(j)
else:
self.assertRaises(ValueError, i.index, j)
loc = -1
r1 = (loc != -1)
r2 = j in i
self.assertEqual(r1, r2)
if loc != -1:
self.assertEqual(i[loc:loc+len(j)], j)

def test_rindex(self):
self.checkequal(12, 'abcdefghiabc', 'rindex', '')
self.checkequal(3, 'abcdefghiabc', 'rindex', 'def')
Expand All @@ -321,6 +328,25 @@ def test_rindex(self):
else:
self.checkraises(TypeError, 'hello', 'rindex', 42)

# For a variety of combinations,
# verify that str.rindex() matches __contains__
# and that the found substring is really at that location
charset = ['', 'a', 'b', 'c']
digits = 5
teststrings = self._get_teststrings(charset, digits)
for i in teststrings:
for j in teststrings:
if j in i:
loc = i.rindex(j)
else:
self.assertRaises(ValueError, i.rindex, j)
loc = -1
r1 = (loc != -1)
r2 = j in i
self.assertEqual(r1, r2)
if loc != -1:
self.assertEqual(i[loc:loc+len(j)], j)

def test_find_periodic_pattern(self):
"""Cover the special path for periodic patterns."""
def reference_find(p, s):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:mod:`collections`: Ensure that the methods ``UserString.rindex()`` and
``UserString.index()`` accept :class:`collections.UserString` instances as the
sub argument.
Loading