From a041de6bae703a2c8fa3e3b31cd863d4801101d2 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Sat, 22 Feb 2025 13:16:27 -0500 Subject: [PATCH] Add into_arro3 method (#289) * Add into_arro3 method * Bump to 0.7.2 * Bump to 0.7.2 --- Cargo.lock | 23 ++++++++++++----------- pyo3-arrow/CHANGELOG.md | 8 ++++++++ pyo3-arrow/Cargo.lock | 2 +- pyo3-arrow/Cargo.toml | 2 +- pyo3-arrow/src/array.rs | 11 +++++++++++ pyo3-arrow/src/array_reader.rs | 22 ++++++++++++++++++---- pyo3-arrow/src/chunked.rs | 11 +++++++++++ pyo3-arrow/src/datatypes.rs | 10 ++++++++++ pyo3-arrow/src/field.rs | 10 ++++++++++ pyo3-arrow/src/record_batch.rs | 9 +++++++++ pyo3-arrow/src/record_batch_reader.rs | 22 ++++++++++++++++++++-- pyo3-arrow/src/scalar.rs | 11 +++++++++++ pyo3-arrow/src/schema.rs | 10 ++++++++++ pyo3-arrow/src/table.rs | 11 +++++++++++ 14 files changed, 143 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31982fc..f822d23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1749,12 +1749,13 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.23.3" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e484fd2c8b4cb67ab05a318f1fd6fa8f199fcc30819f08f07d200809dba26c15" +checksum = "57fe09249128b3173d092de9523eaa75136bf7ba85e0d69eca241c7939c933cc" dependencies = [ "cfg-if", "chrono", + "chrono-tz", "indexmap", "indoc", "libc", @@ -1769,7 +1770,7 @@ dependencies = [ [[package]] name = "pyo3-arrow" -version = "0.7.0" +version = "0.7.1" dependencies = [ "arrow", "arrow-array", @@ -1798,9 +1799,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.23.3" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e0469a84f208e20044b98965e1561028180219e35352a2afaf2b942beff3b" +checksum = "1cd3927b5a78757a0d71aa9dff669f903b1eb64b54142a9bd9f757f8fde65fd7" dependencies = [ "once_cell", "target-lexicon", @@ -1808,9 +1809,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.23.3" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1547a7f9966f6f1a0f0227564a9945fe36b90da5a93b3933fc3dc03fae372d" +checksum = "dab6bb2102bd8f991e7749f130a70d05dd557613e39ed2deeee8e9ca0c4d548d" dependencies = [ "libc", "pyo3-build-config", @@ -1828,9 +1829,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.23.3" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb6da8ec6fa5cedd1626c886fc8749bdcbb09424a86461eb8cdf096b7c33257" +checksum = "91871864b353fd5ffcb3f91f2f703a22a9797c91b9ab497b1acac7b07ae509c7" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -1840,9 +1841,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.23.3" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38a385202ff5a92791168b1136afae5059d3ac118457bb7bc304c197c2d33e7d" +checksum = "43abc3b80bc20f3facd86cd3c60beed58c3e2aa26213f3cda368de39c60a27e4" dependencies = [ "heck", "proc-macro2", diff --git a/pyo3-arrow/CHANGELOG.md b/pyo3-arrow/CHANGELOG.md index 05dc771..97e00af 100644 --- a/pyo3-arrow/CHANGELOG.md +++ b/pyo3-arrow/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.7.2] - 2025-02-22 + +### What's Changed + +- Add `into_arro3` method https://github.com/kylebarron/arro3/pull/289 + +**Full Changelog**: https://github.com/kylebarron/arro3/compare/pyo3-arrow-v0.7.1...pyo3-arrow-v0.7.2 + ## [0.7.1] - 2025-02-21 ### What's Changed diff --git a/pyo3-arrow/Cargo.lock b/pyo3-arrow/Cargo.lock index 89bf158..8e6e0b3 100644 --- a/pyo3-arrow/Cargo.lock +++ b/pyo3-arrow/Cargo.lock @@ -821,7 +821,7 @@ dependencies = [ [[package]] name = "pyo3-arrow" -version = "0.7.1" +version = "0.7.2" dependencies = [ "arrow", "arrow-array", diff --git a/pyo3-arrow/Cargo.toml b/pyo3-arrow/Cargo.toml index fe9bfbd..424ccdf 100644 --- a/pyo3-arrow/Cargo.toml +++ b/pyo3-arrow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pyo3-arrow" -version = "0.7.1" +version = "0.7.2" authors = ["Kyle Barron "] edition = "2021" description = "Arrow integration for pyo3." diff --git a/pyo3-arrow/src/array.rs b/pyo3-arrow/src/array.rs index b0fc7e2..7f358e9 100644 --- a/pyo3-arrow/src/array.rs +++ b/pyo3-arrow/src/array.rs @@ -108,6 +108,17 @@ impl PyArray { ) } + /// Export to an arro3.core.Array. + /// + /// This requires that you depend on arro3-core from your Python package. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let array_capsules = to_array_pycapsules(py, self.field.clone(), &self.array, None)?; + arro3_mod + .getattr(intern!(py, "Array"))? + .call_method1(intern!(py, "from_arrow_pycapsule"), array_capsules) + } + /// Export this to a Python `nanoarrow.Array`. pub fn to_nanoarrow<'py>(&'py self, py: Python<'py>) -> PyResult> { to_nanoarrow_array(py, &self.__arrow_c_array__(py, None)?) diff --git a/pyo3-arrow/src/array_reader.rs b/pyo3-arrow/src/array_reader.rs index 984d995..771d365 100644 --- a/pyo3-arrow/src/array_reader.rs +++ b/pyo3-arrow/src/array_reader.rs @@ -78,7 +78,6 @@ impl PyArrayReader { } /// Export this to a Python `arro3.core.ArrayReader`. - #[allow(clippy::wrong_self_convention)] pub fn to_arro3<'py>(&'py self, py: Python<'py>) -> PyResult> { let arro3_mod = py.import(intern!(py, "arro3.core"))?; arro3_mod.getattr(intern!(py, "ArrayReader"))?.call_method1( @@ -87,8 +86,23 @@ impl PyArrayReader { ) } + /// Export this to a Python `arro3.core.ArrayReader`. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let array_reader = self + .0 + .lock() + .unwrap() + .take() + .ok_or(PyIOError::new_err("Cannot read from closed stream"))?; + let stream_pycapsule = to_stream_pycapsule(py, array_reader, None)?; + arro3_mod.getattr(intern!(py, "ArrayReader"))?.call_method1( + intern!(py, "from_arrow_pycapsule"), + PyTuple::new(py, vec![stream_pycapsule])?, + ) + } + /// Export this to a Python `nanoarrow.ArrayStream`. - #[allow(clippy::wrong_self_convention)] pub fn to_nanoarrow<'py>(&'py self, py: Python<'py>) -> PyResult> { to_nanoarrow_array_stream(py, &self.__arrow_c_stream__(py, None)?) } @@ -135,8 +149,8 @@ impl PyArrayReader { // Return self // https://stackoverflow.com/a/52056290 - fn __iter__<'py>(&'py self, py: Python<'py>) -> PyResult> { - self.to_arro3(py) + fn __iter__(slf: PyRef) -> PyRef { + slf } fn __next__(&self) -> PyArrowResult { diff --git a/pyo3-arrow/src/chunked.rs b/pyo3-arrow/src/chunked.rs index e501e43..e02ab77 100644 --- a/pyo3-arrow/src/chunked.rs +++ b/pyo3-arrow/src/chunked.rs @@ -197,6 +197,17 @@ impl PyChunkedArray { ) } + /// Export this to a Python `arro3.core.ChunkedArray`. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let capsule = Self::to_stream_pycapsule(py, self.chunks.clone(), self.field.clone(), None)?; + arro3_mod + .getattr(intern!(py, "ChunkedArray"))? + .call_method1( + intern!(py, "from_arrow_pycapsule"), + PyTuple::new(py, vec![capsule])?, + ) + } /// Export this to a Python `nanoarrow.ArrayStream`. pub fn to_nanoarrow<'py>(&'py self, py: Python<'py>) -> PyResult> { to_nanoarrow_array_stream(py, &self.__arrow_c_stream__(py, None)?) diff --git a/pyo3-arrow/src/datatypes.rs b/pyo3-arrow/src/datatypes.rs index 84e1ee6..fdb46be 100644 --- a/pyo3-arrow/src/datatypes.rs +++ b/pyo3-arrow/src/datatypes.rs @@ -63,6 +63,16 @@ impl PyDataType { ) } + /// Export this to a Python `arro3.core.DataType`. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let capsule = to_schema_pycapsule(py, &self.0)?; + arro3_mod.getattr(intern!(py, "DataType"))?.call_method1( + intern!(py, "from_arrow_pycapsule"), + PyTuple::new(py, vec![capsule])?, + ) + } + /// Export this to a Python `nanoarrow.Schema`. pub fn to_nanoarrow<'py>(&'py self, py: Python<'py>) -> PyResult> { to_nanoarrow_schema(py, &self.__arrow_c_schema__(py)?) diff --git a/pyo3-arrow/src/field.rs b/pyo3-arrow/src/field.rs index 22a16e0..cea8303 100644 --- a/pyo3-arrow/src/field.rs +++ b/pyo3-arrow/src/field.rs @@ -51,6 +51,16 @@ impl PyField { ) } + /// Export this to a Python `arro3.core.Field`. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let capsule = to_schema_pycapsule(py, self.0.as_ref())?; + arro3_mod.getattr(intern!(py, "Field"))?.call_method1( + intern!(py, "from_arrow_pycapsule"), + PyTuple::new(py, vec![capsule])?, + ) + } + /// Export this to a Python `nanoarrow.Schema`. pub fn to_nanoarrow<'py>(&'py self, py: Python<'py>) -> PyResult> { to_nanoarrow_schema(py, &self.__arrow_c_schema__(py)?) diff --git a/pyo3-arrow/src/record_batch.rs b/pyo3-arrow/src/record_batch.rs index 590f0ab..8a956f3 100644 --- a/pyo3-arrow/src/record_batch.rs +++ b/pyo3-arrow/src/record_batch.rs @@ -90,6 +90,15 @@ impl PyRecordBatch { ) } + /// Export this to a Python `arro3.core.RecordBatch`. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let capsules = Self::to_array_pycapsules(py, self.0.clone(), None)?; + arro3_mod + .getattr(intern!(py, "RecordBatch"))? + .call_method1(intern!(py, "from_arrow_pycapsule"), capsules) + } + /// Export this to a Python `nanoarrow.Array`. pub fn to_nanoarrow<'py>(&'py self, py: Python<'py>) -> PyResult> { to_nanoarrow_array(py, &self.__arrow_c_array__(py, None)?) diff --git a/pyo3-arrow/src/record_batch_reader.rs b/pyo3-arrow/src/record_batch_reader.rs index 66e799b..d8e5b89 100644 --- a/pyo3-arrow/src/record_batch_reader.rs +++ b/pyo3-arrow/src/record_batch_reader.rs @@ -96,6 +96,24 @@ impl PyRecordBatchReader { ) } + /// Export this to a Python `arro3.core.RecordBatchReader`. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let reader = self + .0 + .lock() + .unwrap() + .take() + .ok_or(PyIOError::new_err("Cannot read from closed stream"))?; + let capsule = Self::to_stream_pycapsule(py, reader, None)?; + arro3_mod + .getattr(intern!(py, "RecordBatchReader"))? + .call_method1( + intern!(py, "from_arrow_pycapsule"), + PyTuple::new(py, vec![capsule])?, + ) + } + /// Export this to a Python `nanoarrow.ArrayStream`. pub fn to_nanoarrow<'py>(&'py self, py: Python<'py>) -> PyResult> { to_nanoarrow_array_stream(py, &self.__arrow_c_stream__(py, None)?) @@ -175,8 +193,8 @@ impl PyRecordBatchReader { // Return self // https://stackoverflow.com/a/52056290 - fn __iter__<'py>(&'py self, py: Python<'py>) -> PyResult> { - self.to_arro3(py) + fn __iter__(slf: PyRef) -> PyRef { + slf } fn __next__(&self) -> PyArrowResult { diff --git a/pyo3-arrow/src/scalar.rs b/pyo3-arrow/src/scalar.rs index 3821be1..2e021d9 100644 --- a/pyo3-arrow/src/scalar.rs +++ b/pyo3-arrow/src/scalar.rs @@ -94,6 +94,17 @@ impl PyScalar { self.__arrow_c_array__(py, None)?, ) } + + /// Export to an arro3.core.Scalar. + /// + /// This requires that you depend on arro3-core from your Python package. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let capsules = to_array_pycapsules(py, self.field.clone(), &self.array, None)?; + arro3_mod + .getattr(intern!(py, "Scalar"))? + .call_method1(intern!(py, "from_arrow_pycapsule"), capsules) + } } impl Display for PyScalar { diff --git a/pyo3-arrow/src/schema.rs b/pyo3-arrow/src/schema.rs index 1552f56..865b691 100644 --- a/pyo3-arrow/src/schema.rs +++ b/pyo3-arrow/src/schema.rs @@ -51,6 +51,16 @@ impl PySchema { ) } + /// Export this to a Python `arro3.core.Schema`. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let capsule = to_schema_pycapsule(py, self.0.as_ref())?; + arro3_mod.getattr(intern!(py, "Schema"))?.call_method1( + intern!(py, "from_arrow_pycapsule"), + PyTuple::new(py, vec![capsule])?, + ) + } + /// Export this to a Python `nanoarrow.Schema`. pub fn to_nanoarrow<'py>(&'py self, py: Python<'py>) -> PyResult> { to_nanoarrow_schema(py, &self.__arrow_c_schema__(py)?) diff --git a/pyo3-arrow/src/table.rs b/pyo3-arrow/src/table.rs index 5786a8d..37f6c49 100644 --- a/pyo3-arrow/src/table.rs +++ b/pyo3-arrow/src/table.rs @@ -87,6 +87,17 @@ impl PyTable { ) } + /// Export this to a Python `arro3.core.Table`. + pub fn into_arro3(self, py: Python) -> PyResult> { + let arro3_mod = py.import(intern!(py, "arro3.core"))?; + let capsule = + Self::to_stream_pycapsule(py, self.batches.clone(), self.schema.clone(), None)?; + arro3_mod.getattr(intern!(py, "Table"))?.call_method1( + intern!(py, "from_arrow_pycapsule"), + PyTuple::new(py, vec![capsule])?, + ) + } + /// Export this to a Python `nanoarrow.ArrayStream`. pub fn to_nanoarrow<'py>(&'py self, py: Python<'py>) -> PyResult> { to_nanoarrow_array_stream(py, &self.__arrow_c_stream__(py, None)?)