[pypy-commit] pypy default: test, fix Py_buffer format, which can be a string (issue #2396 and IRC discussion)
mattip
pypy.commits at gmail.com
Fri Sep 9 08:40:35 EDT 2016
Author: Matti Picus <matti.picus at 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):
More information about the pypy-commit
mailing list