diff --git a/guide/src/conversions/traits.md b/guide/src/conversions/traits.md index 3a00a160..65a5d150 100644 --- a/guide/src/conversions/traits.md +++ b/guide/src/conversions/traits.md @@ -499,7 +499,7 @@ _without_ having a unique python type. ```rust use pyo3::prelude::*; - +# #[allow(dead_code)] struct MyPyObjectWrapper(PyObject); impl IntoPy for MyPyObjectWrapper { diff --git a/guide/src/migration.md b/guide/src/migration.md index 5af6eb23..1c5ca597 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -436,7 +436,7 @@ impl SomeClass { When converting from `anyhow::Error` or `eyre::Report` to `PyErr`, if the inner error is a "simple" `PyErr` (with no source error), then the inner error will be used directly as the `PyErr` instead of wrapping it in a new `PyRuntimeError` with the original information converted into a string. -```rust +```rust,ignore # #[cfg(feature = "anyhow")] # #[allow(dead_code)] # mod anyhow_only { @@ -597,9 +597,9 @@ fn function_with_defaults(a: i32, b: i32, c: i32) {} # fn main() { # Python::with_gil(|py| { -# let simple = wrap_pyfunction!(simple_function, py).unwrap(); +# let simple = wrap_pyfunction_bound!(simple_function, py).unwrap(); # assert_eq!(simple.getattr("__text_signature__").unwrap().to_string(), "(a, b, c)"); -# let defaulted = wrap_pyfunction!(function_with_defaults, py).unwrap(); +# let defaulted = wrap_pyfunction_bound!(function_with_defaults, py).unwrap(); # assert_eq!(defaulted.getattr("__text_signature__").unwrap().to_string(), "(a, b=1, c=2)"); # }) # } @@ -1090,6 +1090,7 @@ impl FromPy for PyObject { After ```rust # use pyo3::prelude::*; +# #[allow(dead_code)] struct MyPyObjectWrapper(PyObject); impl IntoPy for MyPyObjectWrapper { diff --git a/pytests/src/enums.rs b/pytests/src/enums.rs index 32478cbe..4bb269fb 100644 --- a/pytests/src/enums.rs +++ b/pytests/src/enums.rs @@ -1,11 +1,13 @@ -use pyo3::{pyclass, pyfunction, pymodule, types::PyModule, wrap_pyfunction, Bound, PyResult}; +use pyo3::{ + pyclass, pyfunction, pymodule, types::PyModule, wrap_pyfunction_bound, Bound, PyResult, +}; #[pymodule] pub fn enums(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_class::()?; m.add_class::()?; - m.add_wrapped(wrap_pyfunction!(do_simple_stuff))?; - m.add_wrapped(wrap_pyfunction!(do_complex_stuff))?; + m.add_wrapped(wrap_pyfunction_bound!(do_simple_stuff))?; + m.add_wrapped(wrap_pyfunction_bound!(do_complex_stuff))?; Ok(()) } diff --git a/src/conversion.rs b/src/conversion.rs index efb09b6b..8d4ad776 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -96,6 +96,7 @@ pub trait ToPyObject { /// ```rust /// use pyo3::prelude::*; /// +/// # #[allow(dead_code)] /// struct Number { /// value: i32, /// } diff --git a/src/conversions/anyhow.rs b/src/conversions/anyhow.rs index fba8816d..623ee7d5 100644 --- a/src/conversions/anyhow.rs +++ b/src/conversions/anyhow.rs @@ -35,7 +35,6 @@ //! //! ```rust //! use pyo3::prelude::*; -//! use pyo3::wrap_pyfunction; //! use std::path::PathBuf; //! //! // A wrapper around a Rust function. @@ -48,7 +47,7 @@ //! //! fn main() { //! let error = Python::with_gil(|py| -> PyResult> { -//! let fun = wrap_pyfunction!(py_open, py)?; +//! let fun = wrap_pyfunction_bound!(py_open, py)?; //! let text = fun.call1(("foo.txt",))?.extract::>()?; //! Ok(text) //! }).unwrap_err(); diff --git a/src/conversions/eyre.rs b/src/conversions/eyre.rs index 236e2c8b..d4704e41 100644 --- a/src/conversions/eyre.rs +++ b/src/conversions/eyre.rs @@ -34,7 +34,6 @@ //! //! ```rust //! use pyo3::prelude::*; -//! use pyo3::wrap_pyfunction; //! use std::path::PathBuf; //! //! // A wrapper around a Rust function. @@ -47,7 +46,7 @@ //! //! fn main() { //! let error = Python::with_gil(|py| -> PyResult> { -//! let fun = wrap_pyfunction!(py_open, py)?; +//! let fun = wrap_pyfunction_bound!(py_open, py)?; //! let text = fun.call1(("foo.txt",))?.extract::>()?; //! Ok(text) //! }).unwrap_err(); diff --git a/src/coroutine/waker.rs b/src/coroutine/waker.rs index 096146f8..b524b6d7 100644 --- a/src/coroutine/waker.rs +++ b/src/coroutine/waker.rs @@ -1,7 +1,7 @@ use crate::sync::GILOnceCell; use crate::types::any::PyAnyMethods; use crate::types::PyCFunction; -use crate::{intern, wrap_pyfunction, Bound, Py, PyAny, PyObject, PyResult, Python}; +use crate::{intern, wrap_pyfunction_bound, Bound, Py, PyAny, PyObject, PyResult, Python}; use pyo3_macros::pyfunction; use std::sync::Arc; use std::task::Wake; @@ -70,8 +70,9 @@ impl LoopAndFuture { fn set_result(&self, py: Python<'_>) -> PyResult<()> { static RELEASE_WAITER: GILOnceCell> = GILOnceCell::new(); - let release_waiter = RELEASE_WAITER - .get_or_try_init(py, || wrap_pyfunction!(release_waiter, py).map(Into::into))?; + let release_waiter = RELEASE_WAITER.get_or_try_init(py, || { + wrap_pyfunction_bound!(release_waiter, py).map(Bound::unbind) + })?; // `Future.set_result` must be called in event loop thread, // so it requires `call_soon_threadsafe` let call_soon_threadsafe = self.event_loop.call_method1( diff --git a/src/err/mod.rs b/src/err/mod.rs index cc4de799..7610f499 100644 --- a/src/err/mod.rs +++ b/src/err/mod.rs @@ -145,7 +145,7 @@ impl PyErr { /// } /// # /// # Python::with_gil(|py| { - /// # let fun = pyo3::wrap_pyfunction!(always_throws, py).unwrap(); + /// # let fun = pyo3::wrap_pyfunction_bound!(always_throws, py).unwrap(); /// # let err = fun.call0().expect_err("called a function that should always return an error but the return value was Ok"); /// # assert!(err.is_instance_of::(py)) /// # }); @@ -163,7 +163,7 @@ impl PyErr { /// } /// # /// # Python::with_gil(|py| { - /// # let fun = pyo3::wrap_pyfunction!(always_throws, py).unwrap(); + /// # let fun = pyo3::wrap_pyfunction_bound!(always_throws, py).unwrap(); /// # let err = fun.call0().expect_err("called a function that should always return an error but the return value was Ok"); /// # assert!(err.is_instance_of::(py)) /// # }); diff --git a/src/exceptions.rs b/src/exceptions.rs index 3401679b..bd9c89c4 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -171,7 +171,7 @@ macro_rules! import_exception { /// } /// # fn main() -> PyResult<()> { /// # Python::with_gil(|py| -> PyResult<()> { -/// # let fun = wrap_pyfunction!(raise_myerror, py)?; +/// # let fun = wrap_pyfunction_bound!(raise_myerror, py)?; /// # let locals = pyo3::types::PyDict::new_bound(py); /// # locals.set_item("MyError", py.get_type_bound::())?; /// # locals.set_item("raise_myerror", fun)?; @@ -322,7 +322,7 @@ fn always_throws() -> PyResult<()> { } # # Python::with_gil(|py| { -# let fun = pyo3::wrap_pyfunction!(always_throws, py).unwrap(); +# let fun = pyo3::wrap_pyfunction_bound!(always_throws, py).unwrap(); # let err = fun.call0().expect_err(\"called a function that should always return an error but the return value was Ok\"); # assert!(err.is_instance_of::(py)) # }); diff --git a/src/impl_/pymethods.rs b/src/impl_/pymethods.rs index a7df90b5..bc1125f9 100644 --- a/src/impl_/pymethods.rs +++ b/src/impl_/pymethods.rs @@ -599,6 +599,14 @@ impl Extractor { } } +impl Extractor> { + #[cfg_attr( + not(feature = "gil-refs"), + deprecated(since = "0.21.0", note = "use `wrap_pyfunction_bound!` instead") + )] + pub fn is_python(&self) {} +} + impl Extractor { #[cfg_attr( not(feature = "gil-refs"), @@ -612,6 +620,7 @@ impl Extractor { impl NotAGilRef { pub fn extract_gil_ref(&self) {} + pub fn is_python(&self) {} } impl std::ops::Deref for Extractor { diff --git a/src/macros.rs b/src/macros.rs index 33f378e7..bd0bd814 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -144,8 +144,10 @@ macro_rules! wrap_pyfunction { }; ($function:path, $py_or_module:expr) => {{ use $function as wrapped_pyfunction; + let (py_or_module, e) = $crate::impl_::pymethods::inspect_type($py_or_module); + e.is_python(); $crate::impl_::pyfunction::WrapPyFunctionArg::wrap_pyfunction( - $py_or_module, + py_or_module, &wrapped_pyfunction::DEF, ) }}; diff --git a/src/marker.rs b/src/marker.rs index 9b3d7329..2a38b83c 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -509,7 +509,7 @@ impl<'py> Python<'py> { /// # /// # fn main() -> PyResult<()> { /// # Python::with_gil(|py| -> PyResult<()> { - /// # let fun = pyo3::wrap_pyfunction!(sum_numbers, py)?; + /// # let fun = pyo3::wrap_pyfunction_bound!(sum_numbers, py)?; /// # let res = fun.call1((vec![1_u32, 2, 3],))?; /// # assert_eq!(res.extract::()?, 6_u32); /// # Ok(()) diff --git a/src/pycell.rs b/src/pycell.rs index 397e7b6a..636fb90c 100644 --- a/src/pycell.rs +++ b/src/pycell.rs @@ -132,7 +132,7 @@ //! # let n = Py::new(py, Number{inner: 35}).unwrap(); //! # let n2 = n.clone_ref(py); //! # assert!(n.is(&n2)); -//! # let fun = pyo3::wrap_pyfunction!(swap_numbers, py).unwrap(); +//! # let fun = pyo3::wrap_pyfunction_bound!(swap_numbers, py).unwrap(); //! # fun.call1((n, n2)).expect_err("Managed to create overlapping mutable references. Note: this is undefined behaviour."); //! # }); //! # } @@ -170,7 +170,7 @@ //! # let n = Py::new(py, Number{inner: 35}).unwrap(); //! # let n2 = n.clone_ref(py); //! # assert!(n.is(&n2)); -//! # let fun = pyo3::wrap_pyfunction!(swap_numbers, py).unwrap(); +//! # let fun = pyo3::wrap_pyfunction_bound!(swap_numbers, py).unwrap(); //! # fun.call1((n, n2)).unwrap(); //! # }); //! # @@ -179,7 +179,7 @@ //! # let n = Py::new(py, Number{inner: 35}).unwrap(); //! # let n2 = Py::new(py, Number{inner: 42}).unwrap(); //! # assert!(!n.is(&n2)); -//! # let fun = pyo3::wrap_pyfunction!(swap_numbers, py).unwrap(); +//! # let fun = pyo3::wrap_pyfunction_bound!(swap_numbers, py).unwrap(); //! # fun.call1((&n, &n2)).unwrap(); //! # let n: u32 = n.borrow(py).inner; //! # let n2: u32 = n2.borrow(py).inner; diff --git a/src/sync.rs b/src/sync.rs index e89a8edd..38471fb7 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -220,7 +220,7 @@ impl GILOnceCell> { /// /// ``` /// use pyo3::intern; -/// # use pyo3::{pyfunction, types::PyDict, wrap_pyfunction, PyResult, Python, prelude::PyDictMethods, Bound}; +/// # use pyo3::{prelude::*, types::PyDict}; /// /// #[pyfunction] /// fn create_dict(py: Python<'_>) -> PyResult> { @@ -241,10 +241,10 @@ impl GILOnceCell> { /// } /// # /// # Python::with_gil(|py| { -/// # let fun_slow = wrap_pyfunction!(create_dict, py).unwrap(); +/// # let fun_slow = wrap_pyfunction_bound!(create_dict, py).unwrap(); /// # let dict = fun_slow.call0().unwrap(); /// # assert!(dict.contains("foo").unwrap()); -/// # let fun = wrap_pyfunction!(create_dict_faster, py).unwrap(); +/// # let fun = wrap_pyfunction_bound!(create_dict_faster, py).unwrap(); /// # let dict = fun.call0().unwrap(); /// # assert!(dict.contains("foo").unwrap()); /// # }); diff --git a/src/tests/hygiene/pyfunction.rs b/src/tests/hygiene/pyfunction.rs index 9cfad0db..edc8b6e3 100644 --- a/src/tests/hygiene/pyfunction.rs +++ b/src/tests/hygiene/pyfunction.rs @@ -10,6 +10,7 @@ fn do_something(x: i32) -> crate::PyResult { #[test] fn invoke_wrap_pyfunction() { crate::Python::with_gil(|py| { + #[allow(deprecated)] let func = crate::wrap_pyfunction!(do_something)(py).unwrap(); crate::py_run!(py, func, r#"func(5)"#); }); diff --git a/src/types/bytearray.rs b/src/types/bytearray.rs index a860b4d4..55cda1a3 100644 --- a/src/types/bytearray.rs +++ b/src/types/bytearray.rs @@ -193,7 +193,7 @@ impl PyByteArray { /// } /// # fn main() -> PyResult<()> { /// # Python::with_gil(|py| -> PyResult<()> { - /// # let fun = wrap_pyfunction!(a_valid_function, py)?; + /// # let fun = wrap_pyfunction_bound!(a_valid_function, py)?; /// # let locals = pyo3::types::PyDict::new_bound(py); /// # locals.set_item("a_valid_function", fun)?; /// # @@ -355,7 +355,7 @@ pub trait PyByteArrayMethods<'py>: crate::sealed::Sealed { /// } /// # fn main() -> PyResult<()> { /// # Python::with_gil(|py| -> PyResult<()> { - /// # let fun = wrap_pyfunction!(a_valid_function, py)?; + /// # let fun = wrap_pyfunction_bound!(a_valid_function, py)?; /// # let locals = pyo3::types::PyDict::new_bound(py); /// # locals.set_item("a_valid_function", fun)?; /// # diff --git a/tests/test_anyhow.rs b/tests/test_anyhow.rs index 1807cfe9..d6f5c036 100644 --- a/tests/test_anyhow.rs +++ b/tests/test_anyhow.rs @@ -1,8 +1,10 @@ #![cfg(feature = "anyhow")] +use pyo3::wrap_pyfunction_bound; + #[test] fn test_anyhow_py_function_ok_result() { - use pyo3::{py_run, pyfunction, wrap_pyfunction, Python}; + use pyo3::{py_run, pyfunction, Python}; #[pyfunction] #[allow(clippy::unnecessary_wraps)] @@ -11,7 +13,7 @@ fn test_anyhow_py_function_ok_result() { } Python::with_gil(|py| { - let func = wrap_pyfunction!(produce_ok_result)(py).unwrap(); + let func = wrap_pyfunction_bound!(produce_ok_result)(py).unwrap(); py_run!( py, @@ -26,7 +28,7 @@ fn test_anyhow_py_function_ok_result() { #[test] fn test_anyhow_py_function_err_result() { use pyo3::prelude::PyDictMethods; - use pyo3::{pyfunction, types::PyDict, wrap_pyfunction, Python}; + use pyo3::{pyfunction, types::PyDict, Python}; #[pyfunction] fn produce_err_result() -> anyhow::Result { @@ -34,7 +36,7 @@ fn test_anyhow_py_function_err_result() { } Python::with_gil(|py| { - let func = wrap_pyfunction!(produce_err_result)(py).unwrap(); + let func = wrap_pyfunction_bound!(produce_err_result)(py).unwrap(); let locals = PyDict::new_bound(py); locals.set_item("func", func).unwrap(); diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index cdb4ec15..a3f1e2fc 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -14,7 +14,7 @@ fn bytes_pybytes_conversion(bytes: &[u8]) -> &[u8] { #[test] fn test_pybytes_bytes_conversion() { Python::with_gil(|py| { - let f = wrap_pyfunction!(bytes_pybytes_conversion)(py).unwrap(); + let f = wrap_pyfunction_bound!(bytes_pybytes_conversion)(py).unwrap(); py_assert!(py, f, "f(b'Hello World') == b'Hello World'"); }); } @@ -27,7 +27,7 @@ fn bytes_vec_conversion(py: Python<'_>, bytes: Vec) -> Bound<'_, PyBytes> { #[test] fn test_pybytes_vec_conversion() { Python::with_gil(|py| { - let f = wrap_pyfunction!(bytes_vec_conversion)(py).unwrap(); + let f = wrap_pyfunction_bound!(bytes_vec_conversion)(py).unwrap(); py_assert!(py, f, "f(b'Hello World') == b'Hello World'"); }); } @@ -35,7 +35,7 @@ fn test_pybytes_vec_conversion() { #[test] fn test_bytearray_vec_conversion() { Python::with_gil(|py| { - let f = wrap_pyfunction!(bytes_vec_conversion)(py).unwrap(); + let f = wrap_pyfunction_bound!(bytes_vec_conversion)(py).unwrap(); py_assert!(py, f, "f(bytearray(b'Hello World')) == b'Hello World'"); }); } diff --git a/tests/test_coroutine.rs b/tests/test_coroutine.rs index 17539fa1..23f6a672 100644 --- a/tests/test_coroutine.rs +++ b/tests/test_coroutine.rs @@ -30,7 +30,7 @@ fn noop_coroutine() { 42 } Python::with_gil(|gil| { - let noop = wrap_pyfunction!(noop, gil).unwrap(); + let noop = wrap_pyfunction_bound!(noop, gil).unwrap(); let test = "import asyncio; assert asyncio.run(noop()) == 42"; py_run!(gil, noop, &handle_windows(test)); }) @@ -68,7 +68,10 @@ fn test_coroutine_qualname() { let locals = [ ( "my_fn", - wrap_pyfunction!(my_fn, gil).unwrap().as_borrowed().as_any(), + wrap_pyfunction_bound!(my_fn, gil) + .unwrap() + .as_borrowed() + .as_any(), ), ("MyClass", gil.get_type_bound::().as_any()), ] @@ -93,7 +96,7 @@ fn sleep_0_like_coroutine() { .await } Python::with_gil(|gil| { - let sleep_0 = wrap_pyfunction!(sleep_0, gil).unwrap(); + let sleep_0 = wrap_pyfunction_bound!(sleep_0, gil).unwrap(); let test = "import asyncio; assert asyncio.run(sleep_0()) == 42"; py_run!(gil, sleep_0, &handle_windows(test)); }) @@ -112,7 +115,7 @@ async fn sleep(seconds: f64) -> usize { #[test] fn sleep_coroutine() { Python::with_gil(|gil| { - let sleep = wrap_pyfunction!(sleep, gil).unwrap(); + let sleep = wrap_pyfunction_bound!(sleep, gil).unwrap(); let test = r#"import asyncio; assert asyncio.run(sleep(0.1)) == 42"#; py_run!(gil, sleep, &handle_windows(test)); }) @@ -121,7 +124,7 @@ fn sleep_coroutine() { #[test] fn cancelled_coroutine() { Python::with_gil(|gil| { - let sleep = wrap_pyfunction!(sleep, gil).unwrap(); + let sleep = wrap_pyfunction_bound!(sleep, gil).unwrap(); let test = r#" import asyncio async def main(): @@ -160,7 +163,7 @@ fn coroutine_cancel_handle() { } } Python::with_gil(|gil| { - let cancellable_sleep = wrap_pyfunction!(cancellable_sleep, gil).unwrap(); + let cancellable_sleep = wrap_pyfunction_bound!(cancellable_sleep, gil).unwrap(); let test = r#" import asyncio; async def main(): @@ -192,7 +195,7 @@ fn coroutine_is_cancelled() { } } Python::with_gil(|gil| { - let sleep_loop = wrap_pyfunction!(sleep_loop, gil).unwrap(); + let sleep_loop = wrap_pyfunction_bound!(sleep_loop, gil).unwrap(); let test = r#" import asyncio; async def main(): @@ -220,7 +223,7 @@ fn coroutine_panic() { panic!("test panic"); } Python::with_gil(|gil| { - let panic = wrap_pyfunction!(panic, gil).unwrap(); + let panic = wrap_pyfunction_bound!(panic, gil).unwrap(); let test = r#" import asyncio coro = panic() diff --git a/tests/test_enum.rs b/tests/test_enum.rs index d73316e5..63492b8d 100644 --- a/tests/test_enum.rs +++ b/tests/test_enum.rs @@ -1,7 +1,7 @@ #![cfg(feature = "macros")] use pyo3::prelude::*; -use pyo3::{py_run, wrap_pyfunction}; +use pyo3::py_run; #[path = "../src/tests/common.rs"] mod common; @@ -30,7 +30,7 @@ fn return_enum() -> MyEnum { #[test] fn test_return_enum() { Python::with_gil(|py| { - let f = wrap_pyfunction!(return_enum)(py).unwrap(); + let f = wrap_pyfunction_bound!(return_enum)(py).unwrap(); let mynum = py.get_type_bound::(); py_run!(py, f mynum, "assert f() == mynum.Variant") @@ -45,7 +45,7 @@ fn enum_arg(e: MyEnum) { #[test] fn test_enum_arg() { Python::with_gil(|py| { - let f = wrap_pyfunction!(enum_arg)(py).unwrap(); + let f = wrap_pyfunction_bound!(enum_arg)(py).unwrap(); let mynum = py.get_type_bound::(); py_run!(py, f mynum, "f(mynum.OtherVariant)") diff --git a/tests/test_exceptions.rs b/tests/test_exceptions.rs index 36035860..ec2fe156 100644 --- a/tests/test_exceptions.rs +++ b/tests/test_exceptions.rs @@ -22,7 +22,7 @@ fn fail_to_open_file() -> PyResult<()> { #[cfg(not(target_os = "windows"))] fn test_filenotfounderror() { Python::with_gil(|py| { - let fail_to_open_file = wrap_pyfunction!(fail_to_open_file)(py).unwrap(); + let fail_to_open_file = wrap_pyfunction_bound!(fail_to_open_file)(py).unwrap(); py_run!( py, @@ -68,7 +68,7 @@ fn call_fail_with_custom_error() -> PyResult<()> { fn test_custom_error() { Python::with_gil(|py| { let call_fail_with_custom_error = - wrap_pyfunction!(call_fail_with_custom_error)(py).unwrap(); + wrap_pyfunction_bound!(call_fail_with_custom_error)(py).unwrap(); py_run!( py, diff --git a/tests/test_macros.rs b/tests/test_macros.rs index 0d2b125b..6a50e5b3 100644 --- a/tests/test_macros.rs +++ b/tests/test_macros.rs @@ -76,7 +76,7 @@ fn test_macro_rules_interactions() { let my_base = py.get_type_bound::(); py_assert!(py, my_base, "my_base.__name__ == 'MyClass'"); - let my_func = wrap_pyfunction!(my_function_in_macro, py).unwrap(); + let my_func = wrap_pyfunction_bound!(my_function_in_macro, py).unwrap(); py_assert!( py, my_func, diff --git a/tests/test_methods.rs b/tests/test_methods.rs index a9e7d37d..e7eacf26 100644 --- a/tests/test_methods.rs +++ b/tests/test_methods.rs @@ -1124,7 +1124,7 @@ fn test_option_pyclass_arg() { } Python::with_gil(|py| { - let f = wrap_pyfunction!(option_class_arg, py).unwrap(); + let f = wrap_pyfunction_bound!(option_class_arg, py).unwrap(); assert!(f.call0().unwrap().is_none()); let obj = Py::new(py, SomePyClass {}).unwrap(); assert!(f diff --git a/tests/test_pyfunction.rs b/tests/test_pyfunction.rs index 32c3ede6..5c435046 100644 --- a/tests/test_pyfunction.rs +++ b/tests/test_pyfunction.rs @@ -23,7 +23,7 @@ fn optional_bool(arg: Option) -> String { fn test_optional_bool() { // Regression test for issue #932 Python::with_gil(|py| { - let f = wrap_pyfunction!(optional_bool)(py).unwrap(); + let f = wrap_pyfunction_bound!(optional_bool)(py).unwrap(); py_assert!(py, f, "f() == 'Some(true)'"); py_assert!(py, f, "f(True) == 'Some(true)'"); @@ -47,7 +47,7 @@ fn buffer_inplace_add(py: Python<'_>, x: PyBuffer, y: PyBuffer) { #[test] fn test_buffer_add() { Python::with_gil(|py| { - let f = wrap_pyfunction!(buffer_inplace_add)(py).unwrap(); + let f = wrap_pyfunction_bound!(buffer_inplace_add)(py).unwrap(); py_expect_exception!( py, @@ -89,8 +89,8 @@ fn function_with_pycfunction_arg(fun: &PyCFunction) -> PyResult<&PyAny> { #[test] fn test_functions_with_function_args() { Python::with_gil(|py| { - let py_cfunc_arg = wrap_pyfunction!(function_with_pycfunction_arg)(py).unwrap(); - let bool_to_string = wrap_pyfunction!(optional_bool)(py).unwrap(); + let py_cfunc_arg = wrap_pyfunction_bound!(function_with_pycfunction_arg)(py).unwrap(); + let bool_to_string = wrap_pyfunction_bound!(optional_bool)(py).unwrap(); pyo3::py_run!( py, @@ -103,7 +103,7 @@ fn test_functions_with_function_args() { #[cfg(not(any(Py_LIMITED_API, PyPy)))] { - let py_func_arg = wrap_pyfunction!(function_with_pyfunction_arg)(py).unwrap(); + let py_func_arg = wrap_pyfunction_bound!(function_with_pyfunction_arg)(py).unwrap(); pyo3::py_run!( py, @@ -137,7 +137,7 @@ fn function_with_custom_conversion( #[test] fn test_function_with_custom_conversion() { Python::with_gil(|py| { - let custom_conv_func = wrap_pyfunction!(function_with_custom_conversion)(py).unwrap(); + let custom_conv_func = wrap_pyfunction_bound!(function_with_custom_conversion)(py).unwrap(); pyo3::py_run!( py, @@ -156,7 +156,7 @@ fn test_function_with_custom_conversion() { #[test] fn test_function_with_custom_conversion_error() { Python::with_gil(|py| { - let custom_conv_func = wrap_pyfunction!(function_with_custom_conversion)(py).unwrap(); + let custom_conv_func = wrap_pyfunction_bound!(function_with_custom_conversion)(py).unwrap(); py_expect_exception!( py, @@ -190,13 +190,13 @@ fn test_from_py_with_defaults() { } Python::with_gil(|py| { - let f = wrap_pyfunction!(from_py_with_option)(py).unwrap(); + let f = wrap_pyfunction_bound!(from_py_with_option)(py).unwrap(); assert_eq!(f.call0().unwrap().extract::().unwrap(), 0); assert_eq!(f.call1((123,)).unwrap().extract::().unwrap(), 123); assert_eq!(f.call1((999,)).unwrap().extract::().unwrap(), 999); - let f2 = wrap_pyfunction!(from_py_with_default)(py).unwrap(); + let f2 = wrap_pyfunction_bound!(from_py_with_default)(py).unwrap(); assert_eq!(f2.call0().unwrap().extract::().unwrap(), 0); assert_eq!(f2.call1(("123",)).unwrap().extract::().unwrap(), 3); @@ -228,7 +228,7 @@ fn conversion_error( #[test] fn test_conversion_error() { Python::with_gil(|py| { - let conversion_error = wrap_pyfunction!(conversion_error)(py).unwrap(); + let conversion_error = wrap_pyfunction_bound!(conversion_error)(py).unwrap(); py_expect_exception!( py, conversion_error, @@ -473,12 +473,12 @@ fn use_pyfunction() { use function_in_module::foo; // check imported name can be wrapped - let f = wrap_pyfunction!(foo, py).unwrap(); + let f = wrap_pyfunction_bound!(foo, py).unwrap(); assert_eq!(f.call1((5,)).unwrap().extract::().unwrap(), 5); assert_eq!(f.call1((42,)).unwrap().extract::().unwrap(), 42); // check path import can be wrapped - let f2 = wrap_pyfunction!(function_in_module::foo, py).unwrap(); + let f2 = wrap_pyfunction_bound!(function_in_module::foo, py).unwrap(); assert_eq!(f2.call1((5,)).unwrap().extract::().unwrap(), 5); assert_eq!(f2.call1((42,)).unwrap().extract::().unwrap(), 42); }) @@ -506,7 +506,7 @@ fn return_value_borrows_from_arguments<'py>( #[test] fn test_return_value_borrows_from_arguments() { Python::with_gil(|py| { - let function = wrap_pyfunction!(return_value_borrows_from_arguments, py).unwrap(); + let function = wrap_pyfunction_bound!(return_value_borrows_from_arguments, py).unwrap(); let key = Py::new(py, Key("key".to_owned())).unwrap(); let value = Py::new(py, Value(42)).unwrap(); @@ -530,7 +530,7 @@ fn test_some_wrap_arguments() { } Python::with_gil(|py| { - let function = wrap_pyfunction!(some_wrap_arguments, py).unwrap(); + let function = wrap_pyfunction_bound!(some_wrap_arguments, py).unwrap(); py_assert!(py, function, "function() == [1, 2, None, None]"); }) } @@ -546,7 +546,7 @@ fn test_reference_to_bound_arguments() { } Python::with_gil(|py| { - let function = wrap_pyfunction!(reference_args, py).unwrap(); + let function = wrap_pyfunction_bound!(reference_args, py).unwrap(); py_assert!(py, function, "function(1) == 1"); py_assert!(py, function, "function(1, 2) == 3"); }) diff --git a/tests/test_string.rs b/tests/test_string.rs index 02bf2ecd..d90c5a81 100644 --- a/tests/test_string.rs +++ b/tests/test_string.rs @@ -11,7 +11,7 @@ fn take_str(_s: &str) {} #[test] fn test_unicode_encode_error() { Python::with_gil(|py| { - let take_str = wrap_pyfunction!(take_str)(py).unwrap(); + let take_str = wrap_pyfunction_bound!(take_str)(py).unwrap(); py_expect_exception!( py, take_str, diff --git a/tests/test_text_signature.rs b/tests/test_text_signature.rs index 0b93500d..32a78346 100644 --- a/tests/test_text_signature.rs +++ b/tests/test_text_signature.rs @@ -101,7 +101,7 @@ fn test_function() { } Python::with_gil(|py| { - let f = wrap_pyfunction!(my_function)(py).unwrap(); + let f = wrap_pyfunction_bound!(my_function)(py).unwrap(); py_assert!(py, f, "f.__text_signature__ == '(a, b=None, *, c=42)'"); }); @@ -147,42 +147,42 @@ fn test_auto_test_signature_function() { } Python::with_gil(|py| { - let f = wrap_pyfunction!(my_function)(py).unwrap(); + let f = wrap_pyfunction_bound!(my_function)(py).unwrap(); py_assert!( py, f, "f.__text_signature__ == '(a, b, c)', f.__text_signature__" ); - let f = wrap_pyfunction!(my_function_2)(py).unwrap(); + let f = wrap_pyfunction_bound!(my_function_2)(py).unwrap(); py_assert!( py, f, "f.__text_signature__ == '($module, a, b, c)', f.__text_signature__" ); - let f = wrap_pyfunction!(my_function_3)(py).unwrap(); + let f = wrap_pyfunction_bound!(my_function_3)(py).unwrap(); py_assert!( py, f, "f.__text_signature__ == '(a, /, b=None, *, c=5)', f.__text_signature__" ); - let f = wrap_pyfunction!(my_function_4)(py).unwrap(); + let f = wrap_pyfunction_bound!(my_function_4)(py).unwrap(); py_assert!( py, f, "f.__text_signature__ == '(a, /, b=None, *args, c, d=5, **kwargs)', f.__text_signature__" ); - let f = wrap_pyfunction!(my_function_5)(py).unwrap(); + let f = wrap_pyfunction_bound!(my_function_5)(py).unwrap(); py_assert!( py, f, "f.__text_signature__ == '(a=1, /, b=None, c=1.5, d=5, e=\"pyo3\", f=\\'f\\', h=True)', f.__text_signature__" ); - let f = wrap_pyfunction!(my_function_6)(py).unwrap(); + let f = wrap_pyfunction_bound!(my_function_6)(py).unwrap(); py_assert!( py, f, @@ -317,10 +317,10 @@ fn test_auto_test_signature_opt_out() { } Python::with_gil(|py| { - let f = wrap_pyfunction!(my_function)(py).unwrap(); + let f = wrap_pyfunction_bound!(my_function)(py).unwrap(); py_assert!(py, f, "f.__text_signature__ == None"); - let f = wrap_pyfunction!(my_function_2)(py).unwrap(); + let f = wrap_pyfunction_bound!(my_function_2)(py).unwrap(); py_assert!(py, f, "f.__text_signature__ == None"); let cls = py.get_type_bound::(); diff --git a/tests/test_various.rs b/tests/test_various.rs index 250f3983..0e619f49 100644 --- a/tests/test_various.rs +++ b/tests/test_various.rs @@ -56,7 +56,7 @@ fn return_custom_class() { assert_eq!(get_zero().value, 0); // Using from python - let get_zero = wrap_pyfunction!(get_zero)(py).unwrap(); + let get_zero = wrap_pyfunction_bound!(get_zero)(py).unwrap(); py_assert!(py, get_zero, "get_zero().value == 0"); }); } @@ -201,6 +201,6 @@ fn result_conversion_function() -> Result<(), MyError> { #[test] fn test_result_conversion() { Python::with_gil(|py| { - wrap_pyfunction!(result_conversion_function)(py).unwrap(); + wrap_pyfunction_bound!(result_conversion_function)(py).unwrap(); }); } diff --git a/tests/test_wrap_pyfunction_deduction.rs b/tests/test_wrap_pyfunction_deduction.rs index 52c9adcb..845cf2a3 100644 --- a/tests/test_wrap_pyfunction_deduction.rs +++ b/tests/test_wrap_pyfunction_deduction.rs @@ -11,6 +11,7 @@ pub fn add_wrapped(wrapper: &impl Fn(Python<'_>) -> PyResult<&PyCFunction>) { #[test] fn wrap_pyfunction_deduction() { + #[allow(deprecated)] add_wrapped(wrap_pyfunction!(f)); } diff --git a/tests/ui/deprecations.rs b/tests/ui/deprecations.rs index c062cead..1f3cc302 100644 --- a/tests/ui/deprecations.rs +++ b/tests/ui/deprecations.rs @@ -72,3 +72,19 @@ fn module_bound_by_value(m: Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(double, &m)?)?; Ok(()) } + +fn test_wrap_pyfunction(py: Python<'_>, m: &Bound<'_, PyModule>) { + // should lint + let _ = wrap_pyfunction!(double, py); + + // should lint but currently does not + let _ = wrap_pyfunction!(double)(py); + + // should not lint + let _ = wrap_pyfunction!(double, m); + let _ = wrap_pyfunction!(double)(m); + let _ = wrap_pyfunction!(double, m.as_gil_ref()); + let _ = wrap_pyfunction!(double)(m.as_gil_ref()); + let _ = wrap_pyfunction_bound!(double, py); + let _ = wrap_pyfunction_bound!(double)(py); +} diff --git a/tests/ui/deprecations.stderr b/tests/ui/deprecations.stderr index edb74f97..d4a3e01f 100644 --- a/tests/ui/deprecations.stderr +++ b/tests/ui/deprecations.stderr @@ -45,3 +45,11 @@ error: use of deprecated method `pyo3::methods::Extractor::::extract_gil_ref` | 53 | fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, m: &PyModule) -> PyResult<()> { | ^ + +error: use of deprecated method `pyo3::methods::Extractor::>::is_python`: use `wrap_pyfunction_bound!` instead + --> tests/ui/deprecations.rs:78:13 + | +78 | 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_result_conversion.rs b/tests/ui/invalid_result_conversion.rs index 4cf3e0bd..373d3cac 100644 --- a/tests/ui/invalid_result_conversion.rs +++ b/tests/ui/invalid_result_conversion.rs @@ -20,11 +20,13 @@ impl fmt::Display for MyError { #[pyfunction] fn should_not_work() -> Result<(), MyError> { - Err(MyError { descr: "something went wrong" }) + Err(MyError { + descr: "something went wrong", + }) } fn main() { - Python::with_gil(|py|{ - wrap_pyfunction!(should_not_work)(py); + Python::with_gil(|py| { + wrap_pyfunction_bound!(should_not_work)(py); }); }