[Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.56.2.8,1.56.2.9
Fred L. Drake
fdrake@weyr.cnri.reston.va.us
Wed, 16 Feb 2000 11:07:46 -0500 (EST)
Update of /projects/cvsroot/python/dist/src/Doc/api
In directory weyr:/home/fdrake/projects/python/Doc-152p1/api
Modified Files:
Tag: release152p1-patches
api.tex
Log Message:
Buffer interface documentation from Greg Stein <gstein@lyra.org>;
thanks!
Index: api.tex
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Doc/api/api.tex,v
retrieving revision 1.56.2.8
retrieving revision 1.56.2.9
diff -C2 -r1.56.2.8 -r1.56.2.9
*** api.tex 2000/02/03 18:23:34 1.56.2.8
--- api.tex 2000/02/16 16:07:43 1.56.2.9
***************
*** 1852,1858 ****
\subsection{Buffer Objects \label{bufferObjects}}
! XXX need a real description of buffers and buffer ''segments.``
\begin{cvardesc}{PyTypeObject}{PyBuffer_Type}
The instance of \ctype{PyTypeObject} which represents the Python
--- 1852,1897 ----
\subsection{Buffer Objects \label{bufferObjects}}
+ \sectionauthor{Greg Stein}{gstein@lyra.org}
! Python type objects can export a group of functions called the
! ``buffer interface.'' These functions can be used by an object to
! expose its data in a raw, byte-oriented format. Clients of the object
! can use the buffer interface to access the object data directly,
! without needing to copy it first.
!
! Two examples of objects that support
! the buffer interface are strings and arrays. The string object exposes
! the character contents in the buffer interface's byte-oriented
! form. An array can also expose its contents, but it should be noted
! that array elements may be multi-byte values.
!
! An example user of the buffer interface is the file object's
! \method{write()} method. Any object that can export a series of bytes
! through the buffer interface can be written to a file. There are a
! number of format codes to \cfunction{PyArgs_ParseTuple()} that operate
! against an object's buffer interface, returning data from the target
! object.
!
! More information on the buffer interface is provided in the section
! \ref{newTypes}, under the description for \ctype{PyBufferProcs}.
+ A ``buffer object'' is defined in the \file{bufferobject.h} header
+ (included by \file{Python.h}). These objects look very similar to
+ string objects at the Python programming level: they support slicing,
+ indexing, concatenation, and some other standard string
+ operations. However, their data can come from one of two sources: from
+ a block of memory, or from another object which exports the buffer
+ interface.
+
+ Buffer objects are useful as a way to expose the data from another
+ object's buffer interface to the Python programmer. They can also be
+ used as a zero-copy slicing mechanism. Using their ability to
+ reference a block of memory, it is possible to expose any data to the
+ Python programmer quite easily. The memory could be a large, constant
+ array in a C extension, it could be a raw block of memory for
+ manipulation before passing to an operating system library, or it
+ could be used to pass around structured data in its native, in-memory
+ format.
+
\begin{cvardesc}{PyTypeObject}{PyBuffer_Type}
The instance of \ctype{PyTypeObject} which represents the Python
***************
*** 1861,1865 ****
\begin{cvardesc}{int}{Py_END_OF_BUFFER}
! Constant returned by \cfunction{Py}
\end{cvardesc}
--- 1900,1910 ----
\begin{cvardesc}{int}{Py_END_OF_BUFFER}
! This constant may be passed as the \var{size} parameter to
! \cfunction{PyBuffer_FromObject()} or
! \cfunction{PyBuffer_FromReadWriteObject()}. It indicates that the new
! \ctype{PyBufferObject} should refer to \var{base} object from the
! specified \var{offset} to the end of its exported buffer. Using this
! enables the caller to avoid querying the \var{base} object for its
! length.
\end{cvardesc}
***************
*** 1870,1878 ****
\begin{cfuncdesc}{PyObject*}{PyBuffer_FromObject}{PyObject *base,
int offset, int size}
! Return a new read-only buffer object.
! Raises \exception{TypeError} if \var{base} doesn't support the
! read-only buffer protocol or doesn't provide exactly one buffer
! segment. Raises \exception{ValueError} if \var{offset} is less than
! zero.
\end{cfuncdesc}
--- 1915,1928 ----
\begin{cfuncdesc}{PyObject*}{PyBuffer_FromObject}{PyObject *base,
int offset, int size}
! Return a new read-only buffer object. This raises
! \exception{TypeError} if \var{base} doesn't support the read-only
! buffer protocol or doesn't provide exactly one buffer segment, or it
! raises \exception{ValueError} if \var{offset} is less than zero. The
! buffer will hold a reference to the \var{base} object, and the
! buffer's contents will refer to the \var{base} object's buffer
! interface, starting as position \var{offset} and extending for
! \var{size} bytes. If \var{size} is \constant{Py_END_OF_BUFFER}, then
! the new buffer's contents extend to the length of the \var{base}
! object's exported buffer data.
\end{cfuncdesc}
***************
*** 1882,1906 ****
Return a new writable buffer object. Parameters and exceptions are
similar to those for \cfunction{PyBuffer_FromObject()}.
\end{cfuncdesc}
\begin{cfuncdesc}{PyObject*}{PyBuffer_FromMemory}{void *ptr, int size}
! Return a new read-only buffer object that reads from a memory buffer.
The caller is responsible for ensuring that the memory buffer, passed
in as \var{ptr}, is not deallocated while the returned buffer object
exists. Raises \exception{ValueError} if \var{size} is less than
zero.
\end{cfuncdesc}
\begin{cfuncdesc}{PyObject*}{PyBuffer_FromReadWriteMemory}{void *ptr, int size}
! Return a new writable buffer object that reads from and writes to a
! memory buffer. The caller is responsible for ensuring that the memory
! buffer, passed in as \var{ptr}, is not deallocated while the returned
! buffer object exists. Raises \exception{ValueError} if \var{size} is
! less than zero.
\end{cfuncdesc}
\begin{cfuncdesc}{PyObject*}{PyBuffer_New}{int size}
Returns a new writable buffer object that maintains its own memory
! buffer of \var{size} bytes. \var{size} must be zero or positive.
\end{cfuncdesc}
--- 1932,1961 ----
Return a new writable buffer object. Parameters and exceptions are
similar to those for \cfunction{PyBuffer_FromObject()}.
+
+ If the \var{base} object does not export the writeable buffer
+ protocol, then \exception{TypeError} is raised.
\end{cfuncdesc}
\begin{cfuncdesc}{PyObject*}{PyBuffer_FromMemory}{void *ptr, int size}
! Return a new read-only buffer object that reads from a specified
! location in memory, with a specified size.
The caller is responsible for ensuring that the memory buffer, passed
in as \var{ptr}, is not deallocated while the returned buffer object
exists. Raises \exception{ValueError} if \var{size} is less than
zero.
+
+ Note that \constant{Py_END_OF_BUFFER} may \emph{not} be passed for the
+ \var{size} parameter.
\end{cfuncdesc}
\begin{cfuncdesc}{PyObject*}{PyBuffer_FromReadWriteMemory}{void *ptr, int size}
! Similar to \cfunction{PyBuffer_FromMemory()}, but the returned buffer
! is writable.
\end{cfuncdesc}
\begin{cfuncdesc}{PyObject*}{PyBuffer_New}{int size}
Returns a new writable buffer object that maintains its own memory
! buffer of \var{size} bytes. \exception{ValueError} is returned if
! \var{size} is not zero or positive.
\end{cfuncdesc}
***************
*** 2572,2577 ****
extension is imported after the interpreter has been completely
re-initialized by calling \cfunction{Py_Finalize()} and
! \cfunction{Py_Initialize()}; in that case, the extension's \code{init}
! function \emph{is} called again.
\strong{Bugs and caveats:} Because sub-interpreters (and the main
--- 2627,2632 ----
extension is imported after the interpreter has been completely
re-initialized by calling \cfunction{Py_Finalize()} and
! \cfunction{Py_Initialize()}; in that case, the extension's
! \code{init\var{module}} function \emph{is} called again.
\strong{Bugs and caveats:} Because sub-interpreters (and the main
***************
*** 3107,3114 ****
unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, intargfunc,
intintargfunc, intobjargproc, intintobjargproc, objobjargproc,
- getreadbufferproc, getsegcountproc, getcharbufferproc,
destructor, printfunc, getattrfunc, getattrofunc, setattrfunc,
setattrofunc, cmpfunc, reprfunc, hashfunc
\begin{ctypedesc}{int (*getwritebufferproc) (PyObject *self, int segment,
void **ptrptr)}
--- 3162,3172 ----
unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, intargfunc,
intintargfunc, intobjargproc, intintobjargproc, objobjargproc,
destructor, printfunc, getattrfunc, getattrofunc, setattrfunc,
setattrofunc, cmpfunc, reprfunc, hashfunc
+ \begin{ctypedesc}{int (*getreadbufferproc) (PyObject *self, int segment,
+ void **ptrptr)}
+ \end{ctypedesc}
+
\begin{ctypedesc}{int (*getwritebufferproc) (PyObject *self, int segment,
void **ptrptr)}
***************
*** 3120,3125 ****
--- 3178,3193 ----
\var{segment} specifies a segment that doesn't exist.
% Why doesn't it raise ValueError for this one?
+ % GJS: because you shouldn't be calling it with an invalid
+ % segment. That indicates a blatant programming error in the C
+ % code.
+ \end{ctypedesc}
+
+ \begin{ctypedesc}{int (*getsegcountproc) (PyObject *self, int *lenp)}
\end{ctypedesc}
+ \begin{ctypedesc}{int (*getcharbufferproc) (PyObject *self, int segment,
+ const char **ptrptr)}
+ \end{ctypedesc}
+
PyNumberMethods
***************
*** 3127,3132 ****
PyMappingMethods
! PyBufferProcs
PyTypeObject
--- 3195,3268 ----
PyMappingMethods
+
+ \begin{ctypedesc}{PyBufferProcs}
+ \code{PyBufferProcs} defines a set of slots for a Python type
+ object. These slots are used to implement the ``buffer interface.''
+
+ The buffer interface exports a model where an object can expose its
+ internal data as a set of chunks of data, each chunk 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
+ \member{tp_as_buffer} member in the \ctype{PyTypeObject} structure
+ should be \NULL{}. Otherwise, \member{tp_as_buffer} will point to a
+ \ctype{PyBufferProcs} structure.
+
+ \emph{Note:} it is very important that your \ctype{PyTypeObject}
+ structure uses \code{Py_TPFLAGS_DEFAULT} for the value of the
+ \member{tp_flags} member. This tells the Python runtime that your
+ \ctype{PyBufferProcs} structure contains the \member{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.
+
+ The first slot in the \ctype{PyBufferProcs} structure is
+ \member{bf_getreadbuffer}, which has type
+ \ctype{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. The read-buffer function is allowed
+ to raise an exception and return \code{-1}. Callers should test for
+ \NULL{} before using the slot and should check for an exception. The
+ \var{segment} which is passed must be zero or positive, and strictly less
+ than the number of segments returned by the \member{bf_getsegcount}
+ slot function.
+
+ The next slot is \member{bf_getwritebuffer} having type
+ \ctype{getwritebufferproc}. This slot may be \NULL{} if the object
+ does not allow writing into its returned buffers. If the slot function
+ is present, it is allowed to raise an exception and return \code{-1}.
+ The \var{segment} follows the same restrictions as for
+ \member{bf_getreadbuffer}.
+
+ The third slot is \member{bf_getsegcount}, with type
+ \ctype{getsegcountproc}. This slot must not be \NULL{} and is used to
+ inform the caller how many segments the object contains. Simple
+ objects such as \ctype{PyString_Type} and \ctype{PyBuffer_Type}
+ objects contain a single segment. The \var{lenp} parameter may be
+ \NULL{}. If not, then the implementation should store the total size of all
+ buffer segments into \code{*lenp}.
+
+ The last slot is \member{bf_getcharbuffer}, which has type
+ \ctype{getcharbufferproc}. This slot will only be present if the
+ \code{Py_TPFLAGS_HAVE_GETCHARBUFFER} flag is present in
+ \member{tp_flags} of the object's \ctype{PyTypeObject}. Before using
+ this slot, the caller should test whether it is present by using the
+ \cfunction{PyType_HasFeature()} macro. Assuming the slot is present,
+ then it may be \NULL{} indicating that the object's contents cannot be
+ used a \emph{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 \member{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.
+
+ \emph{Note:} the current policy seems to state that these
+ characters may be multi-byte characters. This implies that a buffer
+ size of \var{N} does not mean there are \var{N} characters present.
! \end{ctypedesc}
PyTypeObject