From f09f9929765b1471e960fc905b2803bbb1dac215 Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:48:09 +0200 Subject: [PATCH] reintroduce `Py::call` and `Py::call_method` --- examples/decorator/src/lib.rs | 2 +- guide/src/python-from-rust/function-calls.md | 16 ++------ src/instance.rs | 43 ++++++++++++++++---- src/types/any.rs | 2 +- 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/examples/decorator/src/lib.rs b/examples/decorator/src/lib.rs index cfb09c112d5..8d257aecb2e 100644 --- a/examples/decorator/src/lib.rs +++ b/examples/decorator/src/lib.rs @@ -51,7 +51,7 @@ impl PyCounter { println!("{} has been called {} time(s).", name, new_count); // After doing something, we finally forward the call to the wrapped function - let ret = self.wraps.call_bound(py, args, kwargs)?; + let ret = self.wraps.call(py, args, kwargs)?; // We could do something with the return value of // the function before returning it diff --git a/guide/src/python-from-rust/function-calls.md b/guide/src/python-from-rust/function-calls.md index 22fcd8cacf0..12544dc02bd 100644 --- a/guide/src/python-from-rust/function-calls.md +++ b/guide/src/python-from-rust/function-calls.md @@ -91,26 +91,18 @@ fn main() -> PyResult<()> { // call object with PyDict let kwargs = [(key1, val1)].into_py_dict(py); - fun.call_bound(py, (), Some(&kwargs))?; + fun.call(py, (), Some(&kwargs))?; // pass arguments as Vec let kwargs = vec![(key1, val1), (key2, val2)]; - fun.call_bound(py, (), Some(&kwargs.into_py_dict(py)))?; + fun.call(py, (), Some(&kwargs.into_py_dict(py)))?; // pass arguments as HashMap let mut kwargs = HashMap::<&str, i32>::new(); kwargs.insert(key1, 1); - fun.call_bound(py, (), Some(&kwargs.into_py_dict(py)))?; + fun.call(py, (), Some(&kwargs.into_py_dict(py)))?; Ok(()) }) } -``` - -
- -During PyO3's [migration from "GIL Refs" to the `Bound` smart pointer](../migration.md#migrating-from-the-gil-refs-api-to-boundt), `Py::call` is temporarily named [`Py::call_bound`]({{#PYO3_DOCS_URL}}/pyo3/struct.Py.html#method.call_bound) (and `call_method` is temporarily `call_method_bound`). - -(This temporary naming is only the case for the `Py` smart pointer. The methods on the `&PyAny` GIL Ref such as `call` have not been given replacements, and the methods on the `Bound` smart pointer such as [`Bound::call`]({{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.call) already use follow the newest API conventions.) - -
+``` \ No newline at end of file diff --git a/src/instance.rs b/src/instance.rs index b0a4a38d176..c71cf89c02d 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -1449,18 +1449,30 @@ impl Py { /// Calls the object. /// /// This is equivalent to the Python expression `self(*args, **kwargs)`. - pub fn call_bound<'py, N>( + pub fn call<'py, A>( &self, py: Python<'py>, - args: N, + args: A, kwargs: Option<&Bound<'py, PyDict>>, ) -> PyResult where - N: IntoPy>, + A: IntoPy>, { self.bind(py).as_any().call(args, kwargs).map(Bound::unbind) } + /// Deprecated name for [`Py::call`]. + #[deprecated(since = "0.23.0", note = "renamed to `Py::call`")] + #[inline] + pub fn call_bound( + &self, + py: Python<'_>, + args: impl IntoPy>, + kwargs: Option<&Bound<'_, PyDict>>, + ) -> PyResult { + self.call(py, args, kwargs) + } + /// Calls the object with only positional arguments. /// /// This is equivalent to the Python expression `self(*args)`. @@ -1484,7 +1496,7 @@ impl Py { /// /// To avoid repeated temporary allocations of Python strings, the [`intern!`](crate::intern) /// macro can be used to intern `name`. - pub fn call_method_bound<'py, N, A>( + pub fn call_method<'py, N, A>( &self, py: Python<'py>, name: N, @@ -1501,6 +1513,23 @@ impl Py { .map(Bound::unbind) } + /// Deprecated name for [`Py::call_method`]. + #[deprecated(since = "0.23.0", note = "renamed to `Py::call_method`")] + #[inline] + pub fn call_method_bound( + &self, + py: Python<'_>, + name: N, + args: A, + kwargs: Option<&Bound<'_, PyDict>>, + ) -> PyResult + where + N: IntoPy>, + A: IntoPy>, + { + self.call_method(py, name.into_py(py), args, kwargs) + } + /// Calls a method on the object with only positional arguments. /// /// This is equivalent to the Python expression `self.name(*args)`. @@ -1904,11 +1933,11 @@ mod tests { assert_repr(obj.call0(py).unwrap().bind(py), "{}"); assert_repr(obj.call1(py, ()).unwrap().bind(py), "{}"); - assert_repr(obj.call_bound(py, (), None).unwrap().bind(py), "{}"); + assert_repr(obj.call(py, (), None).unwrap().bind(py), "{}"); assert_repr(obj.call1(py, ((('x', 1),),)).unwrap().bind(py), "{'x': 1}"); assert_repr( - obj.call_bound(py, (), Some(&[('x', 1)].into_py_dict(py))) + obj.call(py, (), Some(&[('x', 1)].into_py_dict(py))) .unwrap() .bind(py), "{'x': 1}", @@ -1922,7 +1951,7 @@ mod tests { let obj: PyObject = PyDict::new(py).into(); assert!(obj.call_method0(py, "asdf").is_err()); assert!(obj - .call_method_bound(py, "nonexistent_method", (1,), None) + .call_method(py, "nonexistent_method", (1,), None) .is_err()); assert!(obj.call_method0(py, "nonexistent_method").is_err()); assert!(obj.call_method1(py, "nonexistent_method", (1,)).is_err()); diff --git a/src/types/any.rs b/src/types/any.rs index be3b56deb35..4d786a2144c 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -1699,7 +1699,7 @@ class NonHeapNonDescriptorInt: Python::with_gil(|py| { let list = vec![3, 6, 5, 4, 7].to_object(py); let dict = vec![("reverse", true)].into_py_dict(py); - list.call_method_bound(py, "sort", (), Some(&dict)).unwrap(); + list.call_method(py, "sort", (), Some(&dict)).unwrap(); assert_eq!(list.extract::>(py).unwrap(), vec![7, 6, 5, 4, 3]); }); }