Skip to content

Commit a1bf651

Browse files
committed
fix: use fastpath for PyCapsule export when starting from pyarrow-backed Series, respect requested_schema
1 parent 078e11f commit a1bf651

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

pandas/core/series.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
validate_all_hashable,
7878
)
7979
from pandas.core.dtypes.dtypes import (
80+
ArrowDtype,
8081
CategoricalDtype,
8182
ExtensionDtype,
8283
SparseDtype,
@@ -580,8 +581,19 @@ def __arrow_c_stream__(self, requested_schema=None):
580581
PyCapsule
581582
"""
582583
pa = import_optional_dependency("pyarrow", min_version="16.0.0")
583-
ca = pa.chunked_array([pa.Array.from_pandas(self, type=requested_schema)])
584-
return ca.__arrow_c_stream__(requested_schema)
584+
type = (
585+
pa.DataType._import_from_c_capsule(requested_schema)
586+
if requested_schema is not None
587+
else None
588+
)
589+
if isinstance(self.dtype, ArrowDtype):
590+
# fastpath!
591+
ca = self.values._pa_array
592+
if type is not None:
593+
ca = ca.cast(type)
594+
else:
595+
ca = pa.chunked_array([pa.Array.from_pandas(self, type=type)])
596+
return ca.__arrow_c_stream__()
585597

586598
# ----------------------------------------------------------------------
587599

pandas/tests/series/test_arrow_interface.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,25 @@ def test_series_arrow_interface():
2121
ca = pa.chunked_array(s)
2222
expected = pa.chunked_array([[1, 4, 2]])
2323
assert ca.equals(expected)
24+
ca = pa.chunked_array(s, type=pa.int32())
25+
expected = pa.chunked_array([[1, 4, 2]], type=pa.int32())
26+
assert ca.equals(expected)
27+
28+
29+
def test_series_arrow_interface_arrow_dtypes():
30+
s = pd.Series([1, 4, 2], dtype="Int64[pyarrow]")
31+
32+
capsule = s.__arrow_c_stream__()
33+
assert (
34+
ctypes.pythonapi.PyCapsule_IsValid(
35+
ctypes.py_object(capsule), b"arrow_array_stream"
36+
)
37+
== 1
38+
)
39+
40+
ca = pa.chunked_array(s)
41+
expected = pa.chunked_array([[1, 4, 2]])
42+
assert ca.equals(expected)
43+
ca = pa.chunked_array(s, type=pa.int32())
44+
expected = pa.chunked_array([[1, 4, 2]], type=pa.int32())
45+
assert ca.equals(expected)

0 commit comments

Comments
 (0)