Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit