polars_python/series/
c_interface.rs

1use polars::prelude::*;
2use pyo3::ffi::Py_uintptr_t;
3use pyo3::prelude::*;
4
5use super::PySeries;
6use crate::error::PyPolarsErr;
7
8// Import arrow data directly without requiring pyarrow (used in pyo3-polars)
9#[pymethods]
10impl PySeries {
11    #[staticmethod]
12    unsafe fn _import_arrow_from_c(
13        name: &str,
14        chunks: Vec<(Py_uintptr_t, Py_uintptr_t)>,
15    ) -> PyResult<Self> {
16        let chunks = chunks
17            .into_iter()
18            .map(|(schema_ptr, array_ptr)| {
19                let schema_ptr = schema_ptr as *mut arrow::ffi::ArrowSchema;
20                let array_ptr = array_ptr as *mut arrow::ffi::ArrowArray;
21
22                // Don't take the box from raw as the other process must deallocate that memory.
23                let array = std::ptr::read_unaligned(array_ptr);
24                let schema = &*schema_ptr;
25
26                let field = arrow::ffi::import_field_from_c(schema).unwrap();
27                arrow::ffi::import_array_from_c(array, field.dtype).unwrap()
28            })
29            .collect::<Vec<_>>();
30
31        let s = Series::try_new(name.into(), chunks).map_err(PyPolarsErr::from)?;
32        Ok(s.into())
33    }
34
35    unsafe fn _export_arrow_to_c(
36        &self,
37        out_ptr: Py_uintptr_t,
38        out_schema_ptr: Py_uintptr_t,
39    ) -> PyResult<()> {
40        export_chunk(&self.series, out_ptr, out_schema_ptr).map_err(PyPolarsErr::from)?;
41        Ok(())
42    }
43}
44
45unsafe fn export_chunk(
46    s: &Series,
47    out_ptr: Py_uintptr_t,
48    out_schema_ptr: Py_uintptr_t,
49) -> PolarsResult<()> {
50    polars_ensure!(s.chunks().len() == 1, InvalidOperation: "expect a single chunk");
51
52    let c_array = arrow::ffi::export_array_to_c(s.chunks()[0].clone());
53    let out_ptr = out_ptr as *mut arrow::ffi::ArrowArray;
54    *out_ptr = c_array;
55
56    let field = ArrowField::new(
57        s.name().clone(),
58        s.dtype().to_arrow(CompatLevel::newest()),
59        true,
60    );
61    let c_schema = arrow::ffi::export_field_to_c(&field);
62
63    let out_schema_ptr = out_schema_ptr as *mut arrow::ffi::ArrowSchema;
64    *out_schema_ptr = c_schema;
65    Ok(())
66}