[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