[Python-checkins] python/nondist/peps pep-0298.txt,1.3,1.4
theller@users.sourceforge.net
theller@users.sourceforge.net
Wed, 31 Jul 2002 11:48:38 -0700
Update of /cvsroot/python/python/nondist/peps
In directory usw-pr-cvs1:/tmp/cvs-serv26234
Modified Files:
pep-0298.txt
Log Message:
The model exposed by the fixed buffer interface was changed:
Retrieving a buffer from an object puts this in a locked state, and a
releasebuffer function must be called to unlock the object again.
Added releasefixedbuffer function slot, and renamed the
get...fixedbuffer functions to acquire...fixedbuffer functions.
Renamed the flag from Py_TPFLAG_HAVE_GETFIXEDBUFFER to
Py_TPFLAG_HAVE_FIXEDBUFFER. (Is the 'fixed buffer' name still useful,
or should we use 'static buffer' instead?)
Added posting date (was posted to c.l.p and python-dev).
Index: pep-0298.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0298.txt,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** pep-0298.txt 30 Jul 2002 16:52:53 -0000 1.3
--- pep-0298.txt 31 Jul 2002 18:48:36 -0000 1.4
***************
*** 8,12 ****
Created: 26-Jul-2002
Python-Version: 2.3
! Post-History:
--- 8,12 ----
Created: 26-Jul-2002
Python-Version: 2.3
! Post-History: 30-Jul-2002
***************
*** 17,24 ****
The fixed buffer interface fixes the flaws of the 'old' buffer
! interface as defined in Python versions up to and including 2.2,
! see [1]:
! The lifetime of the retrieved pointer is clearly defined.
The buffer size is returned as a 'size_t' data type, which
--- 17,25 ----
The fixed buffer interface fixes the flaws of the 'old' buffer
! interface [1] as defined in Python versions up to and including
! 2.2, and has the following semantics:
! The lifetime of the retrieved pointer is clearly defined and
! controlled by the client.
The buffer size is returned as a 'size_t' data type, which
***************
*** 26,29 ****
--- 27,34 ----
!= sizeof(void *).
+ (Guido comments: This second sounds like a change we could also
+ make to the "old" buffer interface, if we introduce another flag
+ bit that's *not* part of the default flags.)
+
Specification
***************
*** 33,40 ****
object which chooses to implement this interface.
! The size and pointer returned must be valid as long as the object
! is alive (has a positive reference count). So, only objects which
! never reallocate or resize the memory block are allowed to
! implement this interface.
The fixed buffer interface omits the memory segment model which is
--- 38,51 ----
object which chooses to implement this interface.
! Retrieving a buffer from an object puts this object in a locked
! state during which the buffer may not be freed, resized, or
! reallocated.
!
! The object must be unlocked again by releasing the buffer if it's
! no longer used by calling another function in the fixed buffer
! interface. If the object never resizes or reallocates the buffer
! during it's lifetime, this function may be NULL. Failure to call
! this function (if it is != NULL) is a programming error and may
! have unexpected results.
The fixed buffer interface omits the memory segment model which is
***************
*** 47,53 ****
Define a new flag in Include/object.h:
! /* PyBufferProcs contains bf_getfixedreadbuffer
! and bf_getfixedwritebuffer */
! #define Py_TPFLAGS_HAVE_GETFIXEDBUFFER (1L<<15)
--- 58,64 ----
Define a new flag in Include/object.h:
! /* PyBufferProcs contains bf_acquirefixedreadbuffer,
! bf_acquirefixedwritebuffer, and bf_releasefixedbuffer */
! #define Py_TPFLAGS_HAVE_FIXEDBUFFER (1L<<15)
***************
*** 56,60 ****
#define Py_TPFLAGS_DEFAULT ( \
....
! Py_TPFLAGS_HAVE_GETFIXEDBUFFER | \
....
0)
--- 67,71 ----
#define Py_TPFLAGS_DEFAULT ( \
....
! Py_TPFLAGS_HAVE_FIXEDBUFFER | \
....
0)
***************
*** 64,69 ****
Include/object.h:
! typedef size_t (*getfixedreadbufferproc)(PyObject *, void **);
! typedef size_t (*getfixedwritebufferproc)(PyObject *, void **);
typedef struct {
--- 75,83 ----
Include/object.h:
! typedef size_t (*acquirefixedreadbufferproc)(PyObject *,
! const void **);
! typedef size_t (*acquirefixedwritebufferproc)(PyObject *,
! void **);
! typedef void (*releasefixedbufferproc)(PyObject *);
typedef struct {
***************
*** 73,112 ****
getcharbufferproc bf_getcharbuffer;
/* fixed buffer interface functions */
! getfixedreadbufferproc bf_getfixedreadbufferproc;
! getfixedwritebufferproc bf_getfixedwritebufferproc;
} PyBufferProcs;
! The new fields are present if the Py_TPFLAGS_HAVE_GETFIXEDBUFFER
flag is set in the object's type.
! The Py_TPFLAGS_HAVE_GETFIXEDBUFFER flag implies the
Py_TPFLAGS_HAVE_GETCHARBUFFER flag.
! The getfixedreadbufferproc and getfixedwritebufferproc functions
! return the size in bytes of the memory block on success, and fill
! in the passed void * pointer on success. If these functions fail
! - either because an error occurs or no memory block is exposed -
! they must set the void * pointer to NULL and raise an exception.
! The return value is undefined in these cases and should not be
! used.
! Usually the getfixedwritebufferproc and getfixedreadbufferproc
! functions aren't called directly, they are called through
! convenience functions declared in Include/abstract.h:
! int PyObject_AsFixedReadBuffer(PyObject *obj,
! void **buffer,
! size_t *buffer_len);
! int PyObject_AsFixedWriteBuffer(PyObject *obj,
! void **buffer,
! size_t *buffer_len);
! These functions return 0 on success, set buffer to the memory
! location and buffer_len to the length of the memory block in
! bytes. On failure, or if the fixed buffer interface is not
implemented by obj, they return -1 and set an exception.
Backward Compatibility
--- 87,135 ----
getcharbufferproc bf_getcharbuffer;
/* fixed buffer interface functions */
! acquirefixedreadbufferproc bf_acquirefixedreadbuffer;
! acquirefixedwritebufferproc bf_acquirefixedwritebuffer;
! releasefixedbufferproc bf_releasefixedbuffer;
} PyBufferProcs;
! The new fields are present if the Py_TPFLAGS_HAVE_FIXEDBUFFER
flag is set in the object's type.
! The Py_TPFLAGS_HAVE_FIXEDBUFFER flag implies the
Py_TPFLAGS_HAVE_GETCHARBUFFER flag.
! The acquirefixedreadbufferproc and acquirefixedwritebufferproc
! functions return the size in bytes of the memory block on success,
! and fill in the passed void * pointer on success. If these
! functions fail - either because an error occurs or no memory block
! is exposed - they must set the void * pointer to NULL and raise an
! exception. The return value is undefined in these cases and
! should not be used.
! If calls to these functions succeed, eventually the buffer must be
! released by a call to the releasefixedbufferproc, supplying the
! original object as argument. The releasefixedbufferproc cannot
! fail.
! Usually these functions aren't called directly, they are called
! through convenience functions declared in Include/abstract.h:
! int PyObject_AquireFixedReadBuffer(PyObject *obj,
! const void **buffer,
! size_t *buffer_len);
! int PyObject_AcquireFixedWriteBuffer(PyObject *obj,
! void **buffer,
! size_t *buffer_len);
!
! void PyObject_ReleaseFixedBuffer(PyObject *obj);
!
! The former two functions return 0 on success, set buffer to the
! memory location and buffer_len to the length of the memory block
! in bytes. On failure, or if the fixed buffer interface is not
implemented by obj, they return -1 and set an exception.
+ The latter function doesn't return anything, and cannot fail.
+
Backward Compatibility
***************
*** 124,131 ****
Additional Notes/Comments
! Python strings, Unicode strings, mmap objects, and maybe other
! types would expose the fixed buffer interface, but the array type
! would *not*, because its memory block may be reallocated during
! its lifetime.
--- 147,152 ----
Additional Notes/Comments
! Python strings, Unicode strings, mmap objects, and array objects
! would expose the fixed buffer interface.
***************
*** 138,148 ****
Py_DECREF() may trigger execution of arbitrary Python code.
! Neil Hodgson wants to expose pointers to memory blocks with
! limited lifetime: do some kind of lock operation on the object,
! retrieve the pointer, use it, and unlock the object again. While
! the author sees the need for this, it cannot be addressed by this
! proposal. Beeing required to call a function after not using the
! pointer received by the getfixedbufferprocs any more seems too
! error prone.
--- 159,167 ----
Py_DECREF() may trigger execution of arbitrary Python code.
! The first version of this proposal didn't have the release
! function, but it turned out that this would have been too
! restrictive: mmap and array objects wouldn't have been able to
! implement it, because mmap objects can be closed anytime if not
! locked, and array objects could resize or reallocate the buffer.