deprecate `wrap_pyfunction` with `py` argument (#3954)
* deprecate `wrap_pyfunction` with `py` argument The Python token in `wrap_pyfunction` is not handled automatically by `WrapPyFunctionArg`, for backwards compatibility. This uses deref specialization to deprecate this variant. * merge `Extractor`s * add deprecation ui test, revert closure variant due to test failure * fix nightly
This commit is contained in:
parent
a7fa1bdf22
commit
ee89b2e8e2
|
@ -499,7 +499,7 @@ _without_ having a unique python type.
|
|||
|
||||
```rust
|
||||
use pyo3::prelude::*;
|
||||
|
||||
# #[allow(dead_code)]
|
||||
struct MyPyObjectWrapper(PyObject);
|
||||
|
||||
impl IntoPy<PyObject> for MyPyObjectWrapper {
|
||||
|
|
|
@ -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<MyPyObjectWrapper> for PyObject {
|
|||
After
|
||||
```rust
|
||||
# use pyo3::prelude::*;
|
||||
# #[allow(dead_code)]
|
||||
struct MyPyObjectWrapper(PyObject);
|
||||
|
||||
impl IntoPy<PyObject> for MyPyObjectWrapper {
|
||||
|
|
|
@ -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::<SimpleEnum>()?;
|
||||
m.add_class::<ComplexEnum>()?;
|
||||
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(())
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ pub trait ToPyObject {
|
|||
/// ```rust
|
||||
/// use pyo3::prelude::*;
|
||||
///
|
||||
/// # #[allow(dead_code)]
|
||||
/// struct Number {
|
||||
/// value: i32,
|
||||
/// }
|
||||
|
|
|
@ -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<Vec<u8>> {
|
||||
//! let fun = wrap_pyfunction!(py_open, py)?;
|
||||
//! let fun = wrap_pyfunction_bound!(py_open, py)?;
|
||||
//! let text = fun.call1(("foo.txt",))?.extract::<Vec<u8>>()?;
|
||||
//! Ok(text)
|
||||
//! }).unwrap_err();
|
||||
|
|
|
@ -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<Vec<u8>> {
|
||||
//! let fun = wrap_pyfunction!(py_open, py)?;
|
||||
//! let fun = wrap_pyfunction_bound!(py_open, py)?;
|
||||
//! let text = fun.call1(("foo.txt",))?.extract::<Vec<u8>>()?;
|
||||
//! Ok(text)
|
||||
//! }).unwrap_err();
|
||||
|
|
|
@ -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<Py<PyCFunction>> = 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(
|
||||
|
|
|
@ -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::<PyTypeError>(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::<PyTypeError>(py))
|
||||
/// # });
|
||||
|
|
|
@ -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::<MyError>())?;
|
||||
/// # 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", $name, ">(py))
|
||||
# });
|
||||
|
|
|
@ -599,6 +599,14 @@ impl<T> Extractor<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Extractor<Python<'_>> {
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(since = "0.21.0", note = "use `wrap_pyfunction_bound!` instead")
|
||||
)]
|
||||
pub fn is_python(&self) {}
|
||||
}
|
||||
|
||||
impl<T: IsGilRef> Extractor<T> {
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
|
@ -612,6 +620,7 @@ impl<T: IsGilRef> Extractor<T> {
|
|||
|
||||
impl<T> NotAGilRef<T> {
|
||||
pub fn extract_gil_ref(&self) {}
|
||||
pub fn is_python(&self) {}
|
||||
}
|
||||
|
||||
impl<T> std::ops::Deref for Extractor<T> {
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
}};
|
||||
|
|
|
@ -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::<u32>()?, 6_u32);
|
||||
/// # Ok(())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -220,7 +220,7 @@ impl GILOnceCell<Py<PyType>> {
|
|||
///
|
||||
/// ```
|
||||
/// 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<Bound<'_, PyDict>> {
|
||||
|
@ -241,10 +241,10 @@ impl GILOnceCell<Py<PyType>> {
|
|||
/// }
|
||||
/// #
|
||||
/// # 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());
|
||||
/// # });
|
||||
|
|
|
@ -10,6 +10,7 @@ fn do_something(x: i32) -> crate::PyResult<i32> {
|
|||
#[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)"#);
|
||||
});
|
||||
|
|
|
@ -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)?;
|
||||
/// #
|
||||
|
|
|
@ -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<String> {
|
||||
|
@ -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();
|
||||
|
||||
|
|
|
@ -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<u8>) -> 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'");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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::<MyClass>().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()
|
||||
|
|
|
@ -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::<MyEnum>();
|
||||
|
||||
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::<MyEnum>();
|
||||
|
||||
py_run!(py, f mynum, "f(mynum.OtherVariant)")
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -76,7 +76,7 @@ fn test_macro_rules_interactions() {
|
|||
let my_base = py.get_type_bound::<MyBaseClass>();
|
||||
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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,7 +23,7 @@ fn optional_bool(arg: Option<bool>) -> 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<i32>, y: PyBuffer<i32>) {
|
|||
#[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::<i32>().unwrap(), 0);
|
||||
assert_eq!(f.call1((123,)).unwrap().extract::<i32>().unwrap(), 123);
|
||||
assert_eq!(f.call1((999,)).unwrap().extract::<i32>().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::<usize>().unwrap(), 0);
|
||||
assert_eq!(f2.call1(("123",)).unwrap().extract::<usize>().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::<i32>().unwrap(), 5);
|
||||
assert_eq!(f.call1((42,)).unwrap().extract::<i32>().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::<i32>().unwrap(), 5);
|
||||
assert_eq!(f2.call1((42,)).unwrap().extract::<i32>().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");
|
||||
})
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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::<MyClass>();
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -45,3 +45,11 @@ error: use of deprecated method `pyo3::methods::Extractor::<T>::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::<pyo3::Python<'_>>::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)
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue