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