10.6 Buffer Object Structures

The buffer interface exports a model where an object can expose its internal data as a set of chunks of data, where each chunk is specified as a pointer/length pair. These chunks are called segments and are presumed to be non-contiguous in memory.

If an object does not export the buffer interface, then its tp_as_buffer member in the PyTypeObject structure should be NULL. Otherwise, the tp_as_buffer will point to a PyBufferProcs structure.

Note: It is very important that your PyTypeObject structure uses Py_TPFLAGS_DEFAULT for the value of the tp_flags member rather than 0. This tells the Python runtime that your PyBufferProcs structure contains the bf_getcharbuffer slot. Older versions of Python did not have this member, so a new Python interpreter using an old extension needs to be able to test for its presence before using it.

PyBufferProcs
Structure used to hold the function pointers which define an implementation of the buffer protocol.

The first slot is bf_getreadbuffer, of type getreadbufferproc. If this slot is NULL, then the object does not support reading from the internal data. This is non-sensical, so implementors should fill this in, but callers should test that the slot contains a non-NULL value.

The next slot is bf_getwritebuffer having type getwritebufferproc. This slot may be NULL if the object does not allow writing into its returned buffers.

The third slot is bf_getsegcount, with type getsegcountproc. This slot must not be NULL and is used to inform the caller how many segments the object contains. Simple objects such as PyString_Type and PyBuffer_Type objects contain a single segment.

The last slot is bf_getcharbuffer, of type getcharbufferproc. This slot will only be present if the Py_TPFLAGS_HAVE_GETCHARBUFFER flag is present in the tp_flags field of the object's PyTypeObject. Before using this slot, the caller should test whether it is present by using the PyType_HasFeature()  function. If present, it may be NULL, indicating that the object's contents cannot be used as 8-bit characters. The slot function may also raise an error if the object's contents cannot be interpreted as 8-bit characters. For example, if the object is an array which is configured to hold floating point values, an exception may be raised if a caller attempts to use bf_getcharbuffer to fetch a sequence of 8-bit characters. This notion of exporting the internal buffers as ``text'' is used to distinguish between objects that are binary in nature, and those which have character-based content.

Note: The current policy seems to state that these characters may be multi-byte characters. This implies that a buffer size of N does not mean there are N characters present.

Py_TPFLAGS_HAVE_GETCHARBUFFER
Flag bit set in the type structure to indicate that the bf_getcharbuffer slot is known. This being set does not indicate that the object supports the buffer interface or that the bf_getcharbuffer slot is non-NULL.

int (*getreadbufferproc) (PyObject *self, int segment, void **ptrptr)
Return a pointer to a readable segment of the buffer. This function is allowed to raise an exception, in which case it must return -1. The segment which is passed must be zero or positive, and strictly less than the number of segments returned by the bf_getsegcount slot function. On success, it returns the length of the buffer memory, and sets *ptrptr to a pointer to that memory.

int (*getwritebufferproc) (PyObject *self, int segment, void **ptrptr)
Return a pointer to a writable memory buffer in *ptrptr, and the length of that segment as the function return value. The memory buffer must correspond to buffer segment segment. Must return -1 and set an exception on error. TypeError should be raised if the object only supports read-only buffers, and SystemError should be raised when segment specifies a segment that doesn't exist.

int (*getsegcountproc) (PyObject *self, int *lenp)
Return the number of memory segments which comprise the buffer. If lenp is not NULL, the implementation must report the sum of the sizes (in bytes) of all segments in *lenp. The function cannot fail.

int (*getcharbufferproc) (PyObject *self, int segment, const char **ptrptr)

See About this document... for information on suggesting changes.