Author: Armin Rigo <[email protected]>
Branch: py3.5-bytearray
Changeset: r88841:a338838c2d41
Date: 2016-12-03 10:30 +0100
http://bitbucket.org/pypy/pypy/changeset/a338838c2d41/
Log: in-progress
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
@@ -6,7 +6,7 @@
from rpython.rlib.buffer import Buffer
from rpython.rlib.rarithmetic import intmask
from rpython.rlib.rstring import StringBuilder, ByteListBuilder
-from rpython.rlib.debug import check_list_of_chars
+from rpython.rlib.debug import check_list_of_chars, check_nonneg
from rpython.rtyper.lltypesystem import rffi
from rpython.rlib.rgc import (resizable_list_supporting_raw_ptr,
nonmoving_raw_ptr_for_resizable_list)
@@ -32,23 +32,32 @@
def __init__(self, data):
check_list_of_chars(data)
- self.data = resizable_list_supporting_raw_ptr(data)
+ self._data = resizable_list_supporting_raw_ptr(data)
+ self._offset = 0
+ # NOTE: the bytearray data is in 'self._data[self._offset:]'
+
+ def getdata(self):
+ if self._offset > 0:
+ self._data = self._data[self._offset:]
+ self._offset = 0
+ return self._data
def __repr__(self):
"""representation for debugging purposes"""
- return "%s(%s)" % (self.__class__.__name__, ''.join(self.data))
+ return "%s(%s)" % (self.__class__.__name__,
+ ''.join(self._data[self._offset:]))
def buffer_w(self, space, flags):
- return BytearrayBuffer(self.data, False)
+ return BytearrayBuffer(self._data, self._offset)
def bytearray_list_of_chars_w(self, space):
- return self.data
+ return self.getdata()
def nonmovable_carray(self, space):
- return BytearrayBuffer(self.data, False).get_raw_address()
+ return BytearrayBuffer(self._data, self._offset).get_raw_address()
def _new(self, value):
- if value is self.data:
+ if value is self._data:
value = value[:]
return W_BytearrayObject(value)
@@ -62,17 +71,29 @@
return W_BytearrayObject([])
def _len(self):
- return len(self.data)
+ return len(self._data) - self._offset
+
+ def _fixindex(self, space, index):
+ # for getitem/setitem/delitem of a single char
+ if index >= 0:
+ index += self._offset
+ oob = index >= len(self._data)
+ else:
+ index += len(self._data) # count from the end
+ oob = index < self._offset
+ if oob:
+ raise oefmt(space.w_IndexError, "bytearray index out of range")
+ check_nonneg(index)
+ return index
def _getitem_result(self, space, index):
- try:
- character = self.data[index]
- except IndexError:
- raise oefmt(space.w_IndexError, "bytearray index out of range")
+ character = self._data[self._fixindex(space, index)]
return space.wrap(ord(character))
def _val(self, space):
- return self.data
+ # XXX review the calls of _val and think if some of them should
+ # XXX not force a copy of self._data if _offset > 0
+ return self.getdata()
@staticmethod
def _use_rstr_ops(space, w_other):
@@ -151,11 +172,12 @@
return False
def ord(self, space):
- if len(self.data) != 1:
+ length = self._len()
+ if length != 1:
raise oefmt(space.w_TypeError,
"ord() expected a character, but string of length %d "
- "found", len(self.data))
- return space.wrap(ord(self.data[0]))
+ "found", length)
+ return space.wrap(ord(self._data[self._offset]))
@staticmethod
def descr_new(space, w_bytearraytype, __args__):
@@ -168,7 +190,7 @@
w_dict = space.w_None
return space.newtuple([
space.type(self), space.newtuple([
- space.wrap(''.join(self.data).decode('latin-1')),
+ space.wrap(''.join(self.getdata()).decode('latin-1')),
space.wrap('latin-1')]),
w_dict])
@@ -186,10 +208,11 @@
def descr_init(self, space, w_source=None, encoding=None, errors=None):
assert isinstance(self, W_BytearrayObject)
data = [c for c in newbytesdata_w(space, w_source, encoding, errors)]
- self.data = resizable_list_supporting_raw_ptr(data)
+ self._data = resizable_list_supporting_raw_ptr(data)
+ self._offset = 0
def descr_repr(self, space):
- s = self.data
+ s = self.getdata()
# Good default if there are no replacements.
buf = StringBuilder(len("bytearray(b'')") + len(s))
@@ -237,7 +260,7 @@
def descr_eq(self, space, w_other):
if isinstance(w_other, W_BytearrayObject):
- return space.newbool(self.data == w_other.data)
+ return space.newbool(self.getdata() == w_other.getdata())
try:
buffer = _get_buffer(space, w_other)
@@ -257,7 +280,7 @@
def descr_ne(self, space, w_other):
if isinstance(w_other, W_BytearrayObject):
- return space.newbool(self.data != w_other.data)
+ return space.newbool(self.getdata() != w_other.getdata())
try:
buffer = _get_buffer(space, w_other)
@@ -279,7 +302,7 @@
value = self._val(space)
if isinstance(w_other, W_BytearrayObject):
- other = w_other.data
+ other = w_other.getdata()
other_len = len(other)
cmp = _memcmp(value, other, min(len(value), len(other)))
elif isinstance(w_other, W_BytesObject):
@@ -324,7 +347,7 @@
def descr_inplace_add(self, space, w_other):
if isinstance(w_other, W_BytearrayObject):
- self.data += w_other.data
+ self._data += w_other.getdata()
return self
if isinstance(w_other, W_BytesObject):
@@ -336,7 +359,7 @@
@specialize.argtype(1)
def _inplace_add(self, other):
for i in range(len(other)):
- self.data.append(other[i])
+ self._data.append(other[i])
def descr_inplace_mul(self, space, w_times):
try:
@@ -345,11 +368,13 @@
if e.match(space, space.w_TypeError):
return space.w_NotImplemented
raise
- self.data *= times
+ data = self.getdata()
+ data *= times
return self
def descr_setitem(self, space, w_index, w_other):
if isinstance(w_index, W_SliceObject):
+ XXX
oldsize = len(self.data)
start, stop, step, slicelength = w_index.indices4(space, oldsize)
sequence2 = [c for c in makebytesdata_w(space, w_other)]
@@ -357,33 +382,28 @@
slicelength, sequence2, empty_elem='\x00')
else:
idx = space.getindex_w(w_index, space.w_IndexError, "bytearray")
- try:
- self.data[idx] = getbytevalue(space, w_other)
- except IndexError:
- raise oefmt(space.w_IndexError, "bytearray index out of range")
+ newvalue = getbytevalue(space, w_other)
+ self._data[self._fixindex(space, idx)] = newvalue
def descr_delitem(self, space, w_idx):
if isinstance(w_idx, W_SliceObject):
+ XXX
start, stop, step, slicelength = w_idx.indices4(space,
len(self.data))
_delitem_slice_helper(space, self.data, start, step, slicelength)
else:
+ XXX # case of del b[0]
idx = space.getindex_w(w_idx, space.w_IndexError, "bytearray")
- try:
- del self.data[idx]
- except IndexError:
- raise oefmt(space.w_IndexError,
- "bytearray deletion index out of range")
+ del self._data[self._fixindex(space, idx)]
def descr_append(self, space, w_item):
- self.data.append(getbytevalue(space, w_item))
+ self._data.append(getbytevalue(space, w_item))
def descr_extend(self, space, w_other):
if isinstance(w_other, W_BytearrayObject):
- self.data += w_other.data
+ self._data += w_other.getdata()
else:
- self.data += [c for c in makebytesdata_w(space, w_other)]
- return self
+ self._inplace_add(makebytesdata_w(space, w_other))
def descr_insert(self, space, w_idx, w_other):
where = space.int_w(w_idx)
@@ -391,7 +411,6 @@
index = get_positive_index(where, length)
val = getbytevalue(space, w_other)
self.data.insert(index, val)
- return space.w_None
@unwrap_spec(w_idx=WrappedDefault(-1))
def descr_pop(self, space, w_idx):
@@ -1217,9 +1236,9 @@
class BytearrayBuffer(Buffer):
_immutable_ = True
- def __init__(self, data, readonly):
- self.data = data
- self.readonly = readonly
+ def __init__(self, data, offset):
+ self._data = data
+ self._offset = offset
def getlength(self):
return len(self.data)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit