Author: Matti Picus <matti.pi...@gmail.com> Branch: Changeset: r86972:fe0add22fd7e Date: 2016-09-09 12:37 +0300 http://bitbucket.org/pypy/pypy/changeset/fe0add22fd7e/
Log: test, fix Py_buffer format, which can be a string (issue #2396 and IRC discussion) 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 @@ -119,7 +119,7 @@ constant_names = """ Py_TPFLAGS_READY Py_TPFLAGS_READYING Py_TPFLAGS_HAVE_GETCHARBUFFER -METH_COEXIST METH_STATIC METH_CLASS Py_TPFLAGS_BASETYPE +METH_COEXIST METH_STATIC METH_CLASS Py_TPFLAGS_BASETYPE Py_MAX_FMT METH_NOARGS METH_VARARGS METH_KEYWORDS METH_O Py_TPFLAGS_HAVE_INPLACEOPS Py_TPFLAGS_HEAPTYPE Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_HAVE_NEWBUFFER Py_LT Py_LE Py_EQ Py_NE Py_GT Py_GE Py_TPFLAGS_CHECKTYPES Py_MAX_NDIMS @@ -645,7 +645,7 @@ ('format', rffi.CCHARP), ('shape', Py_ssize_tP), ('strides', Py_ssize_tP), - ('_format', rffi.UCHAR), + ('_format', rffi.CFixedArray(rffi.UCHAR, Py_MAX_FMT)), ('_shape', rffi.CFixedArray(Py_ssize_t, Py_MAX_NDIMS)), ('_strides', rffi.CFixedArray(Py_ssize_t, Py_MAX_NDIMS)), ('suboffsets', Py_ssize_tP), diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h --- a/pypy/module/cpyext/include/object.h +++ b/pypy/module/cpyext/include/object.h @@ -144,6 +144,7 @@ /* Py3k buffer interface, adapted for PyPy */ #define Py_MAX_NDIMS 32 +#define Py_MAX_FMT 5 typedef struct bufferinfo { void *buf; PyObject *obj; /* owned reference */ @@ -158,7 +159,7 @@ Py_ssize_t *shape; Py_ssize_t *strides; Py_ssize_t *suboffsets; /* alway NULL for app-level objects*/ - unsigned char _format; + unsigned char _format[Py_MAX_FMT]; Py_ssize_t _strides[Py_MAX_NDIMS]; Py_ssize_t _shape[Py_MAX_NDIMS]; /* static store for shape and strides of diff --git a/pypy/module/cpyext/memoryobject.py b/pypy/module/cpyext/memoryobject.py --- a/pypy/module/cpyext/memoryobject.py +++ b/pypy/module/cpyext/memoryobject.py @@ -1,5 +1,5 @@ from pypy.module.cpyext.api import (cpython_api, Py_buffer, CANNOT_FAIL, - Py_MAX_NDIMS, build_type_checkers, Py_ssize_tP) + Py_MAX_FMT, Py_MAX_NDIMS, build_type_checkers, Py_ssize_tP) from pypy.module.cpyext.pyobject import PyObject, make_ref, incref from rpython.rtyper.lltypesystem import lltype, rffi from pypy.objspace.std.memoryobject import W_MemoryView @@ -41,10 +41,22 @@ view.c_len = w_obj.getlength() view.c_itemsize = w_obj.buf.getitemsize() rffi.setintfield(view, 'c_ndim', ndim) - view.c__format = rffi.cast(rffi.UCHAR, w_obj.buf.getformat()) view.c_format = rffi.cast(rffi.CCHARP, view.c__format) view.c_shape = rffi.cast(Py_ssize_tP, view.c__shape) view.c_strides = rffi.cast(Py_ssize_tP, view.c__strides) + fmt = w_obj.buf.getformat() + n = Py_MAX_FMT - 1 # NULL terminated buffer + if len(fmt) > n: + ### WARN? + pass + else: + n = len(fmt) + for i in range(n): + if ord(fmt[i]) > 255: + view.c_format[i] = '*' + else: + view.c_format[i] = fmt[i] + view.c_format[n] = '\x00' shape = w_obj.buf.getshape() strides = w_obj.buf.getstrides() for i in range(ndim): diff --git a/pypy/module/cpyext/test/test_api.py b/pypy/module/cpyext/test/test_api.py --- a/pypy/module/cpyext/test/test_api.py +++ b/pypy/module/cpyext/test/test_api.py @@ -1,5 +1,5 @@ import py, pytest -from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rtyper.lltypesystem import lltype from pypy.interpreter.baseobjspace import W_Root from pypy.module.cpyext.state import State from pypy.module.cpyext import api diff --git a/pypy/module/cpyext/test/test_bufferobject.py b/pypy/module/cpyext/test/test_bufferobject.py --- a/pypy/module/cpyext/test/test_bufferobject.py +++ b/pypy/module/cpyext/test/test_bufferobject.py @@ -1,4 +1,4 @@ -from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rtyper.lltypesystem import lltype from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase from pypy.module.cpyext.api import PyObject 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 @@ -1,3 +1,4 @@ +from rpython.rtyper.lltypesystem import rffi from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase from rpython.rlib.buffer import StringBuffer @@ -16,8 +17,12 @@ w_buf = space.newbuffer(StringBuffer("hello")) w_memoryview = api.PyMemoryView_FromObject(w_buf) w_view = api.PyMemoryView_GET_BUFFER(w_memoryview) - ndim = w_view.c_ndim - assert ndim == 1 + assert w_view.c_ndim == 1 + f = rffi.charp2str(w_view.c_format) + assert f == 'B' + assert w_view.c_shape[0] == 5 + assert w_view.c_strides[0] == 1 + assert w_view.c_len == 5 class AppTestBufferProtocol(AppTestCpythonExtensionBase): def test_buffer_protocol(self): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit