mirror of https://github.com/python/cpython
gh-85275: Remove old buffer APIs (#105137)
They are now abi-only. Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
ef300937c2
commit
37498fc950
|
@ -24,4 +24,3 @@ but whose items have not been set to some non-\ ``NULL`` value yet.
|
||||||
mapping.rst
|
mapping.rst
|
||||||
iter.rst
|
iter.rst
|
||||||
buffer.rst
|
buffer.rst
|
||||||
objbuffer.rst
|
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
.. highlight:: c
|
|
||||||
|
|
||||||
Old Buffer Protocol
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
.. deprecated:: 3.0
|
|
||||||
|
|
||||||
These functions were part of the "old buffer protocol" API in Python 2.
|
|
||||||
In Python 3, this protocol doesn't exist anymore but the functions are still
|
|
||||||
exposed to ease porting 2.x code. They act as a compatibility wrapper
|
|
||||||
around the :ref:`new buffer protocol <bufferobjects>`, but they don't give
|
|
||||||
you control over the lifetime of the resources acquired when a buffer is
|
|
||||||
exported.
|
|
||||||
|
|
||||||
Therefore, it is recommended that you call :c:func:`PyObject_GetBuffer`
|
|
||||||
(or the ``y*`` or ``w*`` :ref:`format codes <arg-parsing>` with the
|
|
||||||
:c:func:`PyArg_ParseTuple` family of functions) to get a buffer view over
|
|
||||||
an object, and :c:func:`PyBuffer_Release` when the buffer view can be released.
|
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len)
|
|
||||||
|
|
||||||
Returns a pointer to a read-only memory location usable as character-based
|
|
||||||
input. The *obj* argument must support the single-segment character buffer
|
|
||||||
interface. On success, returns ``0``, sets *buffer* to the memory location
|
|
||||||
and *buffer_len* to the buffer length. Returns ``-1`` and sets a
|
|
||||||
:exc:`TypeError` on error.
|
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
|
|
||||||
|
|
||||||
Returns a pointer to a read-only memory location containing arbitrary data.
|
|
||||||
The *obj* argument must support the single-segment readable buffer
|
|
||||||
interface. On success, returns ``0``, sets *buffer* to the memory location
|
|
||||||
and *buffer_len* to the buffer length. Returns ``-1`` and sets a
|
|
||||||
:exc:`TypeError` on error.
|
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyObject_CheckReadBuffer(PyObject *o)
|
|
||||||
|
|
||||||
Returns ``1`` if *o* supports the single-segment readable buffer interface.
|
|
||||||
Otherwise returns ``0``. This function always succeeds.
|
|
||||||
|
|
||||||
Note that this function tries to get and release a buffer, and exceptions
|
|
||||||
which occur while calling corresponding functions will get suppressed.
|
|
||||||
To get error reporting use :c:func:`PyObject_GetBuffer()` instead.
|
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len)
|
|
||||||
|
|
||||||
Returns a pointer to a writable memory location. The *obj* argument must
|
|
||||||
support the single-segment, character buffer interface. On success,
|
|
||||||
returns ``0``, sets *buffer* to the memory location and *buffer_len* to the
|
|
||||||
buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error.
|
|
||||||
|
|
|
@ -1578,21 +1578,6 @@ PyOS_FSPath:PyObject*:path:0:
|
||||||
PyObject_ASCII:PyObject*::+1:
|
PyObject_ASCII:PyObject*::+1:
|
||||||
PyObject_ASCII:PyObject*:o:0:
|
PyObject_ASCII:PyObject*:o:0:
|
||||||
|
|
||||||
PyObject_AsCharBuffer:int:::
|
|
||||||
PyObject_AsCharBuffer:PyObject*:obj:0:
|
|
||||||
PyObject_AsCharBuffer:const char**:buffer::
|
|
||||||
PyObject_AsCharBuffer:Py_ssize_t*:buffer_len::
|
|
||||||
|
|
||||||
PyObject_AsReadBuffer:int:::
|
|
||||||
PyObject_AsReadBuffer:PyObject*:obj:0:
|
|
||||||
PyObject_AsReadBuffer:const void**:buffer::
|
|
||||||
PyObject_AsReadBuffer:Py_ssize_t*:buffer_len::
|
|
||||||
|
|
||||||
PyObject_AsWriteBuffer:int:::
|
|
||||||
PyObject_AsWriteBuffer:PyObject*:obj:0:
|
|
||||||
PyObject_AsWriteBuffer:void**:buffer::
|
|
||||||
PyObject_AsWriteBuffer:Py_ssize_t*:buffer_len::
|
|
||||||
|
|
||||||
PyObject_Bytes:PyObject*::+1:
|
PyObject_Bytes:PyObject*::+1:
|
||||||
PyObject_Bytes:PyObject*:o:0:
|
PyObject_Bytes:PyObject*:o:0:
|
||||||
|
|
||||||
|
|
|
@ -476,10 +476,7 @@ type,PyObject,3.2,,members
|
||||||
member,PyObject.ob_refcnt,3.2,,
|
member,PyObject.ob_refcnt,3.2,,
|
||||||
member,PyObject.ob_type,3.2,,
|
member,PyObject.ob_type,3.2,,
|
||||||
function,PyObject_ASCII,3.2,,
|
function,PyObject_ASCII,3.2,,
|
||||||
function,PyObject_AsCharBuffer,3.2,,
|
|
||||||
function,PyObject_AsFileDescriptor,3.2,,
|
function,PyObject_AsFileDescriptor,3.2,,
|
||||||
function,PyObject_AsReadBuffer,3.2,,
|
|
||||||
function,PyObject_AsWriteBuffer,3.2,,
|
|
||||||
function,PyObject_Bytes,3.2,,
|
function,PyObject_Bytes,3.2,,
|
||||||
function,PyObject_Call,3.2,,
|
function,PyObject_Call,3.2,,
|
||||||
function,PyObject_CallFunction,3.2,,
|
function,PyObject_CallFunction,3.2,,
|
||||||
|
@ -490,7 +487,6 @@ function,PyObject_CallNoArgs,3.10,,
|
||||||
function,PyObject_CallObject,3.2,,
|
function,PyObject_CallObject,3.2,,
|
||||||
function,PyObject_Calloc,3.7,,
|
function,PyObject_Calloc,3.7,,
|
||||||
function,PyObject_CheckBuffer,3.11,,
|
function,PyObject_CheckBuffer,3.11,,
|
||||||
function,PyObject_CheckReadBuffer,3.2,,
|
|
||||||
function,PyObject_ClearWeakRefs,3.2,,
|
function,PyObject_ClearWeakRefs,3.2,,
|
||||||
function,PyObject_CopyData,3.11,,
|
function,PyObject_CopyData,3.11,,
|
||||||
function,PyObject_DelItem,3.2,,
|
function,PyObject_DelItem,3.2,,
|
||||||
|
|
|
@ -395,6 +395,42 @@ Removed
|
||||||
|
|
||||||
(Contributed by Victor Stinner in :gh:`105107`.)
|
(Contributed by Victor Stinner in :gh:`105107`.)
|
||||||
|
|
||||||
|
* Remove old buffer protocols deprecated in Python 3.0. Use :ref:`bufferobjects` instead.
|
||||||
|
|
||||||
|
* :c:func:`!PyObject_CheckReadBuffer`: Use :c:func:`PyObject_CheckBuffer` to
|
||||||
|
test if the object supports the buffer protocol.
|
||||||
|
Note that :c:func:`PyObject_CheckBuffer` doesn't guarantee that
|
||||||
|
:c:func:`PyObject_GetBuffer` will succeed.
|
||||||
|
To test if the object is actually readable, see the next example
|
||||||
|
of :c:func:`PyObject_GetBuffer`.
|
||||||
|
|
||||||
|
* :c:func:`!PyObject_AsCharBuffer`, :c:func:`!PyObject_AsReadBuffer`:
|
||||||
|
:c:func:`PyObject_GetBuffer` and :c:func:`PyBuffer_Release` instead:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
Py_buffer view;
|
||||||
|
if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Use `view.buf` and `view.len` to read from the buffer.
|
||||||
|
// You may need to cast buf as `(const char*)view.buf`.
|
||||||
|
PyBuffer_Release(&view);
|
||||||
|
|
||||||
|
* :c:func:`!PyObject_AsWriteBuffer`: Use
|
||||||
|
:c:func:`PyObject_GetBuffer` and :c:func:`PyBuffer_Release` instead:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
Py_buffer view;
|
||||||
|
if (PyObject_GetBuffer(obj, &view, PyBUF_WRITABLE) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Use `view.buf` and `view.len` to write to the buffer.
|
||||||
|
PyBuffer_Release(&view);
|
||||||
|
|
||||||
|
(Contributed by Inada Naoki in :gh:`85275`.)
|
||||||
|
|
||||||
* Remove the following old functions to configure the Python initialization,
|
* Remove the following old functions to configure the Python initialization,
|
||||||
deprecated in Python 3.11:
|
deprecated in Python 3.11:
|
||||||
|
|
||||||
|
|
|
@ -320,55 +320,6 @@ PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key);
|
||||||
PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key);
|
PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key);
|
||||||
|
|
||||||
|
|
||||||
/* === Old Buffer API ============================================ */
|
|
||||||
|
|
||||||
/* FIXME: usage of these should all be replaced in Python itself
|
|
||||||
but for backwards compatibility we will implement them.
|
|
||||||
Their usage without a corresponding "unlock" mechanism
|
|
||||||
may create issues (but they would already be there). */
|
|
||||||
|
|
||||||
/* Takes an arbitrary object which must support the (character, single segment)
|
|
||||||
buffer interface and returns a pointer to a read-only memory location
|
|
||||||
usable as character based input for subsequent processing.
|
|
||||||
|
|
||||||
Return 0 on success. buffer and buffer_len are only set in case no error
|
|
||||||
occurs. Otherwise, -1 is returned and an exception set. */
|
|
||||||
Py_DEPRECATED(3.0)
|
|
||||||
PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj,
|
|
||||||
const char **buffer,
|
|
||||||
Py_ssize_t *buffer_len);
|
|
||||||
|
|
||||||
/* Checks whether an arbitrary object supports the (character, single segment)
|
|
||||||
buffer interface.
|
|
||||||
|
|
||||||
Returns 1 on success, 0 on failure. */
|
|
||||||
Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj);
|
|
||||||
|
|
||||||
/* Same as PyObject_AsCharBuffer() except that this API expects (readable,
|
|
||||||
single segment) buffer interface and returns a pointer to a read-only memory
|
|
||||||
location which can contain arbitrary data.
|
|
||||||
|
|
||||||
0 is returned on success. buffer and buffer_len are only set in case no
|
|
||||||
error occurs. Otherwise, -1 is returned and an exception set. */
|
|
||||||
Py_DEPRECATED(3.0)
|
|
||||||
PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj,
|
|
||||||
const void **buffer,
|
|
||||||
Py_ssize_t *buffer_len);
|
|
||||||
|
|
||||||
/* Takes an arbitrary object which must support the (writable, single segment)
|
|
||||||
buffer interface and returns a pointer to a writable memory location in
|
|
||||||
buffer of size 'buffer_len'.
|
|
||||||
|
|
||||||
Return 0 on success. buffer and buffer_len are only set in case no error
|
|
||||||
occurs. Otherwise, -1 is returned and an exception set. */
|
|
||||||
Py_DEPRECATED(3.0)
|
|
||||||
PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj,
|
|
||||||
void **buffer,
|
|
||||||
Py_ssize_t *buffer_len);
|
|
||||||
|
|
||||||
|
|
||||||
/* === New Buffer API ============================================ */
|
|
||||||
|
|
||||||
/* Takes an arbitrary object and returns the result of calling
|
/* Takes an arbitrary object and returns the result of calling
|
||||||
obj.__format__(format_spec). */
|
obj.__format__(format_spec). */
|
||||||
PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj,
|
PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj,
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
``PyObject_AsCharBuffer()``, ``PyObject_AsReadBuffer()``,
|
||||||
|
``PyObject_CheckReadBuffer()``, and ``PyObject_AsWriteBuffer()`` are
|
||||||
|
removed. Please migrate to new buffer protocol; :c:func:`PyObject_GetBuffer`
|
||||||
|
and :c:func:`PyBuffer_Release`.
|
|
@ -1755,12 +1755,16 @@
|
||||||
|
|
||||||
[function.PyObject_AsCharBuffer]
|
[function.PyObject_AsCharBuffer]
|
||||||
added = '3.2'
|
added = '3.2'
|
||||||
|
abi_only = true
|
||||||
[function.PyObject_AsReadBuffer]
|
[function.PyObject_AsReadBuffer]
|
||||||
added = '3.2'
|
added = '3.2'
|
||||||
|
abi_only = true
|
||||||
[function.PyObject_AsWriteBuffer]
|
[function.PyObject_AsWriteBuffer]
|
||||||
added = '3.2'
|
added = '3.2'
|
||||||
|
abi_only = true
|
||||||
[function.PyObject_CheckReadBuffer]
|
[function.PyObject_CheckReadBuffer]
|
||||||
added = '3.2'
|
added = '3.2'
|
||||||
|
abi_only = true
|
||||||
|
|
||||||
# Flags are implicitly part of the ABI:
|
# Flags are implicitly part of the ABI:
|
||||||
|
|
||||||
|
|
|
@ -294,11 +294,17 @@ PyObject_CheckBuffer(PyObject *obj)
|
||||||
return (tp_as_buffer != NULL && tp_as_buffer->bf_getbuffer != NULL);
|
return (tp_as_buffer != NULL && tp_as_buffer->bf_getbuffer != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Old buffer protocols (deprecated, abi only)
|
||||||
|
|
||||||
/* We release the buffer right after use of this function which could
|
/* Checks whether an arbitrary object supports the (character, single segment)
|
||||||
|
buffer interface.
|
||||||
|
|
||||||
|
Returns 1 on success, 0 on failure.
|
||||||
|
|
||||||
|
We release the buffer right after use of this function which could
|
||||||
cause issues later on. Don't use these functions in new code.
|
cause issues later on. Don't use these functions in new code.
|
||||||
*/
|
*/
|
||||||
int
|
PyAPI_FUNC(int) /* abi_only */
|
||||||
PyObject_CheckReadBuffer(PyObject *obj)
|
PyObject_CheckReadBuffer(PyObject *obj)
|
||||||
{
|
{
|
||||||
PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer;
|
PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer;
|
||||||
|
@ -333,7 +339,13 @@ as_read_buffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
/* Takes an arbitrary object which must support the (character, single segment)
|
||||||
|
buffer interface and returns a pointer to a read-only memory location
|
||||||
|
usable as character based input for subsequent processing.
|
||||||
|
|
||||||
|
Return 0 on success. buffer and buffer_len are only set in case no error
|
||||||
|
occurs. Otherwise, -1 is returned and an exception set. */
|
||||||
|
PyAPI_FUNC(int) /* abi_only */
|
||||||
PyObject_AsCharBuffer(PyObject *obj,
|
PyObject_AsCharBuffer(PyObject *obj,
|
||||||
const char **buffer,
|
const char **buffer,
|
||||||
Py_ssize_t *buffer_len)
|
Py_ssize_t *buffer_len)
|
||||||
|
@ -341,16 +353,30 @@ PyObject_AsCharBuffer(PyObject *obj,
|
||||||
return as_read_buffer(obj, (const void **)buffer, buffer_len);
|
return as_read_buffer(obj, (const void **)buffer, buffer_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PyObject_AsReadBuffer(PyObject *obj,
|
/* Same as PyObject_AsCharBuffer() except that this API expects (readable,
|
||||||
const void **buffer,
|
single segment) buffer interface and returns a pointer to a read-only memory
|
||||||
Py_ssize_t *buffer_len)
|
location which can contain arbitrary data.
|
||||||
|
|
||||||
|
0 is returned on success. buffer and buffer_len are only set in case no
|
||||||
|
error occurs. Otherwise, -1 is returned and an exception set. */
|
||||||
|
PyAPI_FUNC(int) /* abi_only */
|
||||||
|
PyObject_AsReadBuffer(PyObject *obj,
|
||||||
|
const void **buffer,
|
||||||
|
Py_ssize_t *buffer_len)
|
||||||
{
|
{
|
||||||
return as_read_buffer(obj, buffer, buffer_len);
|
return as_read_buffer(obj, buffer, buffer_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PyObject_AsWriteBuffer(PyObject *obj,
|
/* Takes an arbitrary object which must support the (writable, single segment)
|
||||||
void **buffer,
|
buffer interface and returns a pointer to a writable memory location in
|
||||||
Py_ssize_t *buffer_len)
|
buffer of size 'buffer_len'.
|
||||||
|
|
||||||
|
Return 0 on success. buffer and buffer_len are only set in case no error
|
||||||
|
occurs. Otherwise, -1 is returned and an exception set. */
|
||||||
|
PyAPI_FUNC(int) /* abi_only */
|
||||||
|
PyObject_AsWriteBuffer(PyObject *obj,
|
||||||
|
void **buffer,
|
||||||
|
Py_ssize_t *buffer_len)
|
||||||
{
|
{
|
||||||
PyBufferProcs *pb;
|
PyBufferProcs *pb;
|
||||||
Py_buffer view;
|
Py_buffer view;
|
||||||
|
|
Loading…
Reference in New Issue