bpo-41103: Resurrect the old buffer protocol. (GH-27437) (GH-27441)
Revert "bpo-41103: Remove old buffer protocol support (GH-21117)"
This reverts commit 6f8a6ee59cb7f99f68df8ee9c3e8c8cf19af3eed.
(cherry picked from commit ce5e1a6809b714eb0383219190a076d9f883e008)
Co-authored-by: Inada Naoki <songofacandy@gmail.com>
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 842c367..8ad1910 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -293,6 +293,85 @@ PyObject_CheckBuffer(PyObject *obj)
}
+/* 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
+PyObject_CheckReadBuffer(PyObject *obj)
+{
+ PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer;
+ Py_buffer view;
+
+ if (pb == NULL ||
+ pb->bf_getbuffer == NULL)
+ return 0;
+ if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE) == -1) {
+ PyErr_Clear();
+ return 0;
+ }
+ PyBuffer_Release(&view);
+ return 1;
+}
+
+static int
+as_read_buffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
+{
+ Py_buffer view;
+
+ if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+ null_error();
+ return -1;
+ }
+ if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0)
+ return -1;
+
+ *buffer = view.buf;
+ *buffer_len = view.len;
+ PyBuffer_Release(&view);
+ return 0;
+}
+
+int
+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)
+{
+ return as_read_buffer(obj, buffer, buffer_len);
+}
+
+int PyObject_AsWriteBuffer(PyObject *obj,
+ void **buffer,
+ Py_ssize_t *buffer_len)
+{
+ PyBufferProcs *pb;
+ Py_buffer view;
+
+ if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+ null_error();
+ return -1;
+ }
+ pb = Py_TYPE(obj)->tp_as_buffer;
+ if (pb == NULL ||
+ pb->bf_getbuffer == NULL ||
+ ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a writable bytes-like object");
+ return -1;
+ }
+
+ *buffer = view.buf;
+ *buffer_len = view.len;
+ PyBuffer_Release(&view);
+ return 0;
+}
+
/* Buffer C-API for Python 3.0 */
int