[pypy-commit] pypy PyBuffer: Add .value_from_bytes() and .bytes_from_value() to PyBuffer

rlamy pypy.commits at gmail.com
Wed Apr 12 23:36:51 EDT 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: PyBuffer
Changeset: r91051:4c5c68bbefa0
Date: 2017-04-13 04:36 +0100
http://bitbucket.org/pypy/pypy/changeset/4c5c68bbefa0/

Log:	Add .value_from_bytes() and .bytes_from_value() to PyBuffer

diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
--- a/pypy/interpreter/buffer.py
+++ b/pypy/interpreter/buffer.py
@@ -50,6 +50,25 @@
     def releasebuffer(self):
         pass
 
+    def value_from_bytes(self, space, s):
+        from pypy.module.struct.formatiterator import UnpackFormatIterator
+        buf = StringBuffer(s)
+        fmtiter = UnpackFormatIterator(space, buf)
+        fmtiter.interpret(self.getformat())
+        return fmtiter.result_w[0]
+
+    def bytes_from_value(self, space, w_val):
+        from pypy.module.struct.formatiterator import PackFormatIterator
+        itemsize = self.getitemsize()
+        fmtiter = PackFormatIterator(space, [w_val], itemsize)
+        try:
+            fmtiter.interpret(self.getformat())
+        except StructError as e:
+            raise oefmt(space.w_TypeError,
+                        "memoryview: invalid type for format '%s'",
+                        self.getformat())
+        return fmtiter.result.build()
+
     def _copy_buffer(self):
         if self.getndim() == 0:
             itemsize = self.getitemsize()
@@ -102,37 +121,18 @@
 
 
     def w_getitem(self, space, idx):
-        from pypy.module.struct.formatiterator import UnpackFormatIterator
         offset = self.get_offset(space, 0, idx)
         itemsize = self.getitemsize()
-        if itemsize == 1:
-            ch = self.as_binary()[offset]
-            return space.newint(ord(ch))
-        else:
-            # TODO: this probably isn't very fast
-            buf = SubBuffer(self.as_binary(), offset, itemsize)
-            fmtiter = UnpackFormatIterator(space, buf)
-            fmtiter.length = buf.getlength()
-            fmtiter.interpret(self.getformat())
-            return fmtiter.result_w[0]
+        # TODO: this probably isn't very fast
+        data = self.getbytes(offset, offset + itemsize, 1, itemsize)
+        return self.value_from_bytes(space, data)
 
     def setitem_w(self, space, idx, w_obj):
-        from pypy.module.struct.formatiterator import PackFormatIterator
         offset = self.get_offset(space, 0, idx)
         itemsize = self.getitemsize()
-        if itemsize == 1:
-            self.as_binary()[offset] = space.byte_w(w_obj)
-        else:
-            # TODO: this probably isn't very fast
-            fmtiter = PackFormatIterator(space, [w_obj], itemsize)
-            try:
-                fmtiter.interpret(self.getformat())
-            except StructError as e:
-                raise oefmt(space.w_TypeError,
-                            "memoryview: invalid type for format '%s'",
-                            self.getformat())
-            byteval = fmtiter.result.build()
-            self.setbytes(offset, byteval)
+        # TODO: this probably isn't very fast
+        byteval = self.bytes_from_value(space, w_obj)
+        self.setbytes(offset, byteval)
 
     def w_tolist(self, space):
         dim = self.getndim()
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
@@ -9,7 +9,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.module.struct.formatiterator import UnpackFormatIterator, PackFormatIterator
+from pypy.module.struct.formatiterator import UnpackFormatIterator
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rlib.objectmodel import always_inline
 
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
@@ -331,8 +331,8 @@
     def getformat(self):
         return self.format
 
-    def getitem(self, index):
-        return self.data[index:index+1]
+    def getbytes(self, start, stop, step, size):
+        return self.data[start:stop]
 
     def getlength(self):
         return len(self.data)
@@ -408,11 +408,6 @@
         empty = self.MockArray([], dim=1, fmt='i', size=4, strides=[1], shape=[1])
         view = memoryview(empty)
         raises(TypeError, "view.cast('l')")
-        try:
-            view.cast('l')
-            assert False, "i -> l not possible. buffer must be byte format"
-        except TypeError:
-            pass
 
     def test_cast_empty(self):
         empty = self.MockArray([], dim=1, fmt='b', size=1, strides=[1], shape=[1])


More information about the pypy-commit mailing list