[pypy-commit] pypy newmemoryview-app-level: handle memoryview of basic ctype arrays Pointers and Structures

mattip pypy.commits at gmail.com
Mon Mar 4 08:11:21 EST 2019


Author: Matti Picus <matti.picus at gmail.com>
Branch: newmemoryview-app-level
Changeset: r96207:1c89b5e95a50
Date: 2019-03-04 15:07 +0200
http://bitbucket.org/pypy/pypy/changeset/1c89b5e95a50/

Log:	handle memoryview of basic ctype arrays Pointers and Structures

diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py
--- a/lib_pypy/_ctypes/array.py
+++ b/lib_pypy/_ctypes/array.py
@@ -4,7 +4,7 @@
 from _ctypes.basics import _CData, cdata_from_address, _CDataMeta, sizeof
 from _ctypes.basics import keepalive_key, store_reference, ensure_objects
 from _ctypes.basics import CArgObject, as_ffi_pointer
-import sys, __pypy__
+import sys, __pypy__, struct
 
 class ArrayMeta(_CDataMeta):
     def __new__(self, name, cls, typedict):
@@ -252,9 +252,12 @@
             except AttributeError:
                 break
             obj = obj[0]
-        
+
         fmt = get_format_str(obj._type_)
-        itemsize = len(memoryview(obj[0]))
+        try:
+            itemsize = struct.calcsize(fmt[1:])
+        except:
+            itemsize = len(memoryview(obj[0]))
         return __pypy__.newmemoryview(memoryview(self._buffer), itemsize, fmt, shape)
 
 ARRAY_CACHE = {}
@@ -288,7 +291,8 @@
             bo = byteorder[sys.byteorder]
         flds = []
         for name, obj in typ._fields_:
-            ch = get_format_str(obj)
+            # Trim off the leading '<' or '>'
+            ch = get_format_str(obj)[1:]
             if (ch) == 'B':
                 flds.append(byteorder[sys.byteorder])
             else:
@@ -299,6 +303,7 @@
             flds.append(':')
         return 'T{' + ''.join(flds) + '}'
     elif hasattr(typ, '_type_'):
-        return typ._type_
+        ch = typ._type_
+        return byteorder[sys.byteorder] + ch
     else:
         raise ValueError('cannot get format string for %r' % typ)
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -7,8 +7,7 @@
 from _ctypes.array import Array, array_get_slice_params, array_slice_getitem,\
      array_slice_setitem
 
-try: from __pypy__ import builtinify
-except ImportError: builtinify = lambda f: f
+from __pypy__ import builtinify, newmemoryview
 
 # This cache maps types to pointers to them.
 _pointer_type_cache = {}
@@ -135,6 +134,9 @@
     def _as_ffi_pointer_(self, ffitype):
         return as_ffi_pointer(self, ffitype)
 
+    def __buffer__(self, flags):
+        mv = memoryview(self.getcontents())
+        return newmemoryview(mv, mv.itemsize, '&' + mv.format, mv.shape)
 
 def _cast_addr(obj, _, tp):
     if not (isinstance(tp, _CDataMeta) and tp._is_pointer_like()):
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -2,9 +2,9 @@
 import _rawffi
 from _ctypes.basics import _CData, _CDataMeta, keepalive_key,\
      store_reference, ensure_objects, CArgObject
-from _ctypes.array import Array
+from _ctypes.array import Array, get_format_str
 from _ctypes.pointer import _Pointer
-import inspect
+import inspect, __pypy__
 
 
 def names_and_fields(self, _fields_, superclass, anonymous_fields=None):
@@ -299,6 +299,10 @@
     def _to_ffi_param(self):
         return self._buffer
 
+    def __buffer__(self, flags):
+        fmt = get_format_str(self)
+        itemsize = type(self)._sizeofinstances() 
+        return __pypy__.newmemoryview(memoryview(self._buffer), itemsize, fmt)
 
 class StructureMeta(StructOrUnionMeta):
     _is_union = False


More information about the pypy-commit mailing list