[pypy-commit] pypy newmemoryview-app-level: test, add a class which fills in tp_as_buffer.bf_getbuffer via __buffer__

mattip pypy.commits at gmail.com
Wed Feb 27 17:47:46 EST 2019


Author: Matti Picus <matti.picus at gmail.com>
Branch: newmemoryview-app-level
Changeset: r96190:ecee4043385d
Date: 2019-02-27 21:54 +0200
http://bitbucket.org/pypy/pypy/changeset/ecee4043385d/

Log:	test, add a class which fills in tp_as_buffer.bf_getbuffer via
	__buffer__

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
@@ -277,8 +277,8 @@
         ARRAY_CACHE[key] = cls
         return cls
 
-byteorder = {'little': '>', 'big': '<'}
-swappedorder = {'little': '<', 'big': '>'}
+byteorder = {'little': '<', 'big': '>'}
+swappedorder = {'little': '>', 'big': '<'}
 
 def get_format_str(typ):
     if hasattr(typ, '_fields_'):
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -62,11 +62,18 @@
 class PyPyDateTime(MixedModule):
     appleveldefs = {}
     interpleveldefs = {
-        'dateinterop': 'interp_pypydatetime.W_DateTime_Date',
-        'timeinterop'    : 'interp_pypydatetime.W_DateTime_Time',
-        'deltainterop'   : 'interp_pypydatetime.W_DateTime_Delta',
+        'dateinterop'  : 'interp_pypydatetime.W_DateTime_Date',
+        'timeinterop'  : 'interp_pypydatetime.W_DateTime_Time',
+        'deltainterop' : 'interp_pypydatetime.W_DateTime_Delta',
     }
 
+class PyPyBufferable(MixedModule):
+    appleveldefs = {}
+    interpleveldefs = {
+        'bufferable': 'interp_buffer.W_Bufferable',
+    }
+        
+
 class Module(MixedModule):
     """ PyPy specific "magic" functions. A lot of them are experimental and
     subject to change, many are internal. """
@@ -110,7 +117,7 @@
         'side_effects_ok'           : 'interp_magic.side_effects_ok',
         'stack_almost_full'         : 'interp_magic.stack_almost_full',
         'pyos_inputhook'            : 'interp_magic.pyos_inputhook',
-        'newmemoryview'             : 'newmemoryview.newmemoryview',
+        'newmemoryview'             : 'interp_buffer.newmemoryview',
     }
     if sys.platform == 'win32':
         interpleveldefs['get_console_cp'] = 'interp_magic.get_console_cp'
@@ -122,6 +129,7 @@
         "intop": IntOpModule,
         "os": OsModule,
         '_pypydatetime': PyPyDateTime,
+        'bufferable': PyPyBufferable,
     }
 
     def setup_after_space_initialization(self):
diff --git a/pypy/module/__pypy__/newmemoryview.py b/pypy/module/__pypy__/interp_buffer.py
rename from pypy/module/__pypy__/newmemoryview.py
rename to pypy/module/__pypy__/interp_buffer.py
--- a/pypy/module/__pypy__/newmemoryview.py
+++ b/pypy/module/__pypy__/interp_buffer.py
@@ -3,8 +3,26 @@
 #
 
 from pypy.interpreter.error import oefmt
-from pypy.interpreter.gateway import unwrap_spec
+from pypy.interpreter.gateway import unwrap_spec, interp2app
 from pypy.objspace.std.memoryobject import BufferViewND
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.typedef import TypeDef, generic_new_descr
+
+class W_Bufferable(W_Root):
+    def __init__(self, space):
+        pass
+
+    def descr_buffer(self, space, w_flags):
+        if self is W_Bufferable:
+            raise oefmt(space.w_ValueError, "override __buffer__ in a subclass")
+        return space.call_method(self, '__buffer__', w_flags)
+
+W_Bufferable.typedef = TypeDef("Bufferable",
+    __doc__ = """a helper class for a app-level class (like _ctypes.Array)
+that want to support tp_as_buffer.bf_getbuffer via a __buffer__ method""",
+    __new__ = generic_new_descr(W_Bufferable),
+    __buffer__ = interp2app(W_Bufferable.descr_buffer),
+)
 
 @unwrap_spec(itemsize=int, format='text')
 def newmemoryview(space, w_obj, itemsize, format, w_shape=None, w_strides=None):
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -29,6 +29,7 @@
 from pypy.module.__builtin__.descriptor import W_Property
 from pypy.module.__builtin__.interp_classobj import W_ClassObject
 from pypy.module.micronumpy.base import W_NDimArray
+from pypy.module.__pypy__.interp_buffer import W_Bufferable
 from rpython.rlib.entrypoint import entrypoint_lowlevel
 from rpython.rlib.rposix import FdValidator
 from rpython.rlib.unroll import unrolling_iterable
@@ -719,6 +720,7 @@
         'PyMemberDescr_Type': 'space.gettypeobject(cpyext.typeobject.W_MemberDescr.typedef)',
         'PyMethodDescr_Type': 'space.gettypeobject(cpyext.methodobject.W_PyCMethodObject.typedef)',
         'PyWrapperDescr_Type': 'space.gettypeobject(cpyext.methodobject.W_PyCWrapperObject.typedef)',
+        'PyBufferable_Type': 'space.gettypeobject(W_Bufferable.typedef)',
         }.items():
         register_global(cpyname, 'PyTypeObject*', pypyexpr, header=pypy_decl)
 
diff --git a/pypy/module/cpyext/test/test_memoryobject.py b/pypy/module/cpyext/test/test_memoryobject.py
--- a/pypy/module/cpyext/test/test_memoryobject.py
+++ b/pypy/module/cpyext/test/test_memoryobject.py
@@ -34,6 +34,21 @@
         decref(space, ref)
         decref(space, c_memoryview)
 
+    def test_class_with___buffer__(self, space, api):
+        w_obj = space.appexec([], """():
+            from __pypy__.bufferable import bufferable
+            class B(bufferable):
+                def __init__(self):
+                    self.buf = bytearray(10)
+
+                def __buffer__(self, flags):
+                    return memoryview(self.buf)
+            return B()""")
+        py_obj = make_ref(space, w_obj)
+        assert py_obj.c_ob_type.c_tp_as_buffer
+        assert py_obj.c_ob_type.c_tp_as_buffer.c_bf_getbuffer
+         
+
 class AppTestPyBuffer_FillInfo(AppTestCpythonExtensionBase):
     def test_fillWithObject(self):
         module = self.import_extension('foo', [


More information about the pypy-commit mailing list