Path: blob/main/crates/polars-python/src/series/c_interface.rs
7889 views
#![allow(unsafe_op_in_unsafe_fn)]1use polars::prelude::*;2use pyo3::ffi::Py_uintptr_t;3use pyo3::prelude::*;45use super::PySeries;6use crate::error::PyPolarsErr;78// Import arrow data directly without requiring pyarrow (used in pyo3-polars)9#[pymethods]10impl PySeries {11#[staticmethod]12unsafe fn _import_arrow_from_c(13name: &str,14chunks: Vec<(Py_uintptr_t, Py_uintptr_t)>,15) -> PyResult<Self> {16let chunks = chunks17.into_iter()18.map(|(schema_ptr, array_ptr)| {19let schema_ptr = schema_ptr as *mut arrow::ffi::ArrowSchema;20let array_ptr = array_ptr as *mut arrow::ffi::ArrowArray;2122// Don't take the box from raw as the other process must deallocate that memory.23let array = std::ptr::read_unaligned(array_ptr);24let schema = &*schema_ptr;2526let field = arrow::ffi::import_field_from_c(schema).unwrap();27arrow::ffi::import_array_from_c(array, field.dtype).unwrap()28})29.collect::<Vec<_>>();3031let s = Series::try_new(name.into(), chunks).map_err(PyPolarsErr::from)?;32Ok(s.into())33}3435unsafe fn _export_arrow_to_c(36&self,37out_ptr: Py_uintptr_t,38out_schema_ptr: Py_uintptr_t,39) -> PyResult<()> {40export_chunk(&self.series.read(), out_ptr, out_schema_ptr).map_err(PyPolarsErr::from)?;41Ok(())42}43}4445unsafe fn export_chunk(46s: &Series,47out_ptr: Py_uintptr_t,48out_schema_ptr: Py_uintptr_t,49) -> PolarsResult<()> {50polars_ensure!(s.chunks().len() == 1, InvalidOperation: "expect a single chunk");5152let c_array = arrow::ffi::export_array_to_c(s.chunks()[0].clone());53let out_ptr = out_ptr as *mut arrow::ffi::ArrowArray;54*out_ptr = c_array;5556let field = ArrowField::new(57s.name().clone(),58s.dtype().to_arrow(CompatLevel::newest()),59true,60);61let c_schema = arrow::ffi::export_field_to_c(&field);6263let out_schema_ptr = out_schema_ptr as *mut arrow::ffi::ArrowSchema;64*out_schema_ptr = c_schema;65Ok(())66}676869