[Python-Dev] PEP 3118: Extended buffer protocol (new version)

Lisandro Dalcin dalcinl at gmail.com
Thu Apr 12 02:21:57 CEST 2007

On 4/9/07, Travis Oliphant <oliphant.travis at ieee.org> wrote:

Travis, all this is far better and simpler than previous approaches...
Just a few comments

> The bufferinfo structure is::
>   struct bufferinfo {
>        void *buf;
>        Py_ssize_t len;
>        int readonly;
>        char *format;
>        int ndims;
>        Py_ssize_t *shape;
>        Py_ssize_t *strides;
>        Py_ssize_t *suboffsets;
>        void *internal;
>   };

1) I assume that 'bufferinfo' structure will be part of public Python
API. In such a case, I think it should be renamed and prefixed.
Something like 'PyBufferInfo' sounds good?

2) I also think 'bufferinfo' could also have an 'itemsize' field
filled if Py_BUF_ITEMSIZE flag is passed. What do you think? Exporters
can possibly fill this field more efficiently than next parsing
'format' string, it can also save consumers from an API call.

3) It does make sense to make 'format' be 'const char *' ?

4) I am not sure about this, but perhaps 'buferingo' should save the
flags passed to 'getbuffer' in a 'flags' field. This can be possibly
needed at 'releasebuffer' call.

>   typedef struct {
>       PyObject_HEAD
>       PyObject *base;
>       struct bufferinfo view;
>       int itemsize;
>       int flags;
>   } PyMemoryViewObject;

5) If my previous comments go in, so 'PyMemoryViewObject' will not
need 'itemsize' and 'flags' fields (they are in 'bufferinfo'

6) Perhaps 'view' field can be renamed to 'info'.

>     int PyObject_SizeFromFormat(char *)

7) Why not 'const char *' here?

>     int PyObject_GetContiguous(PyObject *obj, void **buf, Py_ssize_t *len,
>                                int fortran)
> Return a contiguous chunk of memory representing the buffer.  If a
> copy is made then return 1.  If no copy was needed return 0.

8) If a copy was made, What should consumers call to free memory?

> If the object is multi-dimensional, then if
> fortran is 1, the first dimension of the underlying array will vary
> the fastest in the buffer.  If fortran is 0, then the last dimension
> will vary the fastest (C-style contiguous). If fortran is -1, then it
> does not matter and you will get whatever the object decides is more
> efficient.

9) What about using a char, like 'c' or 'C', and 'f' or 'F', and 0 or
'a' or 'A' (any) ?

>     int PyObject_CopyToObject(PyObject *obj, void *buf, Py_ssize_t len,
>                               int fortran)

10) Better name? Perhaps PyObject_CopyBuffer or PyObject_CopyMemory?

>     int PyObject_SizeFromFormat(char *)
>     int PyObject_IsContiguous(struct bufferinfo *view, int fortran);
>     void PyObject_FillContiguousStrides(int *ndims, Py_ssize_t *shape,
>                                         int itemsize,
>                                         Py_ssize_t *strides, int fortran)
>     int PyObject_FillBufferInfo(struct bufferinfo *view, void *buf, Py_ssize_t len,
>                                  int readonly, int infoflags)

11) Perhaps the 'PyObject_' prefix is wrong, as those functions does
not operate with Python objects.


Lisandro Dalcín
Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC)
Instituto de Desarrollo Tecnológico para la Industria Química (INTEC)
Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET)
PTLC - Güemes 3450, (3000) Santa Fe, Argentina
Tel/Fax: +54-(0)342-451.1594

More information about the Python-Dev mailing list