From 64b5ff438da3d4c7c8abd247a22593498ca51a3a Mon Sep 17 00:00:00 2001 From: Jingyi Zhao Date: Mon, 20 Jul 2026 08:22:10 -0700 Subject: [PATCH 1/2] GH-49384: [Python] Respect copy=True in ChunkedArray.__array__ --- python/pyarrow/table.pxi | 2 +- python/pyarrow/tests/test_table.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/python/pyarrow/table.pxi b/python/pyarrow/table.pxi index 1abe4235c411..0563765f1227 100644 --- a/python/pyarrow/table.pxi +++ b/python/pyarrow/table.pxi @@ -556,7 +556,7 @@ cdef class ChunkedArray(_PandasConvertible): "`np.asarray(obj)` to allow a copy when needed" ) # 'copy' can further be ignored because to_numpy() already returns a copy - values = self.to_numpy() + values = self.to_numpy().copy() if dtype is None: return values return values.astype(dtype, copy=False) diff --git a/python/pyarrow/tests/test_table.py b/python/pyarrow/tests/test_table.py index cb010f4387b6..9637ae3e3aae 100644 --- a/python/pyarrow/tests/test_table.py +++ b/python/pyarrow/tests/test_table.py @@ -144,6 +144,16 @@ def test_chunked_array_to_numpy(): assert np.array_equal(arr1, arr2) +@pytest.mark.numpy +def test_chunked_array_array_copy_true_is_writable(): + data = pa.chunked_array([[1, 2, 3]]) + result = data.__array__(copy=True) + + assert result.flags.writeable + result[0] = 99 + assert result.tolist() == [99, 2, 3] + + def test_chunked_array_mismatch_types(): msg = "chunks must all be same type" with pytest.raises(TypeError, match=msg): From 8a8f339b97bc24da56d1af47e82d9a511f723e3c Mon Sep 17 00:00:00 2001 From: Jingyi Zhao Date: Mon, 20 Jul 2026 08:39:46 -0700 Subject: [PATCH 2/2] [Python] Update ChunkedArray to respect copy parameter in to_numpy() --- python/pyarrow/table.pxi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/pyarrow/table.pxi b/python/pyarrow/table.pxi index 0563765f1227..4aa2c56159de 100644 --- a/python/pyarrow/table.pxi +++ b/python/pyarrow/table.pxi @@ -555,8 +555,9 @@ cdef class ChunkedArray(_PandasConvertible): "If using `np.array(obj, copy=False)` replace it with " "`np.asarray(obj)` to allow a copy when needed" ) - # 'copy' can further be ignored because to_numpy() already returns a copy - values = self.to_numpy().copy() + values = self.to_numpy() + if copy is True: + return np.array(values, dtype=dtype, copy=True) if dtype is None: return values return values.astype(dtype, copy=False)