Author: Tyler Wade <way...@gmail.com>
Branch: fix-bytearray-complexity
Changeset: r71877:6ac3f4336b1b
Date: 2014-05-28 22:45 -0500
http://bitbucket.org/pypy/pypy/changeset/6ac3f4336b1b/

Log:    Fix translation

diff --git a/pypy/objspace/std/bytearrayobject.py 
b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -20,12 +20,12 @@
 class W_BytearrayObject(W_Root):
     import_from_mixin(StringMethods)
 
-    def __init__(w_self, data):
-        w_self.data = data
+    def __init__(self, data):
+        self.data = data
 
-    def __repr__(w_self):
+    def __repr__(self):
         """representation for debugging purposes"""
-        return "%s(%s)" % (w_self.__class__.__name__, ''.join(w_self.data))
+        return "%s(%s)" % (self.__class__.__name__, ''.join(self.data))
 
     def buffer_w(self, space, flags):
         return BytearrayBuffer(self.data, False)
@@ -62,10 +62,6 @@
             raise oefmt(space.w_IndexError, "bytearray index out of range")
         return space.wrap(ord(character))
 
-    def _fillchar(self, space, w_fillchar):
-        c = self._op_val(space, w_fillchar)
-        return [c], len(c)
-
     def _val(self, space):
         return self.data
 
@@ -82,14 +78,14 @@
         return str(char)[0]
 
     def _multi_chr(self, char):
-        return [self._chr(char)]
+        return [char]
 
     @staticmethod
     def _builder(size=100):
         return ByteListBuilder(size)
 
     def _newlist_unwrapped(self, space, res):
-        return space.newlist([W_BytearrayObject(_make_data(i)) for i in res])
+        return space.newlist([W_BytearrayObject(i) for i in res])
 
     def _isupper(self, ch):
         return ch.isupper()
@@ -318,9 +314,6 @@
         return space.newbool(_memcmp(value, buffer, min_length) != 0)
 
     def descr_lt(self, space, w_other):
-        if isinstance(w_other, W_BytearrayObject):
-            return space.newbool(self.data < w_other.data)
-
         try:
             buffer = _get_buffer(space, w_other)
         except OperationError as e:
@@ -332,13 +325,9 @@
         buffer_len = buffer.getlength()
 
         cmp = _memcmp(value, buffer, min(len(value), buffer_len))
-        return space.newbool(
-            cmp < 0 or (cmp == 0 and space.newbool(len(value) < buffer_len)))
+        return space.newbool(cmp < 0 or (cmp == 0 and len(value) < buffer_len))
 
     def descr_le(self, space, w_other):
-        if isinstance(w_other, W_BytearrayObject):
-            return space.newbool(self.data <= w_other.data)
-
         try:
             buffer = _get_buffer(space, w_other)
         except OperationError as e:
@@ -350,13 +339,9 @@
         buffer_len = buffer.getlength()
 
         cmp = _memcmp(value, buffer, min(len(value), buffer_len))
-        return space.newbool(
-            cmp < 0 or (cmp == 0 and space.newbool(len(value) <= buffer_len)))
+        return space.newbool(cmp < 0 or (cmp == 0 and len(value) <= 
buffer_len))
 
     def descr_gt(self, space, w_other):
-        if isinstance(w_other, W_BytearrayObject):
-            return space.newbool(self.data > w_other.data)
-
         try:
             buffer = _get_buffer(space, w_other)
         except OperationError as e:
@@ -368,13 +353,9 @@
         buffer_len = buffer.getlength()
 
         cmp = _memcmp(value, buffer, min(len(value), buffer_len))
-        return space.newbool(
-            cmp > 0 or (cmp == 0 and space.newbool(len(value) > buffer_len)))
+        return space.newbool(cmp > 0 or (cmp == 0 and len(value) > buffer_len))
 
     def descr_ge(self, space, w_other):
-        if isinstance(w_other, W_BytearrayObject):
-            return space.newbool(self.data >= w_other.data)
-
         try:
             buffer = _get_buffer(space, w_other)
         except OperationError as e:
@@ -386,8 +367,7 @@
         buffer_len = buffer.getlength()
 
         cmp = _memcmp(value, buffer, min(len(value), buffer_len))
-        return space.newbool(
-            cmp > 0 or (cmp == 0 and space.newbool(len(value) >= buffer_len)))
+        return space.newbool(cmp > 0 or (cmp == 0 and len(value) >= 
buffer_len))
 
     def descr_iter(self, space):
         return space.newseqiter(self)
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -430,6 +430,7 @@
     _immutable_fields_ = ['_value']
 
     def __init__(self, str):
+        assert str is not None
         self._value = str
 
     def __repr__(self):
@@ -482,7 +483,8 @@
     @staticmethod
     def _use_rstr_ops(space, w_other):
         from pypy.objspace.std.unicodeobject import W_UnicodeObject
-        return isinstance(w_other, (W_BytesObject, W_UnicodeObject))
+        return (isinstance(w_other, W_BytesObject) or
+                isinstance(w_other, W_UnicodeObject))
 
     @staticmethod
     def _op_val(space, w_other):
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
@@ -6,6 +6,7 @@
 from rpython.rlib.rstring import (
     search, SEARCH_FIND, SEARCH_RFIND, SEARCH_COUNT, endswith, replace, rsplit,
     split, startswith)
+from rpython.rlib.buffer import Buffer
 
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import WrappedDefault, unwrap_spec
@@ -31,7 +32,7 @@
         return (value, start, end)
 
     def _multi_chr(self, c):
-        return self._chr(c)
+        return c
 
     def descr_len(self, space):
         return space.wrap(self._len())
@@ -73,7 +74,7 @@
         if times <= 0:
             return self._empty()
         if self._len() == 1:
-            return self._new(self._val(space)[0] * times)
+            return self._new(self._multi_chr(self._val(space)[0]) * times)
         return self._new(self._val(space) * times)
 
     descr_rmul = descr_mul
@@ -134,7 +135,7 @@
         d = width - len(value)
         if d > 0:
             offset = d//2 + (d & width & 1)
-            fillchar = self._multi_chr(fillchar)
+            fillchar = self._multi_chr(fillchar[0])
             centered = offset * fillchar + value + (d - offset) * fillchar
         else:
             centered = value
@@ -177,7 +178,7 @@
         if not value:
             return self._empty()
 
-        if self._use_rstr_ops(value, self):
+        if self._use_rstr_ops(space, self):
             splitted = value.split(self._chr('\t'))
         else:
             splitted = split(value, self._chr('\t'))
@@ -189,7 +190,7 @@
         expanded = oldtoken = splitted.pop(0)
 
         for token in splitted:
-            expanded += self._multi_chr(' ') * self._tabindent(oldtoken,
+            expanded += self._multi_chr(self._chr(' ')) * 
self._tabindent(oldtoken,
                                                          tabsize) + token
             oldtoken = token
 
@@ -391,7 +392,7 @@
             # XXX Maybe the extra copy here is okay? It was basically going to
             #     happen anyway, what with being placed into the builder
             unwrapped.append(self._op_val(space, w_s))
-            prealloc_size += len(unwrapped[0])
+            prealloc_size += len(unwrapped[i])
 
         sb = self._builder(prealloc_size)
         for i in range(size):
@@ -412,7 +413,7 @@
                         "ljust() argument 2 must be a single character")
         d = width - len(value)
         if d > 0:
-            fillchar = self._multi_chr(fillchar)
+            fillchar = self._multi_chr(fillchar[0])
             value += d * fillchar
 
         return self._new(value)
@@ -426,7 +427,7 @@
                         "rjust() argument 2 must be a single character")
         d = width - len(value)
         if d > 0:
-            fillchar = self._multi_chr(fillchar)
+            fillchar = self._multi_chr(fillchar[0])
             value = d * fillchar + value
 
         return self._new(value)
@@ -439,63 +440,61 @@
         return self._new(builder.build())
 
     def descr_partition(self, space, w_sub):
+        from pypy.objspace.std.bytearrayobject import W_BytearrayObject
         value = self._val(space)
 
         if self._use_rstr_ops(space, w_sub):
             sub = self._op_val(space, w_sub)
             sublen = len(sub)
+            if sublen == 0:
+                raise oefmt(space.w_ValueError, "empty separator")
+
+            pos = value.find(sub)
         else:
             sub = _get_buffer(space, w_sub)
             sublen = sub.getlength()
+            if sublen == 0:
+                raise oefmt(space.w_ValueError, "empty separator")
 
-        if sublen == 0:
-            raise oefmt(space.w_ValueError, "empty separator")
-
-        if self._use_rstr_ops(space, w_sub):
-            pos = value.find(sub)
-        else:
             pos = search(value, sub, 0, len(value), SEARCH_FIND)
+            if pos != -1 and isinstance(self, W_BytearrayObject):
+                w_sub = self._new_from_buffer(sub)
 
         if pos == -1:
-            from pypy.objspace.std.bytearrayobject import W_BytearrayObject
             if isinstance(self, W_BytearrayObject):
                 self = self._new(value)
             return space.newtuple([self, self._empty(), self._empty()])
         else:
-            from pypy.objspace.std.bytearrayobject import W_BytearrayObject
-            if isinstance(self, W_BytearrayObject):
-                w_sub = self._new_from_buffer(sub)
             return space.newtuple(
                 [self._sliced(space, value, 0, pos, self), w_sub,
                  self._sliced(space, value, pos + sublen, len(value), self)])
 
     def descr_rpartition(self, space, w_sub):
+        from pypy.objspace.std.bytearrayobject import W_BytearrayObject
         value = self._val(space)
 
         if self._use_rstr_ops(space, w_sub):
             sub = self._op_val(space, w_sub)
             sublen = len(sub)
+            if sublen == 0:
+                raise oefmt(space.w_ValueError, "empty separator")
+
+            pos = value.rfind(sub)
         else:
             sub = _get_buffer(space, w_sub)
             sublen = sub.getlength()
+            if sublen == 0:
+                raise oefmt(space.w_ValueError, "empty separator")
 
-        if sublen == 0:
-            raise oefmt(space.w_ValueError, "empty separator")
-
-        if self._use_rstr_ops(space, w_sub):
-            pos = value.rfind(sub)
-        else:
             pos = search(value, sub, 0, len(value), SEARCH_RFIND)
+            if pos != -1 and isinstance(self, W_BytearrayObject):
+                w_sub = self._new_from_buffer(sub)
 
         if pos == -1:
-            from pypy.objspace.std.bytearrayobject import W_BytearrayObject
             if isinstance(self, W_BytearrayObject):
                 self = self._new(value)
             return space.newtuple([self._empty(), self._empty(), self])
         else:
-            from pypy.objspace.std.bytearrayobject import W_BytearrayObject
-            if isinstance(self, W_BytearrayObject):
-                w_sub = self._new_from_buffer(sub)
             return space.newtuple(
                 [self._sliced(space, value, 0, pos, self), w_sub,
                  self._sliced(space, value, pos + sublen, len(value), self)])
@@ -715,7 +714,7 @@
     def descr_zfill(self, space, width):
         selfval = self._val(space)
         if len(selfval) == 0:
-            return self._new(self._chr('0') * width)
+            return self._new(self._multi_chr(self._chr('0')) * width)
         num_zeros = width - len(selfval)
         if num_zeros <= 0:
             # cannot return self, in case it is a subclass of str
diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py
--- a/rpython/rlib/rstring.py
+++ b/rpython/rlib/rstring.py
@@ -36,6 +36,8 @@
             return search(obj, other, start, end, SEARCH_FIND)
         def rfind(obj, other, start, end):
             return search(obj, other, start, end, SEARCH_RFIND)
+        def count(obj, other, start, end):
+            return search(obj, other, start, end, SEARCH_COUNT)
     else:
         assert isinstance(value, str) or  isinstance(value, unicode)
         assert isinstance(other, str) or  isinstance(other, unicode)
@@ -43,8 +45,10 @@
             return obj.find(other, start, end)
         def rfind(obj, other, start, end):
             return obj.rfind(other, start, end)
+        def count(obj, other, start, end):
+            return obj.count(other, start, end)
 
-    return getitem, getlength, find, rfind
+    return getitem, getlength, find, rfind, count
 
 @specialize.argtype(0)
 def _isspace(char):
@@ -90,7 +94,7 @@
         assert isinstance(by, str)
     else:
         assert isinstance(by, unicode)
-    _, _, find, _ = _get_access_functions(value, by)
+    _, _, find, _, count = _get_access_functions(value, by)
     bylen = len(by)
     if bylen == 0:
         raise ValueError("empty separator")
@@ -99,7 +103,7 @@
     if bylen == 1:
         # fast path: uses str.rfind(character) and str.count(character)
         by = by[0]    # annotator hack: string -> char
-        count = value.count(by)
+        count = count(value, by, 0, len(value))
         if 0 <= maxsplit < count:
             count = maxsplit
         res = newlist_hint(count + 1)
@@ -173,7 +177,7 @@
         res = newlist_hint(min(maxsplit + 1, len(value)))
     else:
         res = []
-    _, _, _, rfind = _get_access_functions(value, by)
+    _, _, _, rfind, _ = _get_access_functions(value, by)
     end = len(value)
     bylen = len(by)
     if bylen == 0:
@@ -212,7 +216,7 @@
     if maxsplit == 0:
         return input
 
-    _, _, find, _ = _get_access_functions(input, sub)
+    _, _, find, _, count = _get_access_functions(input, sub)
 
     if not sub:
         upper = len(input)
@@ -236,7 +240,7 @@
         builder.append_slice(input, upper, len(input))
     else:
         # First compute the exact result size
-        count = input.count(sub)
+        count = count(input, sub, 0, len(input))
         if count > maxsplit and maxsplit > 0:
             count = maxsplit
         diff_len = len(by) - len(sub)
@@ -317,7 +321,7 @@
 
 @specialize.argtype(0, 1)
 def search(value, other, start, end, mode):
-    getitem, getlength, _, _ = _get_access_functions(value, other)
+    getitem, getlength, _, _, _ = _get_access_functions(value, other)
     if start < 0:
         start = 0
     if end > len(value):
@@ -571,7 +575,7 @@
 
     def append_multiple_char(self, c, times):
         assert isinstance(c, str)
-        self.l.extend([c] * times)
+        self.l.extend([c[0]] * times)
 
     def append_charpsize(self, s, size):
         assert size >= 0
diff --git a/rpython/rtyper/rlist.py b/rpython/rtyper/rlist.py
--- a/rpython/rtyper/rlist.py
+++ b/rpython/rtyper/rlist.py
@@ -293,6 +293,11 @@
         v_lst, v_factor = hop.inputargs(r_lst, Signed)
         return hop.gendirectcall(ll_mul, cRESLIST, v_lst, v_factor)
 
+class __extend__(pairtype(IntegerRepr, AbstractBaseListRepr)):
+    def rtype_mul((r_int, r_lst), hop):
+        cRESLIST = hop.inputconst(Void, hop.r_result.LIST)
+        v_factor, v_lst = hop.inputargs(Signed, r_lst)
+        return hop.gendirectcall(ll_mul, cRESLIST, v_lst, v_factor)
 
 class __extend__(pairtype(AbstractListRepr, IntegerRepr)):
 
diff --git a/rpython/rtyper/test/test_rlist.py 
b/rpython/rtyper/test/test_rlist.py
--- a/rpython/rtyper/test/test_rlist.py
+++ b/rpython/rtyper/test/test_rlist.py
@@ -946,6 +946,15 @@
         for arg in (1, 9, 0, -1, -27):
             res = self.interpret(fn, [arg])
             assert res == fn(arg)
+        def fn(i):
+            lst =  i * [i, i + 1]
+            ret = len(lst)
+            if ret:
+                ret *= lst[-1]
+            return ret
+        for arg in (1, 9, 0, -1, -27):
+            res = self.interpret(fn, [arg])
+            assert res == fn(arg)
 
     def test_list_inplace_multiply(self):
         def fn(i):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to