[Python-checkins] r56793 - peps/trunk/pep-3118.txt

travis.oliphant python-checkins at python.org
Tue Aug 7 07:48:33 CEST 2007


Author: travis.oliphant
Date: Tue Aug  7 07:48:32 2007
New Revision: 56793

Modified:
   peps/trunk/pep-3118.txt
Log:
A few changes to PEP 3118 prompted by its implementation

Modified: peps/trunk/pep-3118.txt
==============================================================================
--- peps/trunk/pep-3118.txt	(original)
+++ peps/trunk/pep-3118.txt	Tue Aug  7 07:48:32 2007
@@ -175,7 +175,8 @@
 simpler view of its memory.
 
 The exporter should always fill in all elements of the buffer
-structure (with defaults if nothing else is requested).  
+structure (with defaults or NULLs if nothing else is requested). The
+PyBuffer_FillInfo function can be used for simple cases.
 
 Some flags are useful for requesting a specific kind of memory
 segment, while others indicate to the exporter what kind of
@@ -201,9 +202,10 @@
 
    The returned buffer must be readonly.  If the object is already
    read-only or it can make its memory read-only (and there are no
-   other views on the object) then it should do so and return the
-   buffer information.  If the object does not have read-only memory
-   (or cannot make it read-only), then an error should be raised.
+   other writeable views on the object) then it should do so and
+   return the buffer information.  If the object does not have
+   read-only memory (or cannot make it read-only), then an error
+   should be raised.
 
 ``PyBUF_REQ_FORMAT``
         
@@ -214,25 +216,21 @@
    format is not explicitly requested then the format must be returned
    as ``NULL`` (which means "B")
 
-``PyBUF_REQ_ALIGNED`` (implies ``PyBUF_REQ_FORMAT``)
-
-   The returned buffer must have all (primitive data-type entries)
-   aligned as the compiler would align them
-
 ``PyBUF_ALW_ND``
 
    The returned buffer must provide shape information. The memory will
    be assumed C-style contiguous (last dimension varies the fastest).
    The exporter may raise an error if it cannot provide this kind of
-   contiguous buffer. 
+   contiguous buffer.  If this is not given then shape will be NULL.
    
 ``PyBUF_ALW_STRIDES`` (implies ``PyBUF_ALW_ND``)
 
-   The returned buffer must provide strides information. This would be
-   used when the consumer can handle strided, discontiguous arrays. 
-   Handling strides automatically assumes you can handle shape. 
-   The exporter may raise an error if cannot provide a strided-only
-   representation of the data (i.e. without the suboffsets). 
+   The returned buffer must provide strides information (i.e. the
+   strides cannot be NULL).  This would be used when the consumer can
+   handle strided, discontiguous arrays. Handling strides
+   automatically assumes you can handle shape. The exporter may raise
+   an error if cannot provide a strided-only representation of the
+   data (i.e. without the suboffsets).
 
 | ``PyBUF_REQ_C_CONTIGUOUS``
 | ``PyBUF_REQ_F_CONTIGUOUS``
@@ -247,24 +245,25 @@
 
 ``PyBUF_ALW_INDIRECT`` (implies ``PyBUF_ALW_STRIDES``)
 
-   The returned buffer must have suboffsets information.  This would
-   be used when the consumer can handle indirect array referencing
-   implied by these suboffsets.  
+   The returned buffer must have suboffsets information (which can be
+   NULL if no suboffsets are needed).  This would be used when the
+   consumer can handle indirect array referencing implied by these
+   suboffsets.
 
 
 Specialized combinations of flags for specific kinds of memory_sharing. 
 
   Multi-dimensional (but contiguous)
 
-   | ``PyBUF_CONTIG`` (``PyBUF_ALW_ND | PyBUF_REQ_WRITEABLE | PyBUF_REQ_ALIGNED``)
-   | ``PyBUF_CONTIG_RO`` (``PyBUF_ALW_ND | PyBUF_REQ_ALIGNED``)
-   | ``PyBUF_CONTIG_LCK`` (``PyBUF_ALW_ND | PyBUF_REQ_LOCKDATA | PyBUF_REQ_ALIGNED``)
+   | ``PyBUF_CONTIG`` (``PyBUF_ALW_ND | PyBUF_REQ_WRITEABLE``)
+   | ``PyBUF_CONTIG_RO`` (``PyBUF_ALW_ND``)
+   | ``PyBUF_CONTIG_LCK`` (``PyBUF_ALW_ND | PyBUF_REQ_LOCKDATA``)
 
   Multi-dimensional using strides but aligned
 
-   | ``PyBUF_STRIDED`` (``PyBUF_ALW_STRIDES | PyBUF_REQ_WRITEABLE | PyBUF_REQ_ALIGNED``)
-   | ``PyBUF_STRIDED_RO`` (``PyBUF_ALW_STRIDES | PyBUF_REQ_ALIGNED``)
-   | ``PyBUF_STRIDED_LCK`` (``PyBUF_ALW_STRIDES | PyBUF_REQ_LOCKDATA | PyBUF_REQ_ALIGNED``)
+   | ``PyBUF_STRIDED`` (``PyBUF_ALW_STRIDES | PyBUF_REQ_WRITEABLE``)
+   | ``PyBUF_STRIDED_RO`` (``PyBUF_ALW_STRIDES``)
+   | ``PyBUF_STRIDED_LCK`` (``PyBUF_ALW_STRIDES | PyBUF_REQ_LOCKDATA``)
 
   Multi-dimensional using strides and not necessarily aligned
 
@@ -290,7 +289,6 @@
 buffer info structure correctly according to the provided flags if a
 contiguous chunk of "unsigned bytes" is all that can be exported.
 
-
 The bufferinfo structure is::
 
   struct bufferinfo {
@@ -357,7 +355,8 @@
     if ``ndims`` is 0).  indicating the number of bytes to skip to get to
     the next element in each dimension.  If this is not requested by
     the caller (``PyBUF_ALW_STRIDES`` is not set), then this should be set
-    to NULL which indicates a C-style contiguous array.
+    to NULL which indicates a C-style contiguous array or a 
+    PyExc_BufferError raised if this is not possible. 
 
 ``suboffsets``
     address of a ``Py_ssize_t *`` variable that will be filled with a
@@ -368,7 +367,9 @@
     suboffset value that it negative indicates that no de-referencing
     should occur (striding in a contiguous memory block).  If all 
     suboffsets are negative (i.e. no de-referencing is needed, then
-    this must be NULL (the default value). 
+    this must be NULL (the default value).  If this is not requested
+    by the caller (PyBUF_ALW_INDIRECT is not set), then this should be 
+    set to NULL or an PyExc_BufferError raised if this is not possible. 
 
     For clarity, here is a function that returns a pointer to the
     element in an N-D array pointed to by an N-dimesional index when
@@ -395,7 +396,7 @@
 
 ``itemsize``
     This is a storage for the itemsize of each element of the shared
-    memory.  It is strictly un-necessary as it can be obtained using
+    memory.  It is technically un-necessary as it can be obtained using
     ``PyBuffer_SizeFromFormat``, however an exporter may know this
     information without parsing the format string and it is necessary
     to know the itemsize for proper interpretation of striding.
@@ -420,9 +421,9 @@
 
 The same bufferinfo struct should be used in the release-buffer
 interface call. The caller is responsible for the memory of the
-bufferinfo structure itself. 
+PyBuffer structure itself. 
 
-``typedef int (*releasebufferproc)(PyObject *obj, PyBuffer *view)``
+``typedef void (*releasebufferproc)(PyObject *obj, PyBuffer *view)``
     Callers of getbufferproc must make sure that this function is
     called when memory previously acquired from the object is no
     longer needed.  The exporter of the interface must make sure that
@@ -469,13 +470,11 @@
 success.
 
 ::
-
-    int PyObject_ReleaseBuffer(PyObject *obj, PyBuffer *view)
+    void PyObject_ReleaseBuffer(PyObject *obj, PyBuffer *view)
 
 This is a C-API version of the releasebuffer function call.  It checks
 to make sure the object has the required function pointer and issues
-the call.  Returns 0 on success and -1 (with an error raised) on
-failure. This function always succeeds if there is no releasebuffer
+the call.  This function always succeeds even if there is no releasebuffer
 function for the object.
 
 ::
@@ -554,19 +553,24 @@
 ::
 
     int PyObject_GetContiguous(PyObject *obj, void **buf, Py_ssize_t *len,
-                               char **format, char fortran)
+                               char **format, int writeable, char 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.  If an
 error occurred in probing the buffer interface, then return -1.  The
 contiguous chunk of memory is pointed to by ``*buf`` and the length of
-that memory is ``*len``.  If the object is multi-dimensional, then if
-fortran is 'F', the first dimension of the underlying array will vary
-the fastest in the buffer.  If fortran is 'C', then the last dimension
-will vary the fastest (C-style contiguous). If fortran is 'A', then it
-does not matter and you will get whatever the object decides is more
-efficient.   If a copy is made, then the memory must be freed by calling
-``PyMem_Free``. 
+that memory is ``*len``.  If writeable is 1, then the returned memory
+must be writeable or else an error is raised. Otherwise, the memory
+may or may not be writeable.  If the object is multi-dimensional, then
+if fortran is 'F', the first dimension of the underlying array will
+vary the fastest in the buffer.  If fortran is 'C', then the last
+dimension will vary the fastest (C-style contiguous). If fortran is
+'A', then it does not matter and you will get whatever the object
+decides is more efficient.  If a copy is made, then the memory must be
+freed by calling ``PyMem_Free``.
+
+PyObject_ReleaseBuffer must be called on obj after you are done with the
+memory even if a copy is made. 
 
 :: 
 
@@ -579,11 +583,13 @@
 object does not have a writeable buffer, then an error is raised.  If
 fortran is 'F', then if the object is multi-dimensional, then the data
 will be copied into the array in Fortran-style (first dimension varies
-the fastest).  If fortran is 'C', then the data will be copied into the
-array in C-style (last dimension varies the fastest).  If fortran is 'A', then
-it does not matter and the copy will be made in whatever way is more
-efficient.
+the fastest).  If fortran is 'C', then the data will be copied into
+the array in C-style (last dimension varies the fastest).  If fortran
+is 'A', then it does not matter and the copy will be made in whatever
+way is more efficient.
 
+::
+     int PyObject_CopyData(PyObject *dest, PyObject *src)
 
 These last three C-API calls allow a standard way of getting data in and
 out of Python objects into contiguous memory areas no matter how it is
@@ -600,19 +606,12 @@
 
 ::
 
-    int PyBuffer_IsAligned(PyBuffer *view)
-
-Return 1 if the memory at all elements of the array implied by the
-view object is aligned
-
-::
-
-    void PyBuffer_FillContiguousStrides(int *ndims, Py_ssize_t *shape,
-                                        int itemsize, 
-                                        Py_ssize_t *strides, char fortran)
+    void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape,
+                                        Py_ssize_t *strides, int itemsize,
+                                        char fortran)
 
 Fill the strides array with byte-strides of a contiguous (C-style if
-fortran is 0 or Fortran-style if fortran is 1) array of the given
+fortran is 'C' or Fortran-style if fortran is 'F' array of the given
 shape with the given number of bytes per element.
 
 ::
@@ -627,7 +626,7 @@
 
 ::
 
-    PyErr_BufferError
+    PyExc_BufferError
 
 A new error object for returning buffer errors which arise because an
 exporter cannot provide the kind of buffer that a consumer expects.
@@ -754,6 +753,7 @@
 * buffer object
 * bytes object
 * string object
+* unicode object
 * array module
 * struct module
 * mmap module
@@ -847,7 +847,7 @@
 
   int Image_getbuffer(PyObject *self, PyBuffer *view, int flags) {
 
-      static Py_ssize_t suboffsets[2] = { -1, 0 };
+      static Py_ssize_t suboffsets[2] = { 0, -1};
 
       view->buf = self->lines;
       view->len = self->height*self->width;
@@ -938,8 +938,10 @@
     void *buf;
     Py_ssize_t len;
     char *format;
+    int copy;
 
-    if (PyObject_GetContiguous(obj, &buf, &len, &format, 0) < 0) {
+    copy = PyObject_GetContiguous(obj, &buf, &len, &format, 0, 'A');
+    if (copy < 0) {
        /* error return */
     }
 
@@ -953,9 +955,12 @@
        we could do
        */
 
-    if (PyObject_CopyToObject(obj, buf, len, 0) < 0) {
+    if (PyObject_CopyToObject(obj, buf, len, 'A') < 0) {
            /*        error return */
     }
+
+    /* Make sure that if a copy was made, the memory is freed */
+    if (copy == 1) PyMem_Free(buf);
    
 
 Copyright


More information about the Python-checkins mailing list