From 0854cab31e6c3d58a496aace926855d50802fa9a Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Wed, 20 Mar 2024 00:02:30 +0000 Subject: [PATCH] fix deprecated gil refs in function arguments --- pyo3-macros-backend/src/pyclass.rs | 3 +- pyo3-macros-backend/src/pymethod.rs | 25 ++++-- src/coroutine.rs | 4 +- src/coroutine/waker.rs | 2 +- src/pycell.rs | 2 +- src/tests/hygiene/pymethods.rs | 52 ++++++----- src/types/bytearray.rs | 8 +- tests/test_arithmetics.rs | 86 +++++++++---------- tests/test_inheritance.rs | 4 +- tests/test_methods.rs | 75 +++++++++------- tests/test_no_imports.rs | 2 +- tests/test_proto_methods.rs | 10 +-- tests/test_pyfunction.rs | 6 +- tests/test_sequence.rs | 4 +- tests/test_text_signature.rs | 8 +- tests/test_variable_arguments.rs | 4 +- tests/ui/deprecations.rs | 6 ++ tests/ui/deprecations.stderr | 40 ++++++--- tests/ui/invalid_frozen_pyclass_borrow.stderr | 13 +++ tests/ui/invalid_pyfunctions.stderr | 8 ++ tests/ui/invalid_pymethod_enum.stderr | 13 +++ tests/ui/static_ref.stderr | 8 ++ 22 files changed, 239 insertions(+), 144 deletions(-) diff --git a/pyo3-macros-backend/src/pyclass.rs b/pyo3-macros-backend/src/pyclass.rs index 27a7ee969d5..5122d205640 100644 --- a/pyo3-macros-backend/src/pyclass.rs +++ b/pyo3-macros-backend/src/pyclass.rs @@ -736,10 +736,11 @@ fn impl_simple_enum( fn __pyo3__richcmp__( &self, py: #pyo3_path::Python, - other: &#pyo3_path::PyAny, + other: &#pyo3_path::Bound<'_, #pyo3_path::PyAny>, op: #pyo3_path::basic::CompareOp ) -> #pyo3_path::PyResult<#pyo3_path::PyObject> { use #pyo3_path::conversion::ToPyObject; + use #pyo3_path::types::PyAnyMethods; use ::core::result::Result::*; match op { #pyo3_path::basic::CompareOp::Eq => { diff --git a/pyo3-macros-backend/src/pymethod.rs b/pyo3-macros-backend/src/pymethod.rs index a5d24498409..4e6f46d96d5 100644 --- a/pyo3-macros-backend/src/pymethod.rs +++ b/pyo3-macros-backend/src/pymethod.rs @@ -984,7 +984,9 @@ impl Ty { extract_error_mode, holders, &name_str, - quote! { #ident },ctx + quote! { #ident }, + arg.ty.span(), + ctx ), Ty::MaybeNullObject => extract_object( extract_error_mode, @@ -996,32 +998,40 @@ impl Ty { } else { #ident } - },ctx + }, + arg.ty.span(), + ctx ), Ty::NonNullObject => extract_object( extract_error_mode, holders, &name_str, - quote! { #ident.as_ptr() },ctx + quote! { #ident.as_ptr() }, + arg.ty.span(), + ctx ), Ty::IPowModulo => extract_object( extract_error_mode, holders, &name_str, - quote! { #ident.as_ptr() },ctx + quote! { #ident.as_ptr() }, + arg.ty.span(), + ctx ), Ty::CompareOp => extract_error_mode.handle_error( quote! { #pyo3_path::class::basic::CompareOp::from_raw(#ident) .ok_or_else(|| #pyo3_path::exceptions::PyValueError::new_err("invalid comparison operator")) - },ctx + }, + ctx ), Ty::PySsizeT => { let ty = arg.ty; extract_error_mode.handle_error( quote! { ::std::convert::TryInto::<#ty>::try_into(#ident).map_err(|e| #pyo3_path::exceptions::PyValueError::new_err(e.to_string())) - },ctx + }, + ctx ) } // Just pass other types through unmodified @@ -1035,11 +1045,12 @@ fn extract_object( holders: &mut Holders, name: &str, source_ptr: TokenStream, + span: Span, ctx: &Ctx, ) -> TokenStream { let Ctx { pyo3_path } = ctx; let holder = holders.push_holder(Span::call_site()); - let gil_refs_checker = holders.push_gil_refs_checker(Span::call_site()); + let gil_refs_checker = holders.push_gil_refs_checker(span); let extracted = extract_error_mode.handle_error( quote! { #pyo3_path::impl_::extract_argument::extract_argument( diff --git a/src/coroutine.rs b/src/coroutine.rs index b24197ad593..f2feab4af16 100644 --- a/src/coroutine.rs +++ b/src/coroutine.rs @@ -15,7 +15,7 @@ use crate::{ exceptions::{PyAttributeError, PyRuntimeError, PyStopIteration}, panic::PanicException, types::{string::PyStringMethods, PyIterator, PyString}, - IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python, + Bound, IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python, }; pub(crate) mod cancel; @@ -143,7 +143,7 @@ impl Coroutine { } } - fn send(&mut self, py: Python<'_>, _value: &PyAny) -> PyResult { + fn send(&mut self, py: Python<'_>, _value: &Bound<'_, PyAny>) -> PyResult { self.poll(py, None) } diff --git a/src/coroutine/waker.rs b/src/coroutine/waker.rs index b524b6d7298..fc7c54e1f5a 100644 --- a/src/coroutine/waker.rs +++ b/src/coroutine/waker.rs @@ -97,7 +97,7 @@ impl LoopAndFuture { /// Future can be cancelled by the event loop before being waken. /// See #[pyfunction(crate = "crate")] -fn release_waiter(future: &PyAny) -> PyResult<()> { +fn release_waiter(future: &Bound<'_, PyAny>) -> PyResult<()> { let done = future.call_method0(intern!(future.py(), "done"))?; if !done.extract::()? { future.call_method1(intern!(future.py(), "set_result"), (future.py().None(),))?; diff --git a/src/pycell.rs b/src/pycell.rs index 636fb90cef6..ccc55a756d6 100644 --- a/src/pycell.rs +++ b/src/pycell.rs @@ -149,12 +149,12 @@ //! //! It is better to write that function like this: //! ```rust +//! # #![allow(deprecated)] //! # use pyo3::prelude::*; //! # #[pyclass] //! # pub struct Number { //! # inner: u32, //! # } -//! # #[allow(deprecated)] //! #[pyfunction] //! fn swap_numbers(a: &PyCell, b: &PyCell) { //! // Check that the pointers are unequal diff --git a/src/tests/hygiene/pymethods.rs b/src/tests/hygiene/pymethods.rs index 2ffaf68690f..020f983be31 100644 --- a/src/tests/hygiene/pymethods.rs +++ b/src/tests/hygiene/pymethods.rs @@ -28,7 +28,7 @@ impl Dummy { } fn __format__(&self, format_spec: ::std::string::String) -> ::std::string::String { - ::std::panic!("unimplemented isn't hygienic before 1.50") + ::std::unimplemented!() } fn __lt__(&self, other: &Self) -> bool { @@ -63,12 +63,12 @@ impl Dummy { // Customizing attribute access ////////////////////// - fn __getattr__(&self, name: ::std::string::String) -> &crate::PyAny { - ::std::panic!("unimplemented isn't hygienic before 1.50") + fn __getattr__(&self, name: ::std::string::String) -> &crate::Bound<'_, crate::PyAny> { + ::std::unimplemented!() } - fn __getattribute__(&self, name: ::std::string::String) -> &crate::PyAny { - ::std::panic!("unimplemented isn't hygienic before 1.50") + fn __getattribute__(&self, name: ::std::string::String) -> &crate::Bound<'_, crate::PyAny> { + ::std::unimplemented!() } fn __setattr__(&mut self, name: ::std::string::String, value: ::std::string::String) {} @@ -85,17 +85,27 @@ impl Dummy { fn __get__( &self, - instance: &crate::PyAny, - owner: &crate::PyAny, - ) -> crate::PyResult<&crate::PyAny> { - ::std::panic!("unimplemented isn't hygienic before 1.50") + instance: &crate::Bound<'_, crate::PyAny>, + owner: &crate::Bound<'_, crate::PyAny>, + ) -> crate::PyResult<&crate::Bound<'_, crate::PyAny>> { + ::std::unimplemented!() } - fn __set__(&self, instance: &crate::PyAny, owner: &crate::PyAny) {} + fn __set__( + &self, + instance: &crate::Bound<'_, crate::PyAny>, + owner: &crate::Bound<'_, crate::PyAny>, + ) { + } - fn __delete__(&self, instance: &crate::PyAny) {} + fn __delete__(&self, instance: &crate::Bound<'_, crate::PyAny>) {} - fn __set_name__(&self, owner: &crate::PyAny, name: &crate::PyAny) {} + fn __set_name__( + &self, + owner: &crate::Bound<'_, crate::PyAny>, + name: &crate::Bound<'_, crate::PyAny>, + ) { + } ////////////////////// // Implementing Descriptors @@ -323,9 +333,9 @@ impl Dummy { fn __exit__( &mut self, - exc_type: &crate::PyAny, - exc_value: &crate::PyAny, - traceback: &crate::PyAny, + exc_type: &crate::Bound<'_, crate::PyAny>, + exc_value: &crate::Bound<'_, crate::PyAny>, + traceback: &crate::Bound<'_, crate::PyAny>, ) { } @@ -361,9 +371,9 @@ impl Dummy { fn __aexit__( &mut self, - exc_type: &crate::PyAny, - exc_value: &crate::PyAny, - traceback: &crate::PyAny, + exc_type: &crate::Bound<'_, crate::PyAny>, + exc_value: &crate::Bound<'_, crate::PyAny>, + traceback: &crate::Bound<'_, crate::PyAny>, ) { } @@ -378,10 +388,10 @@ impl Dummy { #[pyo3(signature = (*_args, **_kwds))] fn __call__( &self, - _args: &crate::types::PyTuple, - _kwds: ::std::option::Option<&crate::types::PyDict>, + _args: &crate::Bound<'_, crate::types::PyTuple>, + _kwds: ::std::option::Option<&crate::Bound<'_, crate::types::PyDict>>, ) -> crate::PyResult { - ::std::panic!("unimplemented isn't hygienic before 1.50") + ::std::unimplemented!() } #[new] fn new(a: u8) -> Self { diff --git a/src/types/bytearray.rs b/src/types/bytearray.rs index 55cda1a355a..7227519975b 100644 --- a/src/types/bytearray.rs +++ b/src/types/bytearray.rs @@ -171,7 +171,7 @@ impl PyByteArray { /// use pyo3::types::PyByteArray; /// /// #[pyfunction] - /// fn a_valid_function(bytes: &PyByteArray) -> PyResult<()> { + /// fn a_valid_function(bytes: &Bound<'_, PyByteArray>) -> PyResult<()> { /// let section = { /// // SAFETY: We promise to not let the interpreter regain control /// // or invoke any PyO3 APIs while using the slice. @@ -224,7 +224,7 @@ impl PyByteArray { /// /// # #[allow(dead_code)] /// #[pyfunction] - /// fn bug(py: Python<'_>, bytes: &PyByteArray) { + /// fn bug(py: Python<'_>, bytes: &Bound<'_, PyByteArray>) { /// let slice = unsafe { bytes.as_bytes() }; /// /// // This explicitly yields control back to the Python interpreter... @@ -333,7 +333,7 @@ pub trait PyByteArrayMethods<'py>: crate::sealed::Sealed { /// use pyo3::types::PyByteArray; /// /// #[pyfunction] - /// fn a_valid_function(bytes: &PyByteArray) -> PyResult<()> { + /// fn a_valid_function(bytes: &Bound<'_, PyByteArray>) -> PyResult<()> { /// let section = { /// // SAFETY: We promise to not let the interpreter regain control /// // or invoke any PyO3 APIs while using the slice. @@ -386,7 +386,7 @@ pub trait PyByteArrayMethods<'py>: crate::sealed::Sealed { /// /// # #[allow(dead_code)] /// #[pyfunction] - /// fn bug(py: Python<'_>, bytes: &PyByteArray) { + /// fn bug(py: Python<'_>, bytes: &Bound<'_, PyByteArray>) { /// let slice = unsafe { bytes.as_bytes() }; /// /// // This explicitly yields control back to the Python interpreter... diff --git a/tests/test_arithmetics.rs b/tests/test_arithmetics.rs index 88f9ca44c28..da8d72ea9cc 100644 --- a/tests/test_arithmetics.rs +++ b/tests/test_arithmetics.rs @@ -166,43 +166,43 @@ impl BinaryArithmetic { "BA" } - fn __add__(&self, rhs: &PyAny) -> String { + fn __add__(&self, rhs: &Bound<'_, PyAny>) -> String { format!("BA + {:?}", rhs) } - fn __sub__(&self, rhs: &PyAny) -> String { + fn __sub__(&self, rhs: &Bound<'_, PyAny>) -> String { format!("BA - {:?}", rhs) } - fn __mul__(&self, rhs: &PyAny) -> String { + fn __mul__(&self, rhs: &Bound<'_, PyAny>) -> String { format!("BA * {:?}", rhs) } - fn __truediv__(&self, rhs: &PyAny) -> String { + fn __truediv__(&self, rhs: &Bound<'_, PyAny>) -> String { format!("BA / {:?}", rhs) } - fn __lshift__(&self, rhs: &PyAny) -> String { + fn __lshift__(&self, rhs: &Bound<'_, PyAny>) -> String { format!("BA << {:?}", rhs) } - fn __rshift__(&self, rhs: &PyAny) -> String { + fn __rshift__(&self, rhs: &Bound<'_, PyAny>) -> String { format!("BA >> {:?}", rhs) } - fn __and__(&self, rhs: &PyAny) -> String { + fn __and__(&self, rhs: &Bound<'_, PyAny>) -> String { format!("BA & {:?}", rhs) } - fn __xor__(&self, rhs: &PyAny) -> String { + fn __xor__(&self, rhs: &Bound<'_, PyAny>) -> String { format!("BA ^ {:?}", rhs) } - fn __or__(&self, rhs: &PyAny) -> String { + fn __or__(&self, rhs: &Bound<'_, PyAny>) -> String { format!("BA | {:?}", rhs) } - fn __pow__(&self, rhs: &PyAny, mod_: Option) -> String { + fn __pow__(&self, rhs: &Bound<'_, PyAny>, mod_: Option) -> String { format!("BA ** {:?} (mod: {:?})", rhs, mod_) } } @@ -257,39 +257,39 @@ struct RhsArithmetic {} #[pymethods] impl RhsArithmetic { - fn __radd__(&self, other: &PyAny) -> String { + fn __radd__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} + RA", other) } - fn __rsub__(&self, other: &PyAny) -> String { + fn __rsub__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} - RA", other) } - fn __rmul__(&self, other: &PyAny) -> String { + fn __rmul__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} * RA", other) } - fn __rlshift__(&self, other: &PyAny) -> String { + fn __rlshift__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} << RA", other) } - fn __rrshift__(&self, other: &PyAny) -> String { + fn __rrshift__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} >> RA", other) } - fn __rand__(&self, other: &PyAny) -> String { + fn __rand__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} & RA", other) } - fn __rxor__(&self, other: &PyAny) -> String { + fn __rxor__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} ^ RA", other) } - fn __ror__(&self, other: &PyAny) -> String { + fn __ror__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} | RA", other) } - fn __rpow__(&self, other: &PyAny, _mod: Option<&PyAny>) -> String { + fn __rpow__(&self, other: &Bound<'_, PyAny>, _mod: Option<&PyAny>) -> String { format!("{:?} ** RA", other) } } @@ -334,91 +334,91 @@ impl LhsAndRhs { // "BA" // } - fn __add__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { + fn __add__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>) -> String { format!("{:?} + {:?}", lhs, rhs) } - fn __sub__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { + fn __sub__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>) -> String { format!("{:?} - {:?}", lhs, rhs) } - fn __mul__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { + fn __mul__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>) -> String { format!("{:?} * {:?}", lhs, rhs) } - fn __lshift__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { + fn __lshift__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>) -> String { format!("{:?} << {:?}", lhs, rhs) } - fn __rshift__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { + fn __rshift__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>) -> String { format!("{:?} >> {:?}", lhs, rhs) } - fn __and__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { + fn __and__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>) -> String { format!("{:?} & {:?}", lhs, rhs) } - fn __xor__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { + fn __xor__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>) -> String { format!("{:?} ^ {:?}", lhs, rhs) } - fn __or__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { + fn __or__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>) -> String { format!("{:?} | {:?}", lhs, rhs) } - fn __pow__(lhs: PyRef<'_, Self>, rhs: &PyAny, _mod: Option) -> String { + fn __pow__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>, _mod: Option) -> String { format!("{:?} ** {:?}", lhs, rhs) } - fn __matmul__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { + fn __matmul__(lhs: PyRef<'_, Self>, rhs: &Bound<'_, PyAny>) -> String { format!("{:?} @ {:?}", lhs, rhs) } - fn __radd__(&self, other: &PyAny) -> String { + fn __radd__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} + RA", other) } - fn __rsub__(&self, other: &PyAny) -> String { + fn __rsub__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} - RA", other) } - fn __rmul__(&self, other: &PyAny) -> String { + fn __rmul__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} * RA", other) } - fn __rlshift__(&self, other: &PyAny) -> String { + fn __rlshift__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} << RA", other) } - fn __rrshift__(&self, other: &PyAny) -> String { + fn __rrshift__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} >> RA", other) } - fn __rand__(&self, other: &PyAny) -> String { + fn __rand__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} & RA", other) } - fn __rxor__(&self, other: &PyAny) -> String { + fn __rxor__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} ^ RA", other) } - fn __ror__(&self, other: &PyAny) -> String { + fn __ror__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} | RA", other) } - fn __rpow__(&self, other: &PyAny, _mod: Option<&PyAny>) -> String { + fn __rpow__(&self, other: &Bound<'_, PyAny>, _mod: Option<&PyAny>) -> String { format!("{:?} ** RA", other) } - fn __rmatmul__(&self, other: &PyAny) -> String { + fn __rmatmul__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} @ RA", other) } - fn __rtruediv__(&self, other: &PyAny) -> String { + fn __rtruediv__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} / RA", other) } - fn __rfloordiv__(&self, other: &PyAny) -> String { + fn __rfloordiv__(&self, other: &Bound<'_, PyAny>) -> String { format!("{:?} // RA", other) } } @@ -461,7 +461,7 @@ impl RichComparisons { "RC" } - fn __richcmp__(&self, other: &PyAny, op: CompareOp) -> String { + fn __richcmp__(&self, other: &Bound<'_, PyAny>, op: CompareOp) -> String { match op { CompareOp::Lt => format!("{} < {:?}", self.__repr__(), other), CompareOp::Le => format!("{} <= {:?}", self.__repr__(), other), @@ -482,7 +482,7 @@ impl RichComparisons2 { "RC2" } - fn __richcmp__(&self, other: &PyAny, op: CompareOp) -> PyObject { + fn __richcmp__(&self, other: &Bound<'_, PyAny>, op: CompareOp) -> PyObject { match op { CompareOp::Eq => true.into_py(other.py()), CompareOp::Ne => false.into_py(other.py()), diff --git a/tests/test_inheritance.rs b/tests/test_inheritance.rs index 1209713e487..fc9a7699c1b 100644 --- a/tests/test_inheritance.rs +++ b/tests/test_inheritance.rs @@ -41,7 +41,7 @@ impl BaseClass { fn base_method(&self, x: usize) -> usize { x * self.val1 } - fn base_set(&mut self, fn_: &pyo3::PyAny) -> PyResult<()> { + fn base_set(&mut self, fn_: &Bound<'_, PyAny>) -> PyResult<()> { let value: usize = fn_.call0()?.extract()?; self.val1 = value; Ok(()) @@ -264,7 +264,7 @@ mod inheriting_native_type { #[pymethods] impl CustomException { #[new] - fn new(_exc_arg: &PyAny) -> Self { + fn new(_exc_arg: &Bound<'_, PyAny>) -> Self { CustomException { context: "Hello :)", } diff --git a/tests/test_methods.rs b/tests/test_methods.rs index 7ca06b27c05..2c027d292bf 100644 --- a/tests/test_methods.rs +++ b/tests/test_methods.rs @@ -112,7 +112,7 @@ struct ClassMethodWithArgs {} #[pymethods] impl ClassMethodWithArgs { #[classmethod] - fn method(cls: &Bound<'_, PyType>, input: &PyString) -> PyResult { + fn method(cls: &Bound<'_, PyType>, input: &Bound<'_, PyString>) -> PyResult { Ok(format!( "{}.method({})", cls.as_gil_ref().qualname()?, @@ -215,8 +215,13 @@ impl MethSignature { test } #[pyo3(signature = (*args, **kwargs))] - fn get_kwargs(&self, py: Python<'_>, args: &PyTuple, kwargs: Option<&PyDict>) -> PyObject { - [args.into(), kwargs.to_object(py)].to_object(py) + fn get_kwargs( + &self, + py: Python<'_>, + args: &Bound<'_, PyTuple>, + kwargs: Option<&Bound<'_, PyDict>>, + ) -> PyObject { + [args.to_object(py), kwargs.to_object(py)].to_object(py) } #[pyo3(signature = (a, *args, **kwargs))] @@ -224,10 +229,10 @@ impl MethSignature { &self, py: Python<'_>, a: i32, - args: &PyTuple, - kwargs: Option<&PyDict>, + args: &Bound<'_, PyTuple>, + kwargs: Option<&Bound<'_, PyDict>>, ) -> PyObject { - [a.to_object(py), args.into(), kwargs.to_object(py)].to_object(py) + [a.to_object(py), args.to_object(py), kwargs.to_object(py)].to_object(py) } #[pyo3(signature = (a, b, /))] @@ -270,7 +275,7 @@ impl MethSignature { &self, py: Python<'_>, a: i32, - kwargs: Option<&PyDict>, + kwargs: Option<&Bound<'_, PyDict>>, ) -> PyObject { [a.to_object(py), kwargs.to_object(py)].to_object(py) } @@ -280,7 +285,7 @@ impl MethSignature { &self, py: Python<'_>, a: i32, - kwargs: Option<&PyDict>, + kwargs: Option<&Bound<'_, PyDict>>, ) -> PyObject { [a.to_object(py), kwargs.to_object(py)].to_object(py) } @@ -301,7 +306,12 @@ impl MethSignature { } #[pyo3(signature = (*args, a))] - fn get_args_and_required_keyword(&self, py: Python<'_>, args: &PyTuple, a: i32) -> PyObject { + fn get_args_and_required_keyword( + &self, + py: Python<'_>, + args: &Bound<'_, PyTuple>, + a: i32, + ) -> PyObject { (args, a).to_object(py) } @@ -316,7 +326,7 @@ impl MethSignature { } #[pyo3(signature = (a, **kwargs))] - fn get_pos_kw(&self, py: Python<'_>, a: i32, kwargs: Option<&PyDict>) -> PyObject { + fn get_pos_kw(&self, py: Python<'_>, a: i32, kwargs: Option<&Bound<'_, PyDict>>) -> PyObject { [a.to_object(py), kwargs.to_object(py)].to_object(py) } @@ -697,7 +707,8 @@ struct MethodWithLifeTime {} #[pymethods] impl MethodWithLifeTime { - fn set_to_list<'py>(&self, py: Python<'py>, set: &'py PySet) -> PyResult> { + fn set_to_list<'py>(&self, set: &Bound<'py, PySet>) -> PyResult> { + let py = set.py(); let mut items = vec![]; for _ in 0..set.len() { items.push(set.pop().unwrap()); @@ -1028,45 +1039,45 @@ issue_1506!( fn issue_1506( &self, _py: Python<'_>, - _arg: &PyAny, - _args: &PyTuple, - _kwargs: Option<&PyDict>, + _arg: &Bound<'_, PyAny>, + _args: &Bound<'_, PyTuple>, + _kwargs: Option<&Bound<'_, PyDict>>, ) { } fn issue_1506_mut( &mut self, _py: Python<'_>, - _arg: &PyAny, - _args: &PyTuple, - _kwargs: Option<&PyDict>, + _arg: &Bound<'_, PyAny>, + _args: &Bound<'_, PyTuple>, + _kwargs: Option<&Bound<'_, PyDict>>, ) { } fn issue_1506_custom_receiver( _slf: Py, _py: Python<'_>, - _arg: &PyAny, - _args: &PyTuple, - _kwargs: Option<&PyDict>, + _arg: &Bound<'_, PyAny>, + _args: &Bound<'_, PyTuple>, + _kwargs: Option<&Bound<'_, PyDict>>, ) { } fn issue_1506_custom_receiver_explicit( _slf: Py, _py: Python<'_>, - _arg: &PyAny, - _args: &PyTuple, - _kwargs: Option<&PyDict>, + _arg: &Bound<'_, PyAny>, + _args: &Bound<'_, PyTuple>, + _kwargs: Option<&Bound<'_, PyDict>>, ) { } #[new] fn issue_1506_new( _py: Python<'_>, - _arg: &PyAny, - _args: &PyTuple, - _kwargs: Option<&PyDict>, + _arg: &Bound<'_, PyAny>, + _args: &Bound<'_, PyTuple>, + _kwargs: Option<&Bound<'_, PyDict>>, ) -> Self { Issue1506 {} } @@ -1082,9 +1093,9 @@ issue_1506!( #[staticmethod] fn issue_1506_static( _py: Python<'_>, - _arg: &PyAny, - _args: &PyTuple, - _kwargs: Option<&PyDict>, + _arg: &Bound<'_, PyAny>, + _args: &Bound<'_, PyTuple>, + _kwargs: Option<&Bound<'_, PyDict>>, ) { } @@ -1092,9 +1103,9 @@ issue_1506!( fn issue_1506_class( _cls: &Bound<'_, PyType>, _py: Python<'_>, - _arg: &PyAny, - _args: &PyTuple, - _kwargs: Option<&PyDict>, + _arg: &Bound<'_, PyAny>, + _args: &Bound<'_, PyTuple>, + _kwargs: Option<&Bound<'_, PyDict>>, ) { } } diff --git a/tests/test_no_imports.rs b/tests/test_no_imports.rs index 4c77cc8e2a0..35c978b0da5 100644 --- a/tests/test_no_imports.rs +++ b/tests/test_no_imports.rs @@ -49,7 +49,7 @@ impl BasicClass { const OKAY: bool = true; #[new] - fn new(arg: &pyo3::PyAny) -> pyo3::PyResult { + fn new(arg: &pyo3::Bound<'_, pyo3::PyAny>) -> pyo3::PyResult { if let Ok(v) = arg.extract::() { Ok(Self { v, diff --git a/tests/test_proto_methods.rs b/tests/test_proto_methods.rs index a1cfde2badf..df9de25cf22 100644 --- a/tests/test_proto_methods.rs +++ b/tests/test_proto_methods.rs @@ -28,7 +28,7 @@ impl ExampleClass { } } - fn __setattr__(&mut self, attr: &str, value: &PyAny) -> PyResult<()> { + fn __setattr__(&mut self, attr: &str, value: &Bound<'_, PyAny>) -> PyResult<()> { if attr == "special_custom_attr" { self.custom_attr = Some(value.extract()?); Ok(()) @@ -528,7 +528,7 @@ struct GetItem {} #[pymethods] impl GetItem { - fn __getitem__(&self, idx: &PyAny) -> PyResult<&'static str> { + fn __getitem__(&self, idx: &Bound<'_, PyAny>) -> PyResult<&'static str> { if let Ok(slice) = idx.downcast::() { let indices = slice.indices(1000)?; if indices.start == 100 && indices.stop == 200 && indices.step == 1 { @@ -767,18 +767,18 @@ impl DescrCounter { /// Each access will increase the count fn __get__<'a>( mut slf: PyRefMut<'a, Self>, - _instance: &PyAny, + _instance: &Bound<'_, PyAny>, _owner: Option<&PyType>, ) -> PyRefMut<'a, Self> { slf.count += 1; slf } /// Allow assigning a new counter to the descriptor, copying the count across - fn __set__(&self, _instance: &PyAny, new_value: &mut Self) { + fn __set__(&self, _instance: &Bound<'_, PyAny>, new_value: &mut Self) { new_value.count = self.count; } /// Delete to reset the counter - fn __delete__(&mut self, _instance: &PyAny) { + fn __delete__(&mut self, _instance: &Bound<'_, PyAny>) { self.count = 0; } } diff --git a/tests/test_pyfunction.rs b/tests/test_pyfunction.rs index 5221b0f85a5..8a57e2707c9 100644 --- a/tests/test_pyfunction.rs +++ b/tests/test_pyfunction.rs @@ -77,12 +77,14 @@ assert a, array.array("i", [2, 4, 6, 8]) #[cfg(not(any(Py_LIMITED_API, PyPy)))] #[pyfunction] -fn function_with_pyfunction_arg(fun: &PyFunction) -> PyResult<&PyAny> { +fn function_with_pyfunction_arg<'py>(fun: &Bound<'py, PyFunction>) -> PyResult> { fun.call((), None) } #[pyfunction] -fn function_with_pycfunction_arg(fun: &PyCFunction) -> PyResult<&PyAny> { +fn function_with_pycfunction_arg<'py>( + fun: &Bound<'py, PyCFunction>, +) -> PyResult> { fun.call((), None) } diff --git a/tests/test_sequence.rs b/tests/test_sequence.rs index 363c27f5eb5..4e128a0bbff 100644 --- a/tests/test_sequence.rs +++ b/tests/test_sequence.rs @@ -60,8 +60,8 @@ impl ByteSequence { } } - fn __contains__(&self, other: &PyAny) -> bool { - match u8::extract(other) { + fn __contains__(&self, other: &Bound<'_, PyAny>) -> bool { + match other.extract::() { Ok(x) => self.elements.contains(&x), Err(_) => false, } diff --git a/tests/test_text_signature.rs b/tests/test_text_signature.rs index 32a78346e9a..a9f5a041596 100644 --- a/tests/test_text_signature.rs +++ b/tests/test_text_signature.rs @@ -128,10 +128,10 @@ fn test_auto_test_signature_function() { fn my_function_4( a: i32, b: Option, - args: &PyTuple, + args: &Bound<'_, PyTuple>, c: i32, d: i32, - kwargs: Option<&PyDict>, + kwargs: Option<&Bound<'_, PyDict>>, ) { let _ = (a, b, args, c, d, kwargs); } @@ -218,10 +218,10 @@ fn test_auto_test_signature_method() { &self, a: i32, b: Option, - args: &PyTuple, + args: &Bound<'_, PyTuple>, c: i32, d: i32, - kwargs: Option<&PyDict>, + kwargs: Option<&Bound<'_, PyDict>>, ) { let _ = (a, b, args, c, d, kwargs); } diff --git a/tests/test_variable_arguments.rs b/tests/test_variable_arguments.rs index 8d3cd5d3935..3724689d836 100644 --- a/tests/test_variable_arguments.rs +++ b/tests/test_variable_arguments.rs @@ -13,13 +13,13 @@ struct MyClass {} impl MyClass { #[staticmethod] #[pyo3(signature = (*args))] - fn test_args(args: &PyTuple) -> &PyTuple { + fn test_args(args: Bound<'_, PyTuple>) -> Bound<'_, PyTuple> { args } #[staticmethod] #[pyo3(signature = (**kwargs))] - fn test_kwargs(kwargs: Option<&PyDict>) -> Option<&PyDict> { + fn test_kwargs(kwargs: Option>) -> Option> { kwargs } } diff --git a/tests/ui/deprecations.rs b/tests/ui/deprecations.rs index 1dcc673a33a..191d6b2b07b 100644 --- a/tests/ui/deprecations.rs +++ b/tests/ui/deprecations.rs @@ -23,6 +23,9 @@ impl MyClass { fn method_gil_ref(_slf: &PyCell) {} fn method_bound(_slf: &Bound<'_, Self>) {} + + #[staticmethod] + fn static_method_gil_ref(_any: &PyAny) {} } fn main() {} @@ -89,6 +92,9 @@ fn pyfunction_from_py_with( ) { } +#[pyfunction] +fn pyfunction_gil_ref(_any: &PyAny) {} + fn test_wrap_pyfunction(py: Python<'_>, m: &Bound<'_, PyModule>) { // should lint let _ = wrap_pyfunction!(double, py); diff --git a/tests/ui/deprecations.stderr b/tests/ui/deprecations.stderr index 8bd1450874f..1f48a58aea6 100644 --- a/tests/ui/deprecations.stderr +++ b/tests/ui/deprecations.stderr @@ -29,33 +29,45 @@ error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg` | ^ error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:38:43 + --> tests/ui/deprecations.rs:28:36 | -38 | fn pyfunction_with_module_gil_ref(module: &PyModule) -> PyResult<&str> { +28 | fn static_method_gil_ref(_any: &PyAny) {} + | ^ + +error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument + --> tests/ui/deprecations.rs:41:43 + | +41 | fn pyfunction_with_module_gil_ref(module: &PyModule) -> PyResult<&str> { | ^ error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:48:19 + --> tests/ui/deprecations.rs:51:19 | -48 | fn module_gil_ref(m: &PyModule) -> PyResult<()> { +51 | fn module_gil_ref(m: &PyModule) -> PyResult<()> { | ^ error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:54:57 + --> tests/ui/deprecations.rs:57:57 | -54 | fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, m: &PyModule) -> PyResult<()> { +57 | fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, m: &PyModule) -> PyResult<()> { | ^ error: use of deprecated method `pyo3::deprecations::GilRefs::::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor - --> tests/ui/deprecations.rs:87:27 + --> tests/ui/deprecations.rs:90:27 | -87 | #[pyo3(from_py_with = "extract_gil_ref")] _gil_ref: i32, +90 | #[pyo3(from_py_with = "extract_gil_ref")] _gil_ref: i32, | ^^^^^^^^^^^^^^^^^ -error: use of deprecated method `pyo3::deprecations::GilRefs::>::is_python`: use `wrap_pyfunction_bound!` instead - --> tests/ui/deprecations.rs:94:13 - | -94 | let _ = wrap_pyfunction!(double, py); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument + --> tests/ui/deprecations.rs:96:29 | - = note: this error originates in the macro `wrap_pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) +96 | fn pyfunction_gil_ref(_any: &PyAny) {} + | ^ + +error: use of deprecated method `pyo3::deprecations::GilRefs::>::is_python`: use `wrap_pyfunction_bound!` instead + --> tests/ui/deprecations.rs:100:13 + | +100 | let _ = wrap_pyfunction!(double, py); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `wrap_pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/invalid_frozen_pyclass_borrow.stderr b/tests/ui/invalid_frozen_pyclass_borrow.stderr index 3acfbeb1823..52a0623f282 100644 --- a/tests/ui/invalid_frozen_pyclass_borrow.stderr +++ b/tests/ui/invalid_frozen_pyclass_borrow.stderr @@ -16,6 +16,19 @@ note: required by a bound in `extract_pyclass_ref_mut` | pub fn extract_pyclass_ref_mut<'a, 'py: 'a, T: PyClass>( | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` +error[E0271]: type mismatch resolving `::Frozen == False` + --> tests/ui/invalid_frozen_pyclass_borrow.rs:9:1 + | +9 | #[pymethods] + | ^^^^^^^^^^^^ expected `False`, found `True` + | +note: required by a bound in `PyRefMut` + --> src/pycell.rs + | + | pub struct PyRefMut<'p, T: PyClass> { + | ^^^^^^^^^^^^^^ required by this bound in `PyRefMut` + = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0271]: type mismatch resolving `::Frozen == False` --> tests/ui/invalid_frozen_pyclass_borrow.rs:15:31 | diff --git a/tests/ui/invalid_pyfunctions.stderr b/tests/ui/invalid_pyfunctions.stderr index 6576997a3eb..76eab9b10cb 100644 --- a/tests/ui/invalid_pyfunctions.stderr +++ b/tests/ui/invalid_pyfunctions.stderr @@ -49,3 +49,11 @@ error[E0277]: the trait bound `&str: From> > = note: required for `BoundRef<'_, '_, pyo3::prelude::PyModule>` to implement `Into<&str>` + +warning: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument + --> tests/ui/invalid_pyfunctions.rs:22:57 + | +22 | fn first_argument_not_module<'py>(string: &str, module: &'py PyModule) -> PyResult<&'py str> { + | ^ + | + = note: `#[warn(deprecated)]` on by default diff --git a/tests/ui/invalid_pymethod_enum.stderr b/tests/ui/invalid_pymethod_enum.stderr index bb327dccb5d..6cf6fe89bdf 100644 --- a/tests/ui/invalid_pymethod_enum.stderr +++ b/tests/ui/invalid_pymethod_enum.stderr @@ -9,3 +9,16 @@ note: required by a bound in `extract_pyclass_ref_mut` | | pub fn extract_pyclass_ref_mut<'a, 'py: 'a, T: PyClass>( | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` + +error[E0271]: type mismatch resolving `::Frozen == False` + --> tests/ui/invalid_pymethod_enum.rs:9:1 + | +9 | #[pymethods] + | ^^^^^^^^^^^^ expected `False`, found `True` + | +note: required by a bound in `PyRefMut` + --> src/pycell.rs + | + | pub struct PyRefMut<'p, T: PyClass> { + | ^^^^^^^^^^^^^^ required by this bound in `PyRefMut` + = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/static_ref.stderr b/tests/ui/static_ref.stderr index 2dd3342e5ba..23385de0fd5 100644 --- a/tests/ui/static_ref.stderr +++ b/tests/ui/static_ref.stderr @@ -1,3 +1,11 @@ +warning: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument + --> tests/ui/static_ref.rs:5:21 + | +5 | fn static_ref(list: &'static PyList) -> usize { + | ^ + | + = note: `#[warn(deprecated)]` on by default + error: lifetime may not live long enough --> tests/ui/static_ref.rs:4:1 |