kylebarron commented on issue #5067:
URL: https://github.com/apache/arrow-rs/issues/5067#issuecomment-1807204531
I took a quick stab at this but got stuck. In particular, I tried:
```rs
use arrow::array::ArrayData;
use arrow::ffi;
use pyo3::exceptions::{PyTypeError, PyValueError};
use pyo3::prelude::*;
use pyo3::types::{PyCapsule, PyTuple};
use pyo3::{PyAny, PyResult};
pub fn pyobj_to_array(ob: &'_ PyAny) -> PyResult<ArrayData> {
if ob.hasattr("__arrow_c_array__")? {
let tuple = ob.getattr("__arrow_c_array__")?.call0()?;
if !tuple.is_instance_of::<PyTuple>() {
return Err(PyTypeError::new_err(
"Expected __arrow_c_array__ to return a tuple.",
));
}
let schema_capsule = tuple.get_item(0)?;
if !schema_capsule.is_instance_of::<PyCapsule>() {
return Err(PyTypeError::new_err(
"Expected __arrow_c_array__ first element to be PyCapsule.",
));
}
let schema_capsule: &PyCapsule =
PyTryInto::try_into(schema_capsule)?;
let schema_capsule_name = schema_capsule.name()?;
if schema_capsule_name.is_none() {
return Err(PyValueError::new_err(
"Expected PyCapsule to have name set.",
));
}
let schema_capsule_name = schema_capsule_name.unwrap().to_str()?;
if schema_capsule_name != "arrow_schema" {
return Err(PyValueError::new_err(
"Expected name 'arrow_schema' in PyCapsule.",
));
}
let array_capsule = tuple.get_item(1)?;
if !array_capsule.is_instance_of::<PyCapsule>() {
return Err(PyTypeError::new_err(
"Expected __arrow_c_array__ second element to be PyCapsule.",
));
}
let array_capsule: &PyCapsule = PyTryInto::try_into(array_capsule)?;
let array_capsule_name = array_capsule.name()?;
if array_capsule_name.is_none() {
return Err(PyValueError::new_err(
"Expected PyCapsule to have name set.",
));
}
let array_capsule_name = array_capsule_name.unwrap().to_str()?;
if array_capsule_name != "arrow_array" {
return Err(PyValueError::new_err(
"Expected name 'arrow_array' in PyCapsule.",
));
}
let arr = unsafe {
ffi::from_ffi(
*array_capsule.reference::<ffi::FFI_ArrowArray>(),
schema_capsule.reference::<ffi::FFI_ArrowSchema>(),
)
.unwrap()
};
return Ok(arr);
}
Err(PyValueError::new_err(
"Expected an object with dunder __arrow_c_array__",
))
}
```
but this doesn't work because of
```
error[E0507]: cannot move out of a shared reference
--> src/ffi2.rs:60:17
|
60 | *array_capsule.reference::<ffi::FFI_ArrowArray>(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move
occurs because value has type `arrow::ffi::FFI_ArrowArray`, which does not
implement the `Copy` trait
```
This has a different setup because instead of provisioning FFI structs
ourselves for python to export into, python exports its _own_ ffi structs
inside the capsule. Maybe I'm missing something in the pyo3 api to get an owned
pointer, but I assume that's not possible.
I figure here that the arrow-rs ffi code would need to be changed to allow a
reference to a `FFI_ArrowArray` struct, just like it does with the schema? It
would then just have to check that `released` on the struct is not `true`
before importing..?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]