Author: Tyler Wade <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit