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

Reply via email to