Commit 07839df4 authored by Stefan Behnel's avatar Stefan Behnel

Support simple, non-strided views of "cython.array".

Closes https://github.com/cython/cython/issues/3775
parent 27efc541
......@@ -177,26 +177,29 @@ cdef class array:
@cname('getbuffer')
def __getbuffer__(self, Py_buffer *info, int flags):
cdef int bufmode = -1
if self.mode == u"c":
bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
elif self.mode == u"fortran":
bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
if not (flags & bufmode):
raise ValueError, "Can only create a buffer that is contiguous in memory."
if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS):
if self.mode == u"c":
bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
elif self.mode == u"fortran":
bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
if not (flags & bufmode):
raise ValueError, "Can only create a buffer that is contiguous in memory."
info.buf = self.data
info.len = self.len
info.ndim = self.ndim
info.shape = self._shape
info.strides = self._strides
info.suboffsets = NULL
info.itemsize = self.itemsize
info.readonly = 0
if flags & PyBUF_FORMAT:
info.format = self.format
if flags & PyBUF_STRIDES:
info.ndim = self.ndim
info.shape = self._shape
info.strides = self._strides
else:
info.format = NULL
info.ndim = 1
info.shape = &self.len if flags & PyBUF_ND else NULL
info.strides = NULL
info.suboffsets = NULL
info.itemsize = self.itemsize
info.readonly = 0
info.format = self.format if flags & PyBUF_FORMAT else NULL
info.obj = self
__pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
......
......@@ -217,3 +217,72 @@ class InheritFrom(v.array):
>>> inst = InheritFrom(shape=(3, 3, 3), itemsize=4, format="i")
"""
pass
def test_char_array_in_python_api(*shape):
"""
>>> import sys
>>> if sys.version_info[0] < 3:
... def bytes(b): return memoryview(b).tobytes() # don't call str()
>>> arr1d = test_char_array_in_python_api(10)
>>> print(bytes(arr1d).decode('ascii'))
xxxxxxxxxx
>>> len(bytes(arr1d))
10
>>> arr2d = test_char_array_in_python_api(10, 2)
>>> print(bytes(arr2d).decode('ascii'))
xxxxxxxxxxxxxxxxxxxx
>>> len(bytes(arr2d))
20
# memoryview
>>> len(bytes(memoryview(arr1d)))
10
>>> bytes(memoryview(arr1d)) == bytes(arr1d)
True
>>> len(bytes(memoryview(arr2d)))
20
>>> bytes(memoryview(arr2d)) == bytes(arr2d)
True
# BytesIO
>>> from io import BytesIO
>>> BytesIO(arr1d).read() == bytes(arr1d)
True
>>> BytesIO(arr2d).read() == bytes(arr2d)
True
>>> b = BytesIO()
>>> print(b.write(arr1d))
10
>>> b.getvalue() == bytes(arr1d) or b.getvalue()
True
>>> b = BytesIO()
>>> print(b.write(arr2d))
20
>>> b.getvalue() == bytes(arr2d) or b.getvalue()
True
# BufferedWriter (uses PyBUF_SIMPLE, see https://github.com/cython/cython/issues/3775)
>>> from io import BufferedWriter
>>> b = BytesIO()
>>> bw = BufferedWriter(b)
>>> print(bw.write(arr1d))
10
>>> bw.flush()
>>> b.getvalue() == bytes(arr1d)
True
>>> b = BytesIO()
>>> bw = BufferedWriter(b)
>>> print(bw.write(arr2d))
20
>>> bw.flush()
>>> b.getvalue() == bytes(arr2d)
True
"""
arr = array(shape=shape, itemsize=sizeof(char), format='c', mode='c')
arr[:] = b'x'
return arr
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment