Path: blob/main/crates/polars-python/src/conversion/chunked_array.rs
7889 views
use chrono::NaiveTime;1use polars_compute::decimal::DecimalFmtBuffer;2use polars_core::utils::arrow::temporal_conversions::date32_to_date;3use pyo3::prelude::*;4use pyo3::types::{PyBytes, PyList, PyNone};5use pyo3::{BoundObject, intern};67use super::datetime::{8datetime_to_py_object, elapsed_offset_to_timedelta, nanos_since_midnight_to_naivetime,9};10use super::struct_dict;11use crate::prelude::*;12use crate::py_modules::pl_utils;1314impl<'py> IntoPyObject<'py> for &Wrap<&StringChunked> {15type Target = PyList;16type Output = Bound<'py, Self::Target>;17type Error = PyErr;1819fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {20let iter = self.0.iter();21PyList::new(py, iter)22}23}2425impl<'py> IntoPyObject<'py> for &Wrap<&BinaryChunked> {26type Target = PyList;27type Output = Bound<'py, Self::Target>;28type Error = PyErr;2930fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {31let iter = self32.033.iter()34.map(|opt_bytes| opt_bytes.map(|bytes| PyBytes::new(py, bytes)));35PyList::new(py, iter)36}37}3839impl<'py> IntoPyObject<'py> for &Wrap<&StructChunked> {40type Target = PyList;41type Output = Bound<'py, Self::Target>;42type Error = PyErr;43fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {44let s = self.0.clone().into_series();45let iter = s.iter().map(|av| match av {46AnyValue::Struct(_, _, flds) => struct_dict(py, av._iter_struct_av(), flds)47.unwrap()48.into_any(),49AnyValue::Null => PyNone::get(py).into_bound().into_any(),50_ => unreachable!(),51});5253PyList::new(py, iter)54}55}5657impl<'py> IntoPyObject<'py> for &Wrap<&DurationChunked> {58type Target = PyList;59type Output = Bound<'py, Self::Target>;60type Error = PyErr;6162fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {63let time_unit = self.0.time_unit();64let iter = self65.066.physical()67.iter()68.map(|opt_v| opt_v.map(|v| elapsed_offset_to_timedelta(v, time_unit)));69PyList::new(py, iter)70}71}7273impl<'py> IntoPyObject<'py> for &Wrap<&DatetimeChunked> {74type Target = PyList;75type Output = Bound<'py, Self::Target>;76type Error = PyErr;7778fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {79let time_zone = self.0.time_zone().as_ref();80let time_unit = self.0.time_unit();81let iter = self.0.physical().iter().map(|opt_v| {82opt_v.map(|v| datetime_to_py_object(py, v, time_unit, time_zone).unwrap())83});84PyList::new(py, iter)85}86}8788impl<'py> IntoPyObject<'py> for &Wrap<&TimeChunked> {89type Target = PyList;90type Output = Bound<'py, Self::Target>;91type Error = PyErr;9293fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {94let iter = time_to_pyobject_iter(self.0);95PyList::new(py, iter)96}97}9899pub(crate) fn time_to_pyobject_iter(100ca: &TimeChunked,101) -> impl '_ + ExactSizeIterator<Item = Option<NaiveTime>> {102ca.phys103.iter()104.map(move |opt_v| opt_v.map(nanos_since_midnight_to_naivetime))105}106107impl<'py> IntoPyObject<'py> for &Wrap<&DateChunked> {108type Target = PyList;109type Output = Bound<'py, Self::Target>;110type Error = PyErr;111112fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {113let iter = self114.0115.physical()116.into_iter()117.map(|opt_v| opt_v.map(date32_to_date));118PyList::new(py, iter)119}120}121122impl<'py> IntoPyObject<'py> for &Wrap<&DecimalChunked> {123type Target = PyList;124type Output = Bound<'py, Self::Target>;125type Error = PyErr;126fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {127let iter = decimal_to_pyobject_iter(py, self.0)?;128PyList::new(py, iter)129}130}131132pub(crate) fn decimal_to_pyobject_iter<'py, 'a>(133py: Python<'py>,134ca: &'a DecimalChunked,135) -> PyResult<impl ExactSizeIterator<Item = Option<Bound<'py, PyAny>>> + use<'py, 'a>> {136let utils = pl_utils(py).bind(py);137let convert = utils.getattr(intern!(py, "to_py_decimal"))?;138let py_precision = ca.precision().into_pyobject(py)?;139let mut buf = DecimalFmtBuffer::new();140Ok(ca.physical().iter().map(move |opt_v| {141opt_v.map(|v| {142let s = buf.format_dec128(v, ca.scale(), false, false);143convert.call1((&py_precision, s)).unwrap()144})145}))146}147148149