Skip to content

Commit

Permalink
pythongh-85275: Remove old buffer APIs (python#105137)
Browse files Browse the repository at this point in the history
They are now abi-only.

Co-authored-by: Victor Stinner <vstinner@python.org>
  • Loading branch information
methane and vstinner committed Jun 2, 2023
1 parent ef30093 commit 37498fc
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 133 deletions.
1 change: 0 additions & 1 deletion Doc/c-api/abstract.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,3 @@ but whose items have not been set to some non-\ ``NULL`` value yet.
mapping.rst
iter.rst
buffer.rst
objbuffer.rst
55 changes: 0 additions & 55 deletions Doc/c-api/objbuffer.rst

This file was deleted.

15 changes: 0 additions & 15 deletions Doc/data/refcounts.dat
Original file line number Diff line number Diff line change
Expand Up @@ -1578,21 +1578,6 @@ PyOS_FSPath:PyObject*:path:0:
PyObject_ASCII:PyObject*::+1:
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*:o:0:

Expand Down
4 changes: 0 additions & 4 deletions Doc/data/stable_abi.dat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,42 @@ Removed

(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,
deprecated in Python 3.11:

Expand Down
49 changes: 0 additions & 49 deletions Include/abstract.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,55 +320,6 @@ PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *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
obj.__format__(format_spec). */
PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj,
Expand Down
Original file line number Diff line number Diff line change
@@ -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`.
4 changes: 4 additions & 0 deletions Misc/stable_abi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1755,12 +1755,16 @@

[function.PyObject_AsCharBuffer]
added = '3.2'
abi_only = true
[function.PyObject_AsReadBuffer]
added = '3.2'
abi_only = true
[function.PyObject_AsWriteBuffer]
added = '3.2'
abi_only = true
[function.PyObject_CheckReadBuffer]
added = '3.2'
abi_only = true

# Flags are implicitly part of the ABI:

Expand Down
44 changes: 35 additions & 9 deletions Objects/abstract.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,17 @@ PyObject_CheckBuffer(PyObject *obj)
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.
*/
int
PyAPI_FUNC(int) /* abi_only */
PyObject_CheckReadBuffer(PyObject *obj)
{
PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer;
Expand Down Expand Up @@ -333,24 +339,44 @@ as_read_buffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
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,
const char **buffer,
Py_ssize_t *buffer_len)
{
return as_read_buffer(obj, (const void **)buffer, buffer_len);
}

int PyObject_AsReadBuffer(PyObject *obj,
const void **buffer,
Py_ssize_t *buffer_len)
/* 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. */
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);
}

int PyObject_AsWriteBuffer(PyObject *obj,
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. */
PyAPI_FUNC(int) /* abi_only */
PyObject_AsWriteBuffer(PyObject *obj,
void **buffer,
Py_ssize_t *buffer_len)
{
PyBufferProcs *pb;
Py_buffer view;
Expand Down

0 comments on commit 37498fc

Please sign in to comment.