[pypy-svn] pypy default: (mfoord) implement bytearray extended slice assignment and remove bytearray.__delslice__
mfoord
commits-noreply at bitbucket.org
Tue Jan 18 11:36:16 CET 2011
Author: Michael Foord <michael at voidspace.org.uk>
Branch:
Changeset: r40838:aa1bec94c139
Date: 2011-01-18 11:35 +0100
http://bitbucket.org/pypy/pypy/changeset/aa1bec94c139/
Log: (mfoord) implement bytearray extended slice assignment and remove
bytearray.__delslice__
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -93,7 +93,10 @@
def setslice__List_ANY_ANY_ANY(space, w_list, w_start, w_stop, w_sequence):
length = len(w_list.wrappeditems)
start, stop = normalize_simple_slice(space, length, w_start, w_stop)
- _setitem_slice_helper(space, w_list, start, 1, stop-start, w_sequence)
+
+ sequence2 = space.listview(w_sequence)
+ items = w_list.wrappeditems
+ _setitem_slice_helper(space, items, start, 1, stop-start, sequence2)
def delslice__List_ANY_ANY(space, w_list, w_start, w_stop):
length = len(w_list.wrappeditems)
@@ -259,12 +262,13 @@
def setitem__List_Slice_ANY(space, w_list, w_slice, w_iterable):
oldsize = len(w_list.wrappeditems)
start, stop, step, slicelength = w_slice.indices4(space, oldsize)
- _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable)
-def _setitem_slice_helper(space, w_list, start, step, slicelength, w_iterable):
sequence2 = space.listview(w_iterable)
+ items = w_list.wrappeditems
+ _setitem_slice_helper(space, items, start, step, slicelength, sequence2)
+
+def _setitem_slice_helper(space, items, start, step, slicelength, sequence2):
assert slicelength >= 0
- items = w_list.wrappeditems
oldsize = len(items)
len2 = len(sequence2)
if step == 1: # Support list resizing for non-extended slices
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 pypy.rlib.rarithmetic import intmask
from pypy.rlib.rstring import StringBuilder
from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.listobject import _delitem_slice_helper
+from pypy.objspace.std.listobject import _delitem_slice_helper, _setitem_slice_helper
from pypy.objspace.std.listtype import get_list_index
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import W_UnicodeObject
@@ -391,13 +391,6 @@
list_extend__Bytearray_ANY(space, w_bytearray1, w_iterable2)
return w_bytearray1
-def delslice__Bytearray_ANY_ANY(space, w_bytearray, w_start, w_stop):
- length = len(w_bytearray.data)
- start, stop = normalize_simple_slice(space, length, w_start, w_stop)
- if start == stop:
- return
- del w_bytearray.data[start:stop]
-
def setitem__Bytearray_ANY_ANY(space, w_bytearray, w_index, w_item):
from pypy.objspace.std.bytearraytype import getbytevalue
idx = space.getindex_w(w_index, space.w_IndexError, "bytearray index")
@@ -410,11 +403,8 @@
def setitem__Bytearray_Slice_ANY(space, w_bytearray, w_slice, w_other):
oldsize = len(w_bytearray.data)
start, stop, step, slicelength = w_slice.indices4(space, oldsize)
- if step != 1:
- raise OperationError(space.w_NotImplementedError,
- space.wrap("fixme: only step=1 for the moment"))
- _setitem_helper(w_bytearray, start, stop, slicelength,
- space.str_w(w_other))
+ sequence2 = makebytearraydata_w(space, w_other)
+ setitem_slice_helper(space, w_bytearray.data, start, step, slicelength, sequence2)
def delitem__Bytearray_ANY(space, w_bytearray, w_idx):
idx = get_list_index(space, w_idx)
@@ -430,32 +420,11 @@
len(w_bytearray.data))
delitem_slice_helper(space, w_bytearray.data, start, step, slicelength)
-# create new helper function with different list type specialisation
+# create new helper functions with different list type specialisation
delitem_slice_helper = func_with_new_name(_delitem_slice_helper,
'delitem_slice_helper')
-
-def _setitem_helper(w_bytearray, start, stop, slicelength, data):
- assert start >= 0
- assert stop >= 0
- step = 1
- len2 = len(data)
- delta = slicelength - len2
- if delta < 0:
- delta = -delta
- newsize = len(w_bytearray.data) + delta
- w_bytearray.data += ['\0'] * delta
- lim = start + len2
- i = newsize - 1
- while i >= lim:
- w_bytearray.data[i] = w_bytearray.data[i-delta]
- i -= 1
- elif start >= 0:
- del w_bytearray.data[start:start+delta]
- else:
- assert delta == 0
- for i in range(len2):
- w_bytearray.data[start] = data[i]
- start += step
+setitem_slice_helper = func_with_new_name(_setitem_slice_helper,
+ 'setitem_slice_helper')
# __________________________________________________________
# Buffer interface
diff --git a/pypy/objspace/std/test/test_bytes.py b/pypy/objspace/std/test/test_bytes.py
--- a/pypy/objspace/std/test/test_bytes.py
+++ b/pypy/objspace/std/test/test_bytes.py
@@ -216,6 +216,19 @@
raises(TypeError, b.extend, [object()])
raises(TypeError, b.extend, u"unicode")
+ def test_setslice(self):
+ b = bytearray('hello')
+ b[:] = [ord(c) for c in 'world']
+ assert b == bytearray('world')
+
+ b = bytearray('hello world')
+ b[::2] = 'bogoff'
+ assert b == bytearray('beolg ooflf')
+
+ def set_wrong_size():
+ b[::2] = 'foo'
+ raises(ValueError, set_wrong_size)
+
def test_delslice(self):
b = bytearray('abcdefghi')
del b[5:8]
More information about the Pypy-commit
mailing list