[pypy-commit] pypy py3.5-bytearray: a test to check explicitly for non-forced cases
arigo
pypy.commits at gmail.com
Sat Dec 3 06:40:34 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5-bytearray
Changeset: r88844:9d0fb0aff02d
Date: 2016-12-03 12:20 +0100
http://bitbucket.org/pypy/pypy/changeset/9d0fb0aff02d/
Log: a test to check explicitly for non-forced cases
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,6 +20,7 @@
from pypy.interpreter.typedef import TypeDef
from pypy.objspace.std.sliceobject import W_SliceObject, unwrap_start_stop
from pypy.objspace.std.stringmethods import StringMethods, _get_buffer
+from pypy.objspace.std.stringmethods import _descr_getslice_slowpath
from pypy.objspace.std.bytesobject import W_BytesObject
from pypy.objspace.std.util import get_positive_index
from pypy.objspace.std.formatting import mod_format, FORMAT_BYTEARRAY
@@ -93,8 +94,6 @@
return space.wrap(ord(character))
def _val(self, space):
- # 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
@@ -377,7 +376,7 @@
def descr_setitem(self, space, w_index, w_other):
if isinstance(w_index, W_SliceObject):
- sequence2 = [c for c in makebytesdata_w(space, w_other)]
+ sequence2 = makebytesdata_w(space, w_other)
oldsize = self._len()
start, stop, step, slicelength = w_index.indices4(space, oldsize)
if start == 0 and step == 1 and len(sequence2) <= slicelength:
@@ -385,11 +384,8 @@
slicelength = len(sequence2)
if slicelength == 0:
return
- data = self._data
- start += self._offset
- #stop += self._offset---not used
- else:
- data = self.getdata()
+ data = self._data
+ start += self._offset
_setitem_slice_helper(space, data, start, step,
slicelength, sequence2, empty_elem='\x00')
else:
@@ -506,6 +502,24 @@
ofs = self._offset
return (self._data, start + ofs, end + ofs, ofs)
+ def descr_getitem(self, space, w_index):
+ # optimization: this version doesn't force getdata()
+ if isinstance(w_index, W_SliceObject):
+ start, stop, step, sl = w_index.indices4(space, self._len())
+ if sl == 0:
+ return self._empty()
+ elif step == 1:
+ assert start >= 0 and stop >= 0
+ ofs = self._offset
+ return self._new(self._data[start + ofs : stop + ofs])
+ else:
+ start += self._offset
+ ret = _descr_getslice_slowpath(self._data, start, step, sl)
+ return self._new_from_list(ret)
+
+ index = space.getindex_w(w_index, space.w_IndexError, self._KIND1)
+ return self._getitem_result(space, index)
+
# ____________________________________________________________
# helpers for slow paths, moved out because they contain loops
@@ -1247,21 +1261,6 @@
"attempt to assign sequence of size %d to extended slice "
"of size %d", len2, slicelength)
- if sequence2 is items:
- if step > 0:
- # Always copy starting from the right to avoid
- # having to make a shallow copy in the case where
- # the source and destination lists are the same list.
- i = len2 - 1
- start += i*step
- while i >= 0:
- items[start] = sequence2[i]
- start -= step
- i -= 1
- return
- else:
- # Make a shallow copy to more easily handle the reversal case
- sequence2 = list(sequence2)
for i in range(len2):
items[start] = sequence2[i]
start += step
diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py
--- a/pypy/objspace/std/test/test_bytearrayobject.py
+++ b/pypy/objspace/std/test/test_bytearrayobject.py
@@ -85,6 +85,7 @@
raises(IndexError, b.__getitem__, 4)
assert b[1:5] == bytearray(b'est')
assert b[slice(1,5)] == bytearray(b'est')
+ assert b[1:5:2] == bytearray(b'et')
def test_arithmetic(self):
b1 = bytearray(b'hello ')
@@ -627,3 +628,52 @@
def test_constructor_typeerror(self):
raises(TypeError, bytearray, b'', 'ascii')
raises(TypeError, bytearray, '')
+
+ def test_dont_force_offset(self):
+ def make(x=b'abcdefghij', shift=3):
+ b = bytearray(b'?'*shift + x)
+ repr(b) # force 'b'
+ del b[:shift] # add shift to b._offset
+ return b
+ assert make(shift=0).__alloc__() == 11
+ #
+ x = make(shift=3)
+ assert x.__alloc__() == 14
+ repr(x)
+ assert x.__alloc__() == 11
+ #
+ x = make(shift=3)
+ assert memoryview(x)[1] == ord('b')
+ assert x.__alloc__() == 14
+ assert len(x) == 10
+ assert x.__alloc__() == 14
+ assert x[3] == ord('d')
+ assert x[-3] == ord('h')
+ assert x.__alloc__() == 14
+ assert x[3:-3] == b'defg'
+ assert x[-3:3:-1] == b'hgfe'
+ assert x.__alloc__() == 14
+ #
+ x = make(shift=3)
+ x[3] = ord('D')
+ assert x.__alloc__() == 14
+ x[4:6] = b'EF'
+ assert x.__alloc__() == 14
+ x[6:8] = b'G'
+ assert x.__alloc__() == 13
+ x[-2:4:-2] = b'*/'
+ assert x.__alloc__() == 13
+ assert x == bytearray(b'abcDE/G*j')
+ #
+ x = make(shift=3)
+ assert x.__alloc__() == 14
+ del x[:1]
+ assert x.__alloc__() == 13
+ del x[0:5]
+ assert x.__alloc__() == 8
+ del x[0]
+ assert len(x) == 4
+ assert x.__alloc__() == 7
+ del x[1]
+ assert x.__alloc__() == 4 # forced
+ assert x == bytearray(b'gij')
More information about the pypy-commit
mailing list