diff --git a/crates/polars-python/src/cloud.rs b/crates/polars-python/src/cloud.rs index 19d4f6dfda07..08379da8e955 100644 --- a/crates/polars-python/src/cloud.rs +++ b/crates/polars-python/src/cloud.rs @@ -14,11 +14,11 @@ use crate::lazyframe::visit::NodeTraverser; use crate::{PyDataFrame, PyLazyFrame}; #[pyfunction] -pub fn prepare_cloud_plan(lf: PyLazyFrame, py: Python) -> PyResult { +pub fn prepare_cloud_plan(lf: PyLazyFrame, py: Python<'_>) -> PyResult> { let plan = lf.ldf.logical_plan; let bytes = polars::prelude::prepare_cloud_plan(plan).map_err(PyPolarsErr::from)?; - Ok(PyBytes::new_bound(py, &bytes).to_object(py)) + Ok(PyBytes::new(py, &bytes)) } /// Take a serialized `IRPlan` and execute it on the GPU engine. @@ -62,13 +62,13 @@ fn gpu_post_opt( expr_arena: &mut Arena, ) -> PolarsResult<()> { // Get cuDF Python function. - let cudf = PyModule::import_bound(py, intern!(py, "cudf_polars")).unwrap(); + let cudf = PyModule::import(py, intern!(py, "cudf_polars")).unwrap(); let lambda = cudf.getattr(intern!(py, "execute_with_cudf")).unwrap(); // Define cuDF config. - let polars = PyModule::import_bound(py, intern!(py, "polars")).unwrap(); + let polars = PyModule::import(py, intern!(py, "polars")).unwrap(); let engine = polars.getattr(intern!(py, "GPUEngine")).unwrap(); - let kwargs = [("raise_on_fail", true)].into_py_dict_bound(py); + let kwargs = [("raise_on_fail", true)].into_py_dict(py).unwrap(); let engine = engine.call((), Some(&kwargs)).unwrap(); // Define node traverser. @@ -79,7 +79,7 @@ fn gpu_post_opt( // Pass the node visitor which allows the Python callback to replace parts of the query plan. // Remove "cuda" or specify better once we have multiple post-opt callbacks. - let kwargs = [("config", engine)].into_py_dict_bound(py); + let kwargs = [("config", engine)].into_py_dict(py).unwrap(); lambda .call((nt,), Some(&kwargs)) .map_err(|e| polars_err!(ComputeError: "'cuda' conversion failed: {}", e))?; diff --git a/crates/polars-python/src/conversion/any_value.rs b/crates/polars-python/src/conversion/any_value.rs index bdc0e13c8d7c..1ba0b988f5c8 100644 --- a/crates/polars-python/src/conversion/any_value.rs +++ b/crates/polars-python/src/conversion/any_value.rs @@ -107,8 +107,8 @@ pub(crate) fn any_value_into_py_object(av: AnyValue, py: Python) -> PyObject { let object = v.0.as_any().downcast_ref::().unwrap(); object.inner.clone_ref(py) }, - AnyValue::Binary(v) => PyBytes::new_bound(py, v).into_py(py), - AnyValue::BinaryOwned(v) => PyBytes::new_bound(py, &v).into_py(py), + AnyValue::Binary(v) => PyBytes::new(py, v).into_py(py), + AnyValue::BinaryOwned(v) => PyBytes::new(py, &v).into_py(py), AnyValue::Decimal(v, scale) => { let convert = utils.getattr(intern!(py, "to_py_decimal")).unwrap(); const N: usize = 3; @@ -351,7 +351,7 @@ pub(crate) fn py_object_to_any_value<'py>( // This constructor is able to go via dedicated type constructors // so it can be much faster. let py = ob.py(); - let kwargs = PyDict::new_bound(py); + let kwargs = PyDict::new(py); kwargs.set_item("strict", strict)?; let s = SERIES.call_bound(py, (ob,), Some(&kwargs))?; get_list_from_series(s.bind(py), strict) diff --git a/crates/polars-python/src/conversion/chunked_array.rs b/crates/polars-python/src/conversion/chunked_array.rs index 404fe68ce8ef..0761baea7f44 100644 --- a/crates/polars-python/src/conversion/chunked_array.rs +++ b/crates/polars-python/src/conversion/chunked_array.rs @@ -23,7 +23,7 @@ impl ToPyObject for Wrap<&BinaryChunked> { let iter = self .0 .iter() - .map(|opt_bytes| opt_bytes.map(|bytes| PyBytes::new_bound(py, bytes))); + .map(|opt_bytes| opt_bytes.map(|bytes| PyBytes::new(py, bytes))); PyList::new_bound(py, iter).into_py(py) } } diff --git a/crates/polars-python/src/conversion/mod.rs b/crates/polars-python/src/conversion/mod.rs index a20f1ff4af32..6251e8c15822 100644 --- a/crates/polars-python/src/conversion/mod.rs +++ b/crates/polars-python/src/conversion/mod.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + pub(crate) mod any_value; pub(crate) mod chunked_array; mod datetime; @@ -149,7 +151,7 @@ fn struct_dict<'a>( vals: impl Iterator>, flds: &[Field], ) -> PyObject { - let dict = PyDict::new_bound(py); + let dict = PyDict::new(py); for (fld, val) in flds.iter().zip(vals) { dict.set_item(fld.name().as_str(), Wrap(val).into_py(py)) .unwrap() @@ -597,7 +599,7 @@ impl<'py> FromPyObject<'py> for Wrap { impl IntoPy for Wrap<&Schema> { fn into_py(self, py: Python<'_>) -> PyObject { - let dict = PyDict::new_bound(py); + let dict = PyDict::new(py); for (k, v) in self.0.iter() { dict.set_item(k.as_str(), Wrap(v.clone()).to_object(py)) .unwrap(); diff --git a/crates/polars-python/src/dataframe/construction.rs b/crates/polars-python/src/dataframe/construction.rs index 8520caf220d9..df051cab1741 100644 --- a/crates/polars-python/src/dataframe/construction.rs +++ b/crates/polars-python/src/dataframe/construction.rs @@ -145,7 +145,7 @@ fn dicts_to_rows<'a>( ) -> PyResult>> { let len = data.len()?; let mut rows = Vec::with_capacity(len); - for d in data.iter()? { + for d in data.try_iter()? { let d = d?; let d = d.downcast::()?; @@ -189,7 +189,7 @@ fn infer_schema_names_from_data( .unwrap_or(data_len); let mut names = PlIndexSet::new(); - for d in data.iter()?.take(infer_schema_length) { + for d in data.try_iter()?.take(infer_schema_length) { let d = d?; let d = d.downcast::()?; let keys = d.keys(); diff --git a/crates/polars-python/src/dataframe/export.rs b/crates/polars-python/src/dataframe/export.rs index 7486d9742467..e32c918a6d43 100644 --- a/crates/polars-python/src/dataframe/export.rs +++ b/crates/polars-python/src/dataframe/export.rs @@ -15,7 +15,7 @@ use crate::prelude::PyCompatLevel; #[pymethods] impl PyDataFrame { #[cfg(feature = "object")] - pub fn row_tuple(&self, idx: i64) -> PyResult { + pub fn row_tuple<'py>(&self, idx: i64, py: Python<'py>) -> PyResult> { let idx = if idx < 0 { (self.df.height() as i64 + idx) as usize } else { @@ -24,64 +24,57 @@ impl PyDataFrame { if idx >= self.df.height() { return Err(PyPolarsErr::from(polars_err!(oob = idx, self.df.height())).into()); } - let out = Python::with_gil(|py| { - PyTuple::new_bound( - py, - self.df.get_columns().iter().map(|s| match s.dtype() { - DataType::Object(_, _) => { - let obj: Option<&ObjectValue> = s.get_object(idx).map(|any| any.into()); - obj.to_object(py) - }, - _ => Wrap(s.get(idx).unwrap()).into_py(py), - }), - ) - .into_py(py) - }); - Ok(out) + PyTuple::new( + py, + self.df.get_columns().iter().map(|s| match s.dtype() { + DataType::Object(_, _) => { + let obj: Option<&ObjectValue> = s.get_object(idx).map(|any| any.into()); + obj.to_object(py) + }, + _ => Wrap(s.get(idx).unwrap()).into_py(py), + }), + ) } #[cfg(feature = "object")] - pub fn row_tuples(&self) -> PyObject { - Python::with_gil(|py| { - let mut rechunked; - // Rechunk if random access would become rather expensive. - // TODO: iterate over the chunks directly instead of using random access. - let df = if self.df.max_n_chunks() > 16 { - rechunked = self.df.clone(); - rechunked.as_single_chunk_par(); - &rechunked - } else { - &self.df - }; - PyList::new_bound( - py, - (0..df.height()).map(|idx| { - PyTuple::new_bound( - py, - df.get_columns().iter().map(|c| match c.dtype() { - DataType::Null => py.None(), - DataType::Object(_, _) => { - let obj: Option<&ObjectValue> = - c.get_object(idx).map(|any| any.into()); - obj.to_object(py) - }, - _ => { - // SAFETY: we are in bounds. - let av = unsafe { c.get_unchecked(idx) }; - Wrap(av).into_py(py) - }, - }), - ) - }), - ) - .into_py(py) - }) + pub fn row_tuples<'py>(&self, py: Python<'py>) -> PyResult> { + let mut rechunked; + // Rechunk if random access would become rather expensive. + // TODO: iterate over the chunks directly instead of using random access. + let df = if self.df.max_n_chunks() > 16 { + rechunked = self.df.clone(); + rechunked.as_single_chunk_par(); + &rechunked + } else { + &self.df + }; + PyList::new( + py, + (0..df.height()).map(|idx| { + PyTuple::new( + py, + df.get_columns().iter().map(|c| match c.dtype() { + DataType::Null => py.None(), + DataType::Object(_, _) => { + let obj: Option<&ObjectValue> = c.get_object(idx).map(|any| any.into()); + obj.to_object(py) + }, + _ => { + // SAFETY: we are in bounds. + let av = unsafe { c.get_unchecked(idx) }; + Wrap(av).into_py(py) + }, + }), + ) + .unwrap() + }), + ) } #[allow(clippy::wrong_self_convention)] pub fn to_arrow(&mut self, py: Python, compat_level: PyCompatLevel) -> PyResult> { py.allow_threads(|| self.df.align_chunks_par()); - let pyarrow = py.import_bound("pyarrow")?; + let pyarrow = py.import("pyarrow")?; let names = self.df.get_column_names_str(); let rbs = self @@ -101,7 +94,7 @@ impl PyDataFrame { pub fn to_pandas(&mut self, py: Python) -> PyResult> { py.allow_threads(|| self.df.as_single_chunk_par()); Python::with_gil(|py| { - let pyarrow = py.import_bound("pyarrow")?; + let pyarrow = py.import("pyarrow")?; let names = self.df.get_column_names_str(); let cat_columns = self .df diff --git a/crates/polars-python/src/dataframe/general.rs b/crates/polars-python/src/dataframe/general.rs index 1c2f94368275..b6d091905a11 100644 --- a/crates/polars-python/src/dataframe/general.rs +++ b/crates/polars-python/src/dataframe/general.rs @@ -180,12 +180,12 @@ impl PyDataFrame { } /// Get datatypes - pub fn dtypes(&self, py: Python) -> PyObject { + pub fn dtypes<'py>(&self, py: Python<'py>) -> PyResult> { let iter = self .df .iter() .map(|s| Wrap(s.dtype().clone()).to_object(py)); - PyList::new_bound(py, iter).to_object(py) + PyList::new(py, iter) } pub fn n_chunks(&self) -> usize { @@ -402,7 +402,7 @@ impl PyDataFrame { let function = move |df: DataFrame| { Python::with_gil(|py| { - let pypolars = PyModule::import_bound(py, "polars").unwrap(); + let pypolars = PyModule::import(py, "polars").unwrap(); let pydf = PyDataFrame::new(df); let python_df_wrapper = pypolars.getattr("wrap_df").unwrap().call1((pydf,)).unwrap(); @@ -410,7 +410,7 @@ impl PyDataFrame { // Call the lambda and get a python-side DataFrame wrapper. let result_df_wrapper = match lambda.call1(py, (python_df_wrapper,)) { Ok(pyobj) => pyobj, - Err(e) => panic!("UDF failed: {}", e.value_bound(py)), + Err(e) => panic!("UDF failed: {}", e.value(py)), }; let py_pydf = result_df_wrapper.getattr(py, "_df").expect( "Could not get DataFrame attribute '_df'. Make sure that you return a DataFrame object.", diff --git a/crates/polars-python/src/dataframe/mod.rs b/crates/polars-python/src/dataframe/mod.rs index fbd514ab2c03..cdadb6298148 100644 --- a/crates/polars-python/src/dataframe/mod.rs +++ b/crates/polars-python/src/dataframe/mod.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + #[cfg(feature = "pymethods")] mod construction; #[cfg(feature = "pymethods")] diff --git a/crates/polars-python/src/dataframe/serde.rs b/crates/polars-python/src/dataframe/serde.rs index b08d2bd5ed85..e111cab24526 100644 --- a/crates/polars-python/src/dataframe/serde.rs +++ b/crates/polars-python/src/dataframe/serde.rs @@ -15,14 +15,14 @@ use crate::file::{get_file_like, get_mmap_bytes_reader}; #[pymethods] impl PyDataFrame { #[cfg(feature = "ipc_streaming")] - fn __getstate__(&self, py: Python) -> PyResult { + fn __getstate__<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> { // Used in pickle/pickling let mut buf: Vec = vec![]; IpcStreamWriter::new(&mut buf) .with_compat_level(CompatLevel::newest()) .finish(&mut self.df.clone()) .expect("ipc writer"); - Ok(PyBytes::new_bound(py, &buf).to_object(py)) + PyBytes::new(py, &buf) } #[cfg(feature = "ipc_streaming")] diff --git a/crates/polars-python/src/error.rs b/crates/polars-python/src/error.rs index 1a84ad5517fb..dc04883ebeb1 100644 --- a/crates/polars-python/src/error.rs +++ b/crates/polars-python/src/error.rs @@ -102,16 +102,20 @@ macro_rules! raise_err( }} ); -impl IntoPy for Wrap { - fn into_py(self, py: Python<'_>) -> PyObject { +impl<'py> IntoPyObject<'py> for Wrap { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = std::convert::Infallible; + + fn into_pyobject(self, py: Python<'py>) -> Result { match self.0 { PolarsWarning::CategoricalRemappingWarning => { - CategoricalRemappingWarning::type_object_bound(py).to_object(py) + Ok(CategoricalRemappingWarning::type_object(py).into_any()) }, PolarsWarning::MapWithoutReturnDtypeWarning => { - MapWithoutReturnDtypeWarning::type_object_bound(py).to_object(py) + Ok(MapWithoutReturnDtypeWarning::type_object(py).into_any()) }, - PolarsWarning::UserWarning => PyUserWarning::type_object_bound(py).to_object(py), + PolarsWarning::UserWarning => Ok(PyUserWarning::type_object(py).into_any()), } } } diff --git a/crates/polars-python/src/expr/mod.rs b/crates/polars-python/src/expr/mod.rs index 93a00018a683..56fdd2f001fd 100644 --- a/crates/polars-python/src/expr/mod.rs +++ b/crates/polars-python/src/expr/mod.rs @@ -1,3 +1,4 @@ +#![allow(deprecated)] #[cfg(feature = "pymethods")] mod array; #[cfg(feature = "pymethods")] diff --git a/crates/polars-python/src/expr/serde.rs b/crates/polars-python/src/expr/serde.rs index 9933e9a979b1..949005f08389 100644 --- a/crates/polars-python/src/expr/serde.rs +++ b/crates/polars-python/src/expr/serde.rs @@ -18,7 +18,7 @@ impl PyExpr { ciborium::ser::into_writer(&self.inner, &mut writer) .map_err(|e| PyPolarsErr::Other(format!("{}", e)))?; - Ok(PyBytes::new_bound(py, &writer).to_object(py)) + Ok(PyBytes::new(py, &writer).to_object(py)) } fn __setstate__(&mut self, state: &Bound) -> PyResult<()> { diff --git a/crates/polars-python/src/file.rs b/crates/polars-python/src/file.rs index 6bc91de65f21..028cbbdd40db 100644 --- a/crates/polars-python/src/file.rs +++ b/crates/polars-python/src/file.rs @@ -13,6 +13,7 @@ use polars_error::polars_err; use pyo3::exceptions::PyTypeError; use pyo3::prelude::*; use pyo3::types::{PyBytes, PyString, PyStringMethods}; +use pyo3::IntoPyObjectExt; use crate::error::PyPolarsErr; use crate::prelude::resolve_homedir; @@ -51,7 +52,7 @@ impl PyFileLikeObject { let buf = Python::with_gil(|py| { let bytes = self .inner - .call_method_bound(py, "read", (), None) + .call_method(py, "read", (), None) .expect("no read method found"); if let Ok(bytes) = bytes.downcast_bound::(py) { @@ -106,9 +107,9 @@ impl PyFileLikeObject { /// Extracts a string repr from, and returns an IO error to send back to rust. fn pyerr_to_io_err(e: PyErr) -> io::Error { Python::with_gil(|py| { - let e_as_object: PyObject = e.into_py(py); + let e_as_object: PyObject = e.into_py_any(py).unwrap(); - match e_as_object.call_method_bound(py, "__str__", (), None) { + match e_as_object.call_method(py, "__str__", (), None) { Ok(repr) => match repr.extract::(py) { Ok(s) => io::Error::new(io::ErrorKind::Other, s), Err(_e) => io::Error::new(io::ErrorKind::Other, "An unknown error has occurred"), @@ -123,7 +124,7 @@ impl Read for PyFileLikeObject { Python::with_gil(|py| { let bytes = self .inner - .call_method_bound(py, "read", (buf.len(),), None) + .call_method(py, "read", (buf.len(),), None) .map_err(pyerr_to_io_err)?; let opt_bytes = bytes.downcast_bound::(py); @@ -149,11 +150,11 @@ impl Read for PyFileLikeObject { impl Write for PyFileLikeObject { fn write(&mut self, buf: &[u8]) -> Result { Python::with_gil(|py| { - let pybytes = PyBytes::new_bound(py, buf); + let pybytes = PyBytes::new(py, buf); let number_bytes_written = self .inner - .call_method_bound(py, "write", (pybytes,), None) + .call_method(py, "write", (pybytes,), None) .map_err(pyerr_to_io_err)?; number_bytes_written.extract(py).map_err(pyerr_to_io_err) @@ -163,7 +164,7 @@ impl Write for PyFileLikeObject { fn flush(&mut self) -> Result<(), io::Error> { Python::with_gil(|py| { self.inner - .call_method_bound(py, "flush", (), None) + .call_method(py, "flush", (), None) .map_err(pyerr_to_io_err)?; Ok(()) @@ -182,7 +183,7 @@ impl Seek for PyFileLikeObject { let new_position = self .inner - .call_method_bound(py, "seek", (offset, whence), None) + .call_method(py, "seek", (offset, whence), None) .map_err(pyerr_to_io_err)?; new_position.extract(py).map_err(pyerr_to_io_err) @@ -235,7 +236,7 @@ pub fn get_python_scan_source_input( let file_path = resolve_homedir(file_path); Ok(PythonScanSourceInput::Path(file_path)) } else { - let io = py.import_bound("io").unwrap(); + let io = py.import("io").unwrap(); let is_utf8_encoding = |py_f: &Bound| -> PyResult { let encoding = py_f.getattr("encoding")?; let encoding = encoding.extract::>()?; @@ -316,7 +317,7 @@ pub fn get_python_scan_source_input( }; PyFileLikeObject::ensure_requirements(&py_f, !write, write, !write)?; Ok(PythonScanSourceInput::Buffer( - PyFileLikeObject::new(py_f.to_object(py)).as_bytes(), + PyFileLikeObject::new(py_f.unbind()).as_bytes(), )) } }) @@ -338,7 +339,7 @@ fn get_either_buffer_or_path( }; Ok((EitherRustPythonFile::Rust(f), Some(file_path))) } else { - let io = py.import_bound("io").unwrap(); + let io = py.import("io").unwrap(); let is_utf8_encoding = |py_f: &Bound| -> PyResult { let encoding = py_f.getattr("encoding")?; let encoding = encoding.extract::>()?; @@ -420,7 +421,7 @@ fn get_either_buffer_or_path( py_f }; PyFileLikeObject::ensure_requirements(&py_f, !write, write, !write)?; - let f = PyFileLikeObject::new(py_f.to_object(py)); + let f = PyFileLikeObject::new(py_f.unbind()); Ok((EitherRustPythonFile::Py(f), None)) } }) @@ -467,7 +468,7 @@ pub fn get_mmap_bytes_reader_and_path<'a>( } // string so read file else { - match get_either_buffer_or_path(py_f.to_object(py_f.py()), false)? { + match get_either_buffer_or_path(py_f.to_owned().unbind(), false)? { (EitherRustPythonFile::Rust(f), path) => Ok((Box::new(f), path)), (EitherRustPythonFile::Py(f), path) => Ok((Box::new(f), path)), } diff --git a/crates/polars-python/src/functions/io.rs b/crates/polars-python/src/functions/io.rs index fe681ce648e2..e7c09064f62f 100644 --- a/crates/polars-python/src/functions/io.rs +++ b/crates/polars-python/src/functions/io.rs @@ -24,7 +24,7 @@ pub fn read_ipc_schema(py: Python, py_f: PyObject) -> PyResult { EitherRustPythonFile::Py(mut r) => read_file_metadata(&mut r).map_err(PyPolarsErr::from)?, }; - let dict = PyDict::new_bound(py); + let dict = PyDict::new(py); fields_to_pydict(&metadata.schema, &dict, py)?; Ok(dict.to_object(py)) } @@ -42,7 +42,7 @@ pub fn read_parquet_schema(py: Python, py_f: PyObject) -> PyResult { }; let arrow_schema = infer_schema(&metadata).map_err(PyPolarsErr::from)?; - let dict = PyDict::new_bound(py); + let dict = PyDict::new(py); fields_to_pydict(&arrow_schema, &dict, py)?; Ok(dict.to_object(py)) } diff --git a/crates/polars-python/src/functions/mod.rs b/crates/polars-python/src/functions/mod.rs index ddf58c7acde6..7242f3d83719 100644 --- a/crates/polars-python/src/functions/mod.rs +++ b/crates/polars-python/src/functions/mod.rs @@ -1,3 +1,4 @@ +#![allow(deprecated)] mod aggregation; mod business; mod eager; diff --git a/crates/polars-python/src/interop/mod.rs b/crates/polars-python/src/interop/mod.rs index c46c7c692607..957c37901373 100644 --- a/crates/polars-python/src/interop/mod.rs +++ b/crates/polars-python/src/interop/mod.rs @@ -1,2 +1,3 @@ +#![allow(deprecated)] pub mod arrow; pub mod numpy; diff --git a/crates/polars-python/src/interop/numpy/to_numpy_df.rs b/crates/polars-python/src/interop/numpy/to_numpy_df.rs index 887d218f5fe0..73f9fcafaf06 100644 --- a/crates/polars-python/src/interop/numpy/to_numpy_df.rs +++ b/crates/polars-python/src/interop/numpy/to_numpy_df.rs @@ -278,7 +278,7 @@ fn df_columns_to_numpy( arr }); - let numpy = PyModule::import_bound(py, intern!(py, "numpy"))?; + let numpy = PyModule::import(py, intern!(py, "numpy"))?; let np_array = match order { IndexOrder::C => numpy .getattr(intern!(py, "column_stack")) diff --git a/crates/polars-python/src/lazyframe/general.rs b/crates/polars-python/src/lazyframe/general.rs index a3126f9ad090..6aee24465934 100644 --- a/crates/polars-python/src/lazyframe/general.rs +++ b/crates/polars-python/src/lazyframe/general.rs @@ -1223,7 +1223,7 @@ impl PyLazyFrame { .allow_threads(|| self.ldf.collect_schema()) .map_err(PyPolarsErr::from)?; - let schema_dict = PyDict::new_bound(py); + let schema_dict = PyDict::new(py); schema.iter_fields().for_each(|fld| { schema_dict .set_item(fld.name().as_str(), Wrap(fld.dtype().clone()).to_object(py)) diff --git a/crates/polars-python/src/lazyframe/mod.rs b/crates/polars-python/src/lazyframe/mod.rs index 85433332e415..7ad03295c041 100644 --- a/crates/polars-python/src/lazyframe/mod.rs +++ b/crates/polars-python/src/lazyframe/mod.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + mod exitable; #[cfg(feature = "pymethods")] mod general; diff --git a/crates/polars-python/src/lazyframe/serde.rs b/crates/polars-python/src/lazyframe/serde.rs index fa51fa9efb37..126652df2298 100644 --- a/crates/polars-python/src/lazyframe/serde.rs +++ b/crates/polars-python/src/lazyframe/serde.rs @@ -19,7 +19,7 @@ impl PyLazyFrame { ciborium::ser::into_writer(&self.ldf.logical_plan, &mut writer) .map_err(|e| PyPolarsErr::Other(format!("{}", e)))?; - Ok(PyBytes::new_bound(py, &writer).to_object(py)) + Ok(PyBytes::new(py, &writer).to_object(py)) } fn __setstate__(&mut self, py: Python, state: PyObject) -> PyResult<()> { diff --git a/crates/polars-python/src/lazygroupby.rs b/crates/polars-python/src/lazygroupby.rs index d2ed68f3d568..21e48ac4890d 100644 --- a/crates/polars-python/src/lazygroupby.rs +++ b/crates/polars-python/src/lazygroupby.rs @@ -51,7 +51,7 @@ impl PyLazyGroupBy { let function = move |df: DataFrame| { Python::with_gil(|py| { // get the pypolars module - let pypolars = PyModule::import_bound(py, "polars").unwrap(); + let pypolars = PyModule::import(py, "polars").unwrap(); // create a PyDataFrame struct/object for Python let pydf = PyDataFrame::new(df); diff --git a/crates/polars-python/src/lib.rs b/crates/polars-python/src/lib.rs index 801853d4e5fa..dee0efe4a710 100644 --- a/crates/polars-python/src/lib.rs +++ b/crates/polars-python/src/lib.rs @@ -3,7 +3,6 @@ #![allow(non_local_definitions)] #![allow(clippy::too_many_arguments)] // Python functions can have many arguments due to default arguments #![allow(clippy::disallowed_types)] -#![allow(deprecated)] #[cfg(feature = "csv")] pub mod batched_csv; diff --git a/crates/polars-python/src/map/lazy.rs b/crates/polars-python/src/map/lazy.rs index 77389b974085..12ace2216659 100644 --- a/crates/polars-python/src/map/lazy.rs +++ b/crates/polars-python/src/map/lazy.rs @@ -11,7 +11,7 @@ pub(crate) trait ToSeries { fn to_series( &self, py: Python, - py_polars_module: &PyObject, + py_polars_module: &Py, name: &str, ) -> PolarsResult; } @@ -20,7 +20,7 @@ impl ToSeries for PyObject { fn to_series( &self, py: Python, - py_polars_module: &PyObject, + py_polars_module: &Py, name: &str, ) -> PolarsResult { let py_pyseries = match self.getattr(py, "_s") { @@ -30,7 +30,7 @@ impl ToSeries for PyObject { let res = py_polars_module .getattr(py, "Series") .unwrap() - .call1(py, (name, PyList::new_bound(py, [self]))); + .call1(py, (name, PyList::new(py, [self]).unwrap())); match res { Ok(python_s) => python_s.getattr(py, "_s").unwrap(), @@ -52,10 +52,10 @@ impl ToSeries for PyObject { // multiple chunks Err(_) => { use polars::export::arrow::ffi; - let kwargs = PyDict::new_bound(py); + let kwargs = PyDict::new(py); kwargs.set_item("in_place", true).unwrap(); py_pyseries - .call_method_bound(py, "rechunk", (), Some(&kwargs)) + .call_method(py, "rechunk", (), Some(&kwargs)) .map_err(|e| polars_err!(ComputeError: "could not rechunk: {e}"))?; // Prepare a pointer to receive the Array struct. @@ -90,7 +90,7 @@ pub(crate) fn call_lambda_with_series( s: Series, lambda: &PyObject, ) -> PyResult { - let pypolars = POLARS.downcast_bound::(py).unwrap(); + let pypolars = POLARS.bind(py); // create a PySeries struct/object for Python let pyseries = PySeries::new(s); @@ -112,7 +112,7 @@ pub(crate) fn binary_lambda( ) -> PolarsResult> { Python::with_gil(|py| { // get the pypolars module - let pypolars = PyModule::import_bound(py, "polars").unwrap(); + let pypolars = PyModule::import(py, "polars").unwrap(); // create a PySeries struct/object for Python let pyseries_a = PySeries::new(a); let pyseries_b = PySeries::new(b); @@ -134,7 +134,7 @@ pub(crate) fn binary_lambda( match lambda.call1(py, (python_series_wrapper_a, python_series_wrapper_b)) { Ok(pyobj) => pyobj, Err(e) => polars_bail!( - ComputeError: "custom python function failed: {}", e.value_bound(py), + ComputeError: "custom python function failed: {}", e.value(py), ), }; let pyseries = if let Ok(expr) = result_series_wrapper.getattr(py, "_pyexpr") { @@ -151,8 +151,7 @@ pub(crate) fn binary_lambda( let s = out.select_at_idx(0).unwrap().clone(); PySeries::new(s.take_materialized_series()) } else { - return Some(result_series_wrapper.to_series(py, &pypolars.into_py(py), "")) - .transpose(); + return Some(result_series_wrapper.to_series(py, &pypolars.unbind(), "")).transpose(); }; // Finally get the actual Series @@ -179,9 +178,9 @@ pub(crate) fn call_lambda_with_columns_slice( py: Python, s: &[Column], lambda: &PyObject, - polars_module: &PyObject, + polars_module: &Py, ) -> PyObject { - let pypolars = polars_module.downcast_bound::(py).unwrap(); + let pypolars = polars_module.bind(py); // create a PySeries struct/object for Python let iter = s.iter().map(|s| { @@ -192,12 +191,12 @@ pub(crate) fn call_lambda_with_columns_slice( python_series_wrapper }); - let wrapped_s = PyList::new_bound(py, iter); + let wrapped_s = PyList::new(py, iter).unwrap(); // call the lambda and get a python side Series wrapper match lambda.call1(py, (wrapped_s,)) { Ok(pyobj) => pyobj, - Err(e) => panic!("python function failed: {}", e.value_bound(py)), + Err(e) => panic!("python function failed: {}", e.value(py)), } } @@ -211,7 +210,7 @@ pub fn map_mul( ) -> PyExpr { // get the pypolars module // do the import outside of the function to prevent import side effects in a hot loop. - let pypolars = PyModule::import_bound(py, "polars").unwrap().to_object(py); + let pypolars = PyModule::import(py, "polars").unwrap().unbind(); let function = move |s: &mut [Column]| { Python::with_gil(|py| { diff --git a/crates/polars-python/src/map/mod.rs b/crates/polars-python/src/map/mod.rs index 9ffc74961302..b4b0f1019696 100644 --- a/crates/polars-python/src/map/mod.rs +++ b/crates/polars-python/src/map/mod.rs @@ -1,3 +1,4 @@ +#![allow(deprecated)] pub mod dataframe; pub mod lazy; pub mod series; diff --git a/crates/polars-python/src/map/series.rs b/crates/polars-python/src/map/series.rs index 4c51f85c5b55..6745e2a82708 100644 --- a/crates/polars-python/src/map/series.rs +++ b/crates/polars-python/src/map/series.rs @@ -41,7 +41,7 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>( applyer .apply_lambda_with_list_out_type( py, - lambda.to_object(py), + lambda.to_owned().unbind(), null_count, Some(&series), dt, @@ -65,15 +65,16 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>( // make a new python function that is: // def new_lambda(lambda: Callable): // pl.Series(lambda(value)) - let lambda_owned = lambda.to_object(py); - let new_lambda = PyCFunction::new_closure_bound(py, None, None, move |args, _kwargs| { + let lambda_owned = lambda.to_owned().unbind(); + let new_lambda = PyCFunction::new_closure(py, None, None, move |args, _kwargs| { Python::with_gil(|py| { let out = lambda_owned.call1(py, args)?; // check if Series, if not, call series constructor on it SERIES.call1(py, (out,)) }) })? - .to_object(py); + .into_any() + .unbind(); let result = applyer .apply_lambda_with_list_out_type(py, new_lambda, null_count, Some(&series), dt) @@ -116,7 +117,7 @@ fn infer_and_finish<'a, A: ApplyLambda<'a>>( py, lambda, null_count, - Some(out.to_object(py).into()), + Some(out.to_owned().unbind().into()), ) .map(|ca| ca.into_series().into()) } @@ -1177,7 +1178,7 @@ fn call_series_lambda( impl<'a> ApplyLambda<'a> for ListChunked { fn apply_lambda_unknown(&'a self, py: Python, lambda: &Bound<'a, PyAny>) -> PyResult { - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; let mut null_count = 0; for opt_v in self.into_iter() { if let Some(v) = opt_v { @@ -1214,7 +1215,7 @@ impl<'a> ApplyLambda<'a> for ListChunked { ) -> PyResult { let skip = 1; // get the pypolars module - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if !self.has_nulls() { let it = self .into_no_null_iter() @@ -1278,7 +1279,7 @@ impl<'a> ApplyLambda<'a> for ListChunked { D::Native: ToPyObject + FromPyObject<'a>, { let skip = usize::from(first_value.is_some()); - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) } else if !self.has_nulls() { @@ -1338,7 +1339,7 @@ impl<'a> ApplyLambda<'a> for ListChunked { first_value: Option, ) -> PyResult { let skip = usize::from(first_value.is_some()); - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) } else if !self.has_nulls() { @@ -1399,7 +1400,7 @@ impl<'a> ApplyLambda<'a> for ListChunked { ) -> PyResult { let skip = usize::from(first_value.is_some()); // get the pypolars module - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) @@ -1461,7 +1462,7 @@ impl<'a> ApplyLambda<'a> for ListChunked { dt: &DataType, ) -> PyResult { let skip = usize::from(first_value.is_some()); - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; let lambda = lambda.bind(py); if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) @@ -1502,7 +1503,7 @@ impl<'a> ApplyLambda<'a> for ListChunked { init_null_count: usize, first_value: AnyValue<'a>, ) -> PyResult { - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; let mut avs = Vec::with_capacity(self.len()); avs.extend(std::iter::repeat(AnyValue::Null).take(init_null_count)); avs.push(first_value); @@ -1549,7 +1550,7 @@ impl<'a> ApplyLambda<'a> for ListChunked { first_value: Option, ) -> PyResult> { let skip = usize::from(first_value.is_some()); - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) } else if !self.has_nulls() { @@ -1606,7 +1607,7 @@ impl<'a> ApplyLambda<'a> for ListChunked { #[cfg(feature = "dtype-array")] impl<'a> ApplyLambda<'a> for ArrayChunked { fn apply_lambda_unknown(&'a self, py: Python, lambda: &Bound<'a, PyAny>) -> PyResult { - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; let mut null_count = 0; for opt_v in self.into_iter() { if let Some(v) = opt_v { @@ -1643,7 +1644,7 @@ impl<'a> ApplyLambda<'a> for ArrayChunked { ) -> PyResult { let skip = 1; // get the pypolars module - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if !self.has_nulls() { let it = self .into_no_null_iter() @@ -1707,7 +1708,7 @@ impl<'a> ApplyLambda<'a> for ArrayChunked { D::Native: ToPyObject + FromPyObject<'a>, { let skip = usize::from(first_value.is_some()); - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) } else if !self.has_nulls() { @@ -1767,7 +1768,7 @@ impl<'a> ApplyLambda<'a> for ArrayChunked { first_value: Option, ) -> PyResult { let skip = usize::from(first_value.is_some()); - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) } else if !self.has_nulls() { @@ -1828,7 +1829,7 @@ impl<'a> ApplyLambda<'a> for ArrayChunked { ) -> PyResult { let skip = usize::from(first_value.is_some()); // get the pypolars module - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) @@ -1890,7 +1891,7 @@ impl<'a> ApplyLambda<'a> for ArrayChunked { dt: &DataType, ) -> PyResult { let skip = usize::from(first_value.is_some()); - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; let lambda = lambda.bind(py); if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) @@ -1931,7 +1932,7 @@ impl<'a> ApplyLambda<'a> for ArrayChunked { init_null_count: usize, first_value: AnyValue<'a>, ) -> PyResult { - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; let mut avs = Vec::with_capacity(self.len()); avs.extend(std::iter::repeat(AnyValue::Null).take(init_null_count)); avs.push(first_value); @@ -1978,7 +1979,7 @@ impl<'a> ApplyLambda<'a> for ArrayChunked { first_value: Option, ) -> PyResult> { let skip = usize::from(first_value.is_some()); - let pypolars = PyModule::import_bound(py, "polars")?; + let pypolars = PyModule::import(py, "polars")?; if init_null_count == self.len() { Ok(ChunkedArray::full_null(self.name().clone(), self.len())) } else if !self.has_nulls() { diff --git a/crates/polars-python/src/on_startup.rs b/crates/polars-python/src/on_startup.rs index 629620c3710a..2ac57030d6b1 100644 --- a/crates/polars-python/src/on_startup.rs +++ b/crates/polars-python/src/on_startup.rs @@ -59,7 +59,7 @@ fn warning_function(msg: &str, warning: PolarsWarning) { Python::with_gil(|py| { let warn_fn = UTILS.bind(py).getattr(intern!(py, "_polars_warn")).unwrap(); - if let Err(e) = warn_fn.call1((msg, Wrap(warning).into_py(py))) { + if let Err(e) = warn_fn.call1((msg, Wrap(warning).into_pyobject(py).unwrap())) { eprintln!("{e}") } }); @@ -83,6 +83,7 @@ pub fn register_startup_deps() { let object_converter = Arc::new(|av: AnyValue| { let object = Python::with_gil(|py| ObjectValue { + #[allow(deprecated)] inner: Wrap(av).to_object(py), }); Box::new(object) as Box diff --git a/crates/polars-python/src/py_modules.rs b/crates/polars-python/src/py_modules.rs index c193644faef0..71e0f7690293 100644 --- a/crates/polars-python/src/py_modules.rs +++ b/crates/polars-python/src/py_modules.rs @@ -1,9 +1,8 @@ use once_cell::sync::Lazy; use pyo3::prelude::*; -pub(crate) static POLARS: Lazy = Lazy::new(|| { - Python::with_gil(|py| PyModule::import_bound(py, "polars").unwrap().to_object(py)) -}); +pub(crate) static POLARS: Lazy> = + Lazy::new(|| Python::with_gil(|py| PyModule::import(py, "polars").unwrap().unbind())); pub(crate) static UTILS: Lazy = Lazy::new(|| Python::with_gil(|py| POLARS.getattr(py, "_utils").unwrap())); diff --git a/crates/polars-python/src/series/export.rs b/crates/polars-python/src/series/export.rs index 959b2dd47293..1aa69aa954de 100644 --- a/crates/polars-python/src/series/export.rs +++ b/crates/polars-python/src/series/export.rs @@ -149,7 +149,7 @@ impl PySeries { #[allow(clippy::wrong_self_convention)] fn to_arrow(&mut self, py: Python, compat_level: PyCompatLevel) -> PyResult { self.rechunk(py, true); - let pyarrow = py.import_bound("pyarrow")?; + let pyarrow = py.import("pyarrow")?; interop::arrow::to_py::to_py_array(self.series.to_arrow(0, compat_level.0), py, &pyarrow) } diff --git a/crates/polars-python/src/series/general.rs b/crates/polars-python/src/series/general.rs index 431343519d47..df0e70bca8f0 100644 --- a/crates/polars-python/src/series/general.rs +++ b/crates/polars-python/src/series/general.rs @@ -408,7 +408,7 @@ impl PySeries { .with_compat_level(CompatLevel::newest()) .finish(&mut df) .expect("ipc writer"); - Ok(PyBytes::new_bound(py, &buf).to_object(py)) + Ok(PyBytes::new(py, &buf).to_object(py)) } #[cfg(feature = "ipc_streaming")] diff --git a/crates/polars-python/src/series/map.rs b/crates/polars-python/src/series/map.rs index f003096f7dc9..14d581ca1ecd 100644 --- a/crates/polars-python/src/series/map.rs +++ b/crates/polars-python/src/series/map.rs @@ -229,7 +229,7 @@ impl PySeries { let function_owned = function.to_object(py); let dtype_py = Wrap((*inner).clone()).to_object(py); let function_wrapped = - PyCFunction::new_closure_bound(py, None, None, move |args, _kwargs| { + PyCFunction::new_closure(py, None, None, move |args, _kwargs| { Python::with_gil(|py| { let out = function_owned.call1(py, args)?; SERIES.call1(py, ("", out, dtype_py.clone_ref(py))) diff --git a/crates/polars-python/src/series/mod.rs b/crates/polars-python/src/series/mod.rs index 0c1ecbc40b1c..ee8206f81666 100644 --- a/crates/polars-python/src/series/mod.rs +++ b/crates/polars-python/src/series/mod.rs @@ -1,3 +1,4 @@ +#![allow(deprecated)] #[cfg(feature = "pymethods")] mod aggregation; #[cfg(feature = "pymethods")] diff --git a/crates/polars-python/src/series/numpy_ufunc.rs b/crates/polars-python/src/series/numpy_ufunc.rs index 5df438686447..81668df7a21a 100644 --- a/crates/polars-python/src/series/numpy_ufunc.rs +++ b/crates/polars-python/src/series/numpy_ufunc.rs @@ -84,8 +84,7 @@ macro_rules! impl_ufuncs { // We're not going to allocate the output array. // Instead, we'll let the ufunc do it. let result = lambda.call1((PyNone::get_bound(py),))?; - let series_factory = - PyModule::import_bound(py, "polars")?.getattr("Series")?; + let series_factory = PyModule::import(py, "polars")?.getattr("Series")?; return series_factory .call((self.name(), result), None)? .getattr("_s")?