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

Reply via email to