diff --git a/crates/polars-python/src/lazyframe/visitor/expr_nodes.rs b/crates/polars-python/src/lazyframe/visitor/expr_nodes.rs index f5076433c84d..94f50c2b3658 100644 --- a/crates/polars-python/src/lazyframe/visitor/expr_nodes.rs +++ b/crates/polars-python/src/lazyframe/visitor/expr_nodes.rs @@ -1,3 +1,4 @@ +#![allow(deprecated)] #[cfg(feature = "iejoin")] use polars::prelude::InequalityOperator; use polars::series::ops::NullBehavior; diff --git a/crates/polars-python/src/lazyframe/visitor/mod.rs b/crates/polars-python/src/lazyframe/visitor/mod.rs index 8e4ea93de0f4..39af9e064b73 100644 --- a/crates/polars-python/src/lazyframe/visitor/mod.rs +++ b/crates/polars-python/src/lazyframe/visitor/mod.rs @@ -1,3 +1,2 @@ -#![allow(deprecated)] pub mod expr_nodes; pub mod nodes; diff --git a/crates/polars-python/src/lazyframe/visitor/nodes.rs b/crates/polars-python/src/lazyframe/visitor/nodes.rs index 0cf040171900..b4de93612fd0 100644 --- a/crates/polars-python/src/lazyframe/visitor/nodes.rs +++ b/crates/polars-python/src/lazyframe/visitor/nodes.rs @@ -6,7 +6,6 @@ use polars_plan::prelude::{ }; use pyo3::exceptions::{PyNotImplementedError, PyValueError}; use pyo3::prelude::*; -#[cfg(feature = "iejoin")] use pyo3::IntoPyObjectExt; use super::expr_nodes::PyGroupbyOptions; @@ -49,43 +48,37 @@ pub struct PyFileOptions { #[pymethods] impl PyFileOptions { #[getter] - fn n_rows(&self, py: Python<'_>) -> PyResult { - Ok(self - .inner - .slice - .map_or_else(|| py.None(), |n| n.into_py(py))) + fn n_rows(&self) -> Option<(i64, usize)> { + self.inner.slice } #[getter] - fn with_columns(&self, py: Python<'_>) -> PyResult { - Ok(self.inner.with_columns.as_ref().map_or_else( - || py.None(), - |cols| { - cols.iter() - .map(|x| x.as_str()) - .collect::>() - .to_object(py) - }, - )) + fn with_columns(&self) -> Option> { + self.inner + .with_columns + .as_ref()? + .iter() + .map(|x| x.as_str()) + .collect::>() + .into() } #[getter] - fn cache(&self, _py: Python<'_>) -> PyResult { - Ok(self.inner.cache) + fn cache(&self, _py: Python<'_>) -> bool { + self.inner.cache } #[getter] - fn row_index(&self, py: Python<'_>) -> PyResult { - Ok(self - .inner + fn row_index(&self) -> Option<(&str, IdxSize)> { + self.inner .row_index .as_ref() - .map_or_else(|| py.None(), |n| (n.name.as_str(), n.offset).to_object(py))) + .map(|n| (n.name.as_str(), n.offset)) } #[getter] - fn rechunk(&self, _py: Python<'_>) -> PyResult { - Ok(self.inner.rechunk) + fn rechunk(&self, _py: Python<'_>) -> bool { + self.inner.rechunk } #[getter] - fn file_counter(&self, _py: Python<'_>) -> PyResult { - Ok(self.inner.file_counter) + fn file_counter(&self, _py: Python<'_>) -> FileCount { + self.inner.file_counter } #[getter] fn hive_options(&self, _py: Python<'_>) -> PyResult { @@ -262,7 +255,7 @@ pub struct Sink { } pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { - let result = match plan { + match plan { IR::PythonScan { options } => { let python_src = match options.python_source { PythonScanSource::Pyarrow => "pyarrow", @@ -277,47 +270,45 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { .as_ref() .map_or_else(|| py.None(), |s| s.0.clone_ref(py)), options.with_columns.as_ref().map_or_else( - || py.None(), + || Ok(py.None()), |cols| { cols.iter() .map(|x| x.as_str()) .collect::>() - .to_object(py) + .into_py_any(py) }, - ), + )?, python_src, match &options.predicate { PythonPredicate::None => py.None(), - PythonPredicate::PyArrow(s) => ("pyarrow", s).to_object(py), - PythonPredicate::Polars(e) => ("polars", e.node().0).to_object(py), + PythonPredicate::PyArrow(s) => ("pyarrow", s).into_py_any(py)?, + PythonPredicate::Polars(e) => ("polars", e.node().0).into_py_any(py)?, }, options .n_rows - .map_or_else(|| py.None(), |s| s.to_object(py)), + .map_or_else(|| Ok(py.None()), |s| s.into_py_any(py))?, ) - .to_object(py), + .into_py_any(py)?, } - .into_py(py) + .into_py_any(py) }, IR::Slice { input, offset, len } => Slice { input: input.0, offset: *offset, len: *len, } - .into_py(py), + .into_py_any(py), IR::Filter { input, predicate } => Filter { input: input.0, predicate: predicate.into(), } - .into_py(py), + .into_py_any(py), IR::Scan { hive_parts: Some(_), .. - } => { - return Err(PyNotImplementedError::new_err( - "scan with hive partitioning", - )) - }, + } => Err(PyNotImplementedError::new_err( + "scan with hive partitioning", + )), IR::Scan { sources, file_info: _, @@ -330,7 +321,7 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { paths: sources .into_paths() .ok_or_else(|| PyNotImplementedError::new_err("scan with BytesIO"))? - .to_object(py), + .into_py_any(py)?, // TODO: file info file_info: py.None(), predicate: predicate.as_ref().map(|e| e.into()), @@ -349,7 +340,7 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { .map_err(|err| PyValueError::new_err(format!("{err:?}")))?; let cloud_options = serde_json::to_string(cloud_options) .map_err(|err| PyValueError::new_err(format!("{err:?}")))?; - ("csv", options, cloud_options).into_py(py) + ("csv", options, cloud_options).into_py_any(py)? }, #[cfg(feature = "parquet")] FileScan::Parquet { @@ -361,7 +352,7 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { .map_err(|err| PyValueError::new_err(format!("{err:?}")))?; let cloud_options = serde_json::to_string(cloud_options) .map_err(|err| PyValueError::new_err(format!("{err:?}")))?; - ("parquet", options, cloud_options).into_py(py) + ("parquet", options, cloud_options).into_py_any(py)? }, #[cfg(feature = "ipc")] FileScan::Ipc { .. } => return Err(PyNotImplementedError::new_err("ipc scan")), @@ -370,14 +361,14 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { // TODO: Also pass cloud_options let options = serde_json::to_string(options) .map_err(|err| PyValueError::new_err(format!("{err:?}")))?; - ("ndjson", options).into_py(py) + ("ndjson", options).into_py_any(py)? }, FileScan::Anonymous { .. } => { return Err(PyNotImplementedError::new_err("anonymous scan")) }, }, } - .into_py(py), + .into_py_any(py), IR::DataFrameScan { df, schema: _, @@ -386,19 +377,19 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { } => DataFrameScan { df: PyDataFrame::new((**df).clone()), projection: output_schema.as_ref().map_or_else( - || py.None(), + || Ok(py.None()), |s| { s.iter_names() .map(|s| s.as_str()) .collect::>() - .to_object(py) + .into_py_any(py) }, - ), + )?, selection: selection.as_ref().map(|e| e.into()), } - .into_py(py), + .into_py_any(py), IR::SimpleProjection { input, columns: _ } => { - SimpleProjection { input: input.0 }.into_py(py) + SimpleProjection { input: input.0 }.into_py_any(py) }, IR::Select { input, @@ -410,7 +401,7 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { input: input.0, should_broadcast: options.should_broadcast, } - .into_py(py), + .into_py_any(py), IR::Sort { input, by_column, @@ -426,7 +417,7 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { ), slice: *slice, } - .into_py(py), + .into_py_any(py), IR::Cache { input, id, @@ -436,7 +427,7 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { id_: *id, cache_hits: *cache_hits, } - .into_py(py), + .into_py_any(py), IR::GroupBy { input, keys, @@ -456,9 +447,9 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { ))) })?, maintain_order: *maintain_order, - options: PyGroupbyOptions::new(options.as_ref().clone()).into_py(py), + options: PyGroupbyOptions::new(options.as_ref().clone()).into_py_any(py)?, } - .into_py(py), + .into_py_any(py), IR::Join { input_left, input_right, @@ -473,7 +464,7 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { right_on: right_on.iter().map(|e| e.into()).collect(), options: { let how = &options.args.how; - let name = Into::<&str>::into(how).to_object(py); + let name = Into::<&str>::into(how).into_pyobject(py)?; ( match how { #[cfg(feature = "asof_join")] @@ -485,12 +476,12 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { name, crate::Wrap(ie_options.operator1).into_py_any(py)?, ie_options.operator2.as_ref().map_or_else( - || Ok(py.None()), - |op| crate::Wrap(*op).into_py_any(py), + || py.None(), + |op| crate::Wrap(*op).into_py_any(py)?, )?, ) - .into_py(py), - _ => name, + .into_py_any(py)?, + _ => name.into_any().unbind(), }, options.args.join_nulls, options.args.slice, @@ -498,10 +489,10 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { options.args.coalesce.coalesce(how), Into::<&str>::into(options.args.maintain_order), ) - .to_object(py) + .into_py_any(py)? }, } - .into_py(py), + .into_py_any(py), IR::HStack { input, exprs, @@ -512,7 +503,7 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { exprs: exprs.iter().map(|e| e.into()).collect(), should_broadcast: options.should_broadcast, } - .into_py(py), + .into_py_any(py), IR::Reduce { input, exprs, @@ -521,26 +512,26 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { input: input.0, exprs: exprs.iter().map(|e| e.into()).collect(), } - .into_py(py), + .into_py_any(py), IR::Distinct { input, options } => Distinct { input: input.0, options: ( Into::<&str>::into(options.keep_strategy), options.subset.as_ref().map_or_else( - || py.None(), + || Ok(py.None()), |f| { f.iter() .map(|s| s.as_ref()) .collect::>() - .to_object(py) + .into_py_any(py) }, - ), + )?, options.maintain_order, options.slice, ) - .to_object(py), + .into_py_any(py)?, } - .into_py(py), + .into_py_any(py), IR::MapFunction { input, function } => MapFunction { input: input.0, function: match function { @@ -564,11 +555,11 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { "unnest", columns.iter().map(|s| s.to_string()).collect::>(), ) - .to_object(py), - FunctionIR::Rechunk => ("rechunk",).to_object(py), + .into_py_any(py)?, + FunctionIR::Rechunk => ("rechunk",).into_py_any(py)?, #[cfg(feature = "merge_sorted")] FunctionIR::MergeSorted { column } => { - ("merge_sorted", column.to_string()).to_object(py) + ("merge_sorted", column.to_string()).into_py_any(py)? }, FunctionIR::Rename { existing, @@ -581,12 +572,12 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { new.iter().map(|s| s.as_str()).collect::>(), *swapping, ) - .to_object(py), + .into_py_any(py)?, FunctionIR::Explode { columns, schema: _ } => ( "explode", columns.iter().map(|s| s.to_string()).collect::>(), ) - .to_object(py), + .into_py_any(py)?, #[cfg(feature = "pivot")] FunctionIR::Unpivot { args, schema: _ } => ( "unpivot", @@ -594,17 +585,17 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { args.on.iter().map(|s| s.as_str()).collect::>(), args.variable_name .as_ref() - .map_or_else(|| py.None(), |s| s.as_str().to_object(py)), + .map_or_else(|| Ok(py.None()), |s| s.as_str().into_py_any(py))?, args.value_name .as_ref() - .map_or_else(|| py.None(), |s| s.as_str().to_object(py)), + .map_or_else(|| Ok(py.None()), |s| s.as_str().into_py_any(py))?, ) - .to_object(py), + .into_py_any(py)?, FunctionIR::RowIndex { name, schema: _, offset, - } => ("row_index", name.to_string(), offset.unwrap_or(0)).to_object(py), + } => ("row_index", name.to_string(), offset.unwrap_or(0)).into_py_any(py)?, FunctionIR::FastCount { sources: _, scan_type: _, @@ -612,13 +603,13 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { } => return Err(PyNotImplementedError::new_err("function count")), }, } - .into_py(py), + .into_py_any(py), IR::Union { inputs, options } => Union { inputs: inputs.iter().map(|n| n.0).collect(), // TODO: rest of options options: options.slice, } - .into_py(py), + .into_py_any(py), IR::HConcat { inputs, schema: _, @@ -627,7 +618,7 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { inputs: inputs.iter().map(|n| n.0).collect(), options: (), } - .into_py(py), + .into_py_any(py), IR::ExtContext { input, contexts, @@ -636,16 +627,13 @@ pub(crate) fn into_py(py: Python<'_>, plan: &IR) -> PyResult { input: input.0, contexts: contexts.iter().map(|n| n.0).collect(), } - .into_py(py), + .into_py_any(py), IR::Sink { input: _, payload: _, - } => { - return Err(PyNotImplementedError::new_err( - "Not expecting to see a Sink node", - )) - }, - IR::Invalid => return Err(PyNotImplementedError::new_err("Invalid")), - }; - Ok(result) + } => Err(PyNotImplementedError::new_err( + "Not expecting to see a Sink node", + )), + IR::Invalid => Err(PyNotImplementedError::new_err("Invalid")), + } }