diff --git a/python/pyarrow/__init__.py b/python/pyarrow/__init__.py index 15a37ca10d2..8cb4b3b9b75 100644 --- a/python/pyarrow/__init__.py +++ b/python/pyarrow/__init__.py @@ -72,8 +72,8 @@ from pyarrow.lib import TimestampType # Buffers, allocation -from pyarrow.lib import (Buffer, ResizableBuffer, compress, decompress, - allocate_buffer, frombuffer) +from pyarrow.lib import (Buffer, ForeignBuffer, ResizableBuffer, compress, + decompress, allocate_buffer, frombuffer) from pyarrow.lib import (MemoryPool, total_allocated_bytes, set_memory_pool, default_memory_pool, diff --git a/python/pyarrow/io.pxi b/python/pyarrow/io.pxi index 325c5827f00..5c8411be4cd 100644 --- a/python/pyarrow/io.pxi +++ b/python/pyarrow/io.pxi @@ -720,6 +720,18 @@ cdef class Buffer: return self.size +cdef class ForeignBuffer(Buffer): + + def __init__(self, addr, size, base): + cdef: + intptr_t c_addr = addr + int64_t c_size = size + self.base = base + cdef shared_ptr[CBuffer] buffer = make_shared[CBuffer]( + c_addr, c_size) + self.init( buffer) + + cdef class ResizableBuffer(Buffer): cdef void init_rz(self, const shared_ptr[CResizableBuffer]& buffer): diff --git a/python/pyarrow/lib.pxd b/python/pyarrow/lib.pxd index e4d574f18b3..c37bc2bebe7 100644 --- a/python/pyarrow/lib.pxd +++ b/python/pyarrow/lib.pxd @@ -324,6 +324,11 @@ cdef class Buffer: cdef int _check_nullptr(self) except -1 +cdef class ForeignBuffer(Buffer): + cdef: + object base + + cdef class ResizableBuffer(Buffer): cdef void init_rz(self, const shared_ptr[CResizableBuffer]& buffer) diff --git a/python/pyarrow/tests/test_io.py b/python/pyarrow/tests/test_io.py index d269ad0e7cd..17aca43331f 100644 --- a/python/pyarrow/tests/test_io.py +++ b/python/pyarrow/tests/test_io.py @@ -24,6 +24,7 @@ import weakref import numpy as np +import numpy.testing as npt import pandas as pd @@ -253,6 +254,14 @@ def test_buffer_equals(): assert buf2.equals(buf5) +def test_foreign_buffer(): + n = np.array([1, 2]) + addr = n.__array_interface__["data"][0] + size = n.nbytes + fb = pa.ForeignBuffer(addr, size, n) + npt.assert_array_equal(np.asarray(fb), n.view(dtype=np.int8)) + + def test_allocate_buffer(): buf = pa.allocate_buffer(100) assert buf.size == 100