diff --git a/pandas/io/msgpack/_unpacker.pyx b/pandas/io/msgpack/_unpacker.pyx index 8734990c44da0..c2e2dfc521a51 100644 --- a/pandas/io/msgpack/_unpacker.pyx +++ b/pandas/io/msgpack/_unpacker.pyx @@ -5,15 +5,13 @@ from cython cimport Py_ssize_t from cpython cimport ( PyCallable_Check, - PyBUF_SIMPLE, PyObject_GetBuffer, PyBuffer_Release, + PyBUF_SIMPLE, PyObject_GetBuffer, PyBuffer_Release, Py_buffer, PyBytes_Size, PyBytes_FromStringAndSize, PyBytes_AsString) cdef extern from "Python.h": ctypedef struct PyObject - cdef int PyObject_AsReadBuffer(object o, const void** buff, - Py_ssize_t* buf_len) except -1 from libc.stdlib cimport free, malloc from libc.string cimport memcpy, memmove @@ -129,8 +127,14 @@ def unpackb(object packed, object object_hook=None, object list_hook=None, Py_ssize_t buf_len char* cenc = NULL char* cerr = NULL + Py_buffer view + bytes extra_bytes - PyObject_AsReadBuffer(packed, &buf, &buf_len) + # GH#26769 Effectively re-implement deprecated PyObject_AsReadBuffer; + # based on https://xpra.org/trac/ticket/1884 + PyObject_GetBuffer(packed, &view, PyBUF_SIMPLE) + buf = view.buf + buf_len = view.len if encoding is not None: if isinstance(encoding, unicode): @@ -149,10 +153,13 @@ def unpackb(object packed, object object_hook=None, object list_hook=None, if ret == 1: obj = unpack_data(&ctx) if off < buf_len: - raise ExtraData(obj, PyBytes_FromStringAndSize( - buf + off, buf_len - off)) + extra_bytes = PyBytes_FromStringAndSize(buf + off, buf_len - off) + PyBuffer_Release(&view) + raise ExtraData(obj, extra_bytes) + PyBuffer_Release(&view) return obj else: + PyBuffer_Release(&view) raise UnpackValueError("Unpack failed: error = {ret}".format(ret=ret))