polars_python/interop/arrow/
mod.rs1use polars::prelude::{ArrowDataType, DataType};
2use polars_error::polars_err;
3use pyo3::exceptions::PyValueError;
4use pyo3::types::{PyAnyMethods, PyTuple};
5use pyo3::{Bound, IntoPyObject, PyAny, PyResult, intern, pyfunction};
6
7use crate::prelude::Wrap;
8use crate::series::import_schema_pycapsule;
9use crate::utils::to_py_err;
10
11pub mod to_py;
12pub mod to_rust;
13
14#[pyfunction]
15pub fn init_polars_schema_from_arrow_c_schema(
16 polars_schema: Bound<PyAny>,
17 schema_object: Bound<PyAny>,
18) -> PyResult<()> {
19 let py = polars_schema.py();
20
21 let schema_capsule = schema_object
22 .getattr(intern!(py, "__arrow_c_schema__"))?
23 .call0()?;
24
25 let field = import_schema_pycapsule(&schema_capsule.extract()?)?;
26
27 let ArrowDataType::Struct(fields) = field.dtype else {
28 return Err(PyValueError::new_err(format!(
29 "__arrow_c_schema__ of object passed to pl.Schema did not return struct dtype: \
30 object: {}, dtype: {:?}",
31 schema_object, &field.dtype
32 )));
33 };
34
35 for field in fields {
36 let dtype = DataType::from_arrow_field(&field);
37
38 let name = field.name.into_pyobject(py)?;
39 let dtype = Wrap(dtype).into_pyobject(py)?;
40
41 if polars_schema.contains(&name)? {
42 return Err(to_py_err(polars_err!(
43 Duplicate:
44 "arrow schema contained duplicate name: {}",
45 name
46 )));
47 }
48
49 polars_schema.set_item(name, dtype)?;
50 }
51
52 Ok(())
53}
54
55#[pyfunction]
56pub fn polars_schema_field_from_arrow_c_schema(
57 schema_object: Bound<PyAny>,
58) -> PyResult<Bound<PyTuple>> {
59 let py = schema_object.py();
60
61 let schema_capsule = schema_object
62 .getattr(intern!(py, "__arrow_c_schema__"))?
63 .call0()?;
64
65 let field = import_schema_pycapsule(&schema_capsule.extract()?)?;
66 let dtype = DataType::from_arrow_field(&field);
67
68 let name = field.name.into_pyobject(py)?.into_any();
69 let dtype = Wrap(dtype).into_pyobject(py)?.into_any();
70
71 PyTuple::new(py, [name, dtype])
72}