From 99026331160952462120afb09ba8b43193b3bc5c Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:03:04 +0100 Subject: [PATCH] allow `from_py_with` on function args to take a `fn(&Bound) -> PyResult` (#3837) --- pyo3-macros-backend/src/params.rs | 8 ++++---- src/impl_/extract_argument.rs | 14 +++++++------- src/impl_/frompyobject.rs | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pyo3-macros-backend/src/params.rs b/pyo3-macros-backend/src/params.rs index 1ef31867..3781b41b 100644 --- a/pyo3-macros-backend/src/params.rs +++ b/pyo3-macros-backend/src/params.rs @@ -217,18 +217,18 @@ fn impl_arg_param( quote_arg_span! { #[allow(clippy::redundant_closure)] _pyo3::impl_::extract_argument::from_py_with_with_default( - #arg_value, + #arg_value.map(_pyo3::PyNativeType::as_borrowed).as_deref(), #name_str, - #expr_path, + #expr_path as fn(_) -> _, || #default )? } } else { quote_arg_span! { _pyo3::impl_::extract_argument::from_py_with( - _pyo3::impl_::extract_argument::unwrap_required_argument(#arg_value), + &_pyo3::impl_::extract_argument::unwrap_required_argument(#arg_value).as_borrowed(), #name_str, - #expr_path, + #expr_path as fn(_) -> _, )? } } diff --git a/src/impl_/extract_argument.rs b/src/impl_/extract_argument.rs index 4df674e7..ff1c2436 100644 --- a/src/impl_/extract_argument.rs +++ b/src/impl_/extract_argument.rs @@ -133,12 +133,12 @@ where /// Alternative to [`extract_argument`] used when the argument has a `#[pyo3(from_py_with)]` annotation. #[doc(hidden)] -pub fn from_py_with<'py, T>( - obj: &'py PyAny, +pub fn from_py_with<'a, 'py, T>( + obj: &'a Bound<'py, PyAny>, arg_name: &str, - extractor: fn(&'py PyAny) -> PyResult, + extractor: impl Into>, ) -> PyResult { - match extractor(obj) { + match extractor.into().call(obj) { Ok(value) => Ok(value), Err(e) => Err(argument_extraction_error(obj.py(), arg_name, e)), } @@ -146,10 +146,10 @@ pub fn from_py_with<'py, T>( /// Alternative to [`extract_argument`] used when the argument has a `#[pyo3(from_py_with)]` annotation and also a default value. #[doc(hidden)] -pub fn from_py_with_with_default<'py, T>( - obj: Option<&'py PyAny>, +pub fn from_py_with_with_default<'a, 'py, T>( + obj: Option<&'a Bound<'py, PyAny>>, arg_name: &str, - extractor: fn(&'py PyAny) -> PyResult, + extractor: impl Into>, default: fn() -> T, ) -> PyResult { match obj { diff --git a/src/impl_/frompyobject.rs b/src/impl_/frompyobject.rs index 5ab595ca..e38ff3c7 100644 --- a/src/impl_/frompyobject.rs +++ b/src/impl_/frompyobject.rs @@ -20,7 +20,7 @@ impl<'a, T> From PyResult> for Extractor<'a, '_, T> { } impl<'a, 'py, T> Extractor<'a, 'py, T> { - fn call(self, obj: &'a Bound<'py, PyAny>) -> PyResult { + pub(crate) fn call(self, obj: &'a Bound<'py, PyAny>) -> PyResult { match self { Extractor::Bound(f) => f(obj), Extractor::GilRef(f) => f(obj.as_gil_ref()),