[pypy-commit] pypy py3k: memoryview.setitem()

arigo pypy.commits at gmail.com
Sat Aug 27 04:02:57 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: py3k
Changeset: r86591:8c171091c731
Date: 2016-08-27 10:02 +0200
http://bitbucket.org/pypy/pypy/changeset/8c171091c731/

Log:	memoryview.setitem()

diff --git a/pypy/objspace/std/memoryobject.py b/pypy/objspace/std/memoryobject.py
--- a/pypy/objspace/std/memoryobject.py
+++ b/pypy/objspace/std/memoryobject.py
@@ -10,6 +10,7 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import interp2app
 from pypy.interpreter.typedef import TypeDef, GetSetProperty,  make_weakref_descr
+from pypy.objspace.std.bytesobject import getbytevalue
 from pypy.module.struct.formatiterator import UnpackFormatIterator, PackFormatIterator
 
 
@@ -106,35 +107,32 @@
         if self.buf.readonly:
             raise oefmt(space.w_TypeError, "cannot modify read-only memory")
         if space.isinstance_w(w_index, space.w_tuple):
-            raise oefmt(space.w_NotImplementedError, "")
+            raise oefmt(space.w_NotImplementedError, "XXX tuple setitem")
         start, stop, step, size = space.decode_index4(w_index, self.getlength())
         itemsize = self.itemsize
-        if itemsize > 1:
-            start *= itemsize
-            size *= itemsize
-            stop  = start + size
-            if step == 0:
-                step = 1
-            if stop > self.getlength():
-                raise oefmt(space.w_IndexError, 'index out of range')
         if step == 0:  # index only
-            # TODO: this probably isn't very fast
-            fmtiter = PackFormatIterator(space, [w_obj], self.itemsize)
-            try:
-                fmtiter.interpret(self.format)
-            except StructError as e:
-                raise oefmt(space.w_TypeError,
-                            "memoryview: invalid type for format '%s'",
-                            self.format)
-            self.buf.setslice(start, fmtiter.result.build())
+            if itemsize == 1:
+                ch = getbytevalue(space, w_obj)
+                self.buf.setitem(start, ch)
+            else:
+                # TODO: this probably isn't very fast
+                fmtiter = PackFormatIterator(space, [w_obj], itemsize)
+                try:
+                    fmtiter.interpret(self.format)
+                except StructError as e:
+                    raise oefmt(space.w_TypeError,
+                                "memoryview: invalid type for format '%s'",
+                                self.format)
+                self.buf.setslice(start * itemsize, fmtiter.result.build())
         elif step == 1:
             value = space.buffer_w(w_obj, space.BUF_CONTIG_RO)
             if value.getlength() != size * self.itemsize:
                 raise oefmt(space.w_ValueError,
                             "cannot modify size of memoryview object")
-            self.buf.setslice(start, value.as_str())
+            self.buf.setslice(start * itemsize, value.as_str())
         else:
-            raise oefmt(space.w_NotImplementedError, "")
+            raise oefmt(space.w_NotImplementedError,
+                        "XXX extended slicing")
 
     def descr_len(self, space):
         self._check_released(space)
diff --git a/pypy/objspace/std/test/test_memoryobject.py b/pypy/objspace/std/test/test_memoryobject.py
--- a/pypy/objspace/std/test/test_memoryobject.py
+++ b/pypy/objspace/std/test/test_memoryobject.py
@@ -196,3 +196,21 @@
         assert m3[1::2].tobytes() == b'cdgh'
         assert m3[::2].tobytes() == b'abef'
         assert m3[:2:2].tobytes() == b'ab'
+
+    def test_memoryview_cast_setitem(self):
+        data = bytearray(b'abcdefgh')
+        m1 = memoryview(data)
+        m2 = m1.cast('I')
+        m3 = m1.cast('h')
+        m1[2] = ord(b'C')
+        assert m2[0] == 1682137697
+        m3[1] = -9999
+        assert data == bytearray(bytes([97, 98, 241, 216, 101, 102, 103, 104]))
+        m3[1:3] = memoryview(b"pqrs").cast('h')
+        assert data == bytearray(b'abpqrsgh')
+
+    def test_memoryview_cast_setitem_extended_slicing(self):
+        data = bytearray(b'abcdefghij')
+        m3 = memoryview(data).cast('h')
+        m3[1:5:2] = memoryview(b"xyXY").cast('h')
+        assert data == bytearray(b'abxyefXYij')


More information about the pypy-commit mailing list