Author: Armin Rigo <[email protected]>
Branch:
Changeset: r85132:41928beccff9
Date: 2016-06-13 17:26 +0200
http://bitbucket.org/pypy/pypy/changeset/41928beccff9/
Log: Issue #2324: fix for bytearray().replace('a', 'ab')
We have too much mess and code duplication around here.
diff --git a/pypy/objspace/std/stringmethods.py
b/pypy/objspace/std/stringmethods.py
--- a/pypy/objspace/std/stringmethods.py
+++ b/pypy/objspace/std/stringmethods.py
@@ -162,7 +162,8 @@
buffer = _get_buffer(space, w_sub)
res = count(value, buffer, start, end)
- return space.wrap(max(res, 0))
+ assert res >= 0
+ return space.wrap(res)
def descr_decode(self, space, w_encoding=None, w_errors=None):
from pypy.objspace.std.unicodeobject import (
diff --git a/pypy/objspace/std/test/test_bytearrayobject.py
b/pypy/objspace/std/test/test_bytearrayobject.py
--- a/pypy/objspace/std/test/test_bytearrayobject.py
+++ b/pypy/objspace/std/test/test_bytearrayobject.py
@@ -211,6 +211,7 @@
check(bytearray('abc').replace('b', bytearray('d')), 'adc')
check(bytearray('abc').replace('b', 'd'), 'adc')
+ check(bytearray('').replace('a', 'ab'), '')
check(bytearray('abc').upper(), 'ABC')
check(bytearray('ABC').lower(), 'abc')
diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py
--- a/rpython/rlib/rstring.py
+++ b/rpython/rlib/rstring.py
@@ -291,6 +291,7 @@
return _search(value, other, start, end, SEARCH_COUNT)
# -------------- substring searching helper ----------------
+# XXX a lot of code duplication with lltypesystem.rstr :-(
SEARCH_COUNT = 0
SEARCH_FIND = 1
@@ -309,6 +310,8 @@
if end > len(value):
end = len(value)
if start > end:
+ if mode == SEARCH_COUNT:
+ return 0
return -1
count = 0
@@ -326,6 +329,8 @@
w = n - m
if w < 0:
+ if mode == SEARCH_COUNT:
+ return 0
return -1
mlast = m - 1
@@ -570,18 +575,20 @@
class ByteListBuilder(object):
def __init__(self, init_size=INIT_SIZE):
+ assert init_size >= 0
self.l = newlist_hint(init_size)
@specialize.argtype(1)
def append(self, s):
+ l = self.l
for c in s:
- self.l.append(c)
+ l.append(c)
@specialize.argtype(1)
def append_slice(self, s, start, end):
- assert 0 <= start <= end <= len(s)
- for c in s[start:end]:
- self.l.append(c)
+ l = self.l
+ for i in xrange(start, end):
+ l.append(s[i])
def append_multiple_char(self, c, times):
assert isinstance(c, str)
@@ -589,8 +596,9 @@
def append_charpsize(self, s, size):
assert size >= 0
+ l = self.l
for i in xrange(size):
- self.l.append(s[i])
+ l.append(s[i])
def build(self):
return self.l
diff --git a/rpython/rlib/test/test_rstring.py
b/rpython/rlib/test/test_rstring.py
--- a/rpython/rlib/test/test_rstring.py
+++ b/rpython/rlib/test/test_rstring.py
@@ -231,6 +231,10 @@
check_search(count, 'one two three', 'e', 0, 1, res=0)
check_search(count, 'one two three', '', 0, 13, res=14)
+ check_search(count, '', 'ab', 0, 0, res=0)
+ check_search(count, 'a', 'ab', 0, 1, res=0)
+ check_search(count, 'ac', 'ab', 0, 2, res=0)
+
class TestTranslates(BaseRtypingTest):
def test_split_rsplit(self):
diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py
--- a/rpython/rtyper/test/test_rstr.py
+++ b/rpython/rtyper/test/test_rstr.py
@@ -972,6 +972,13 @@
s.count(s, -10)
py.test.raises(AnnotatorError, self.interpret, f, ())
+ def test_count_in_empty_string(self):
+ const = self.const
+ def fn():
+ return const('').count(const('ab'))
+ res = self.interpret(fn, [])
+ assert res == 0
+
def test_getitem_exc(self):
const = self.const
def f(x):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit