Skip to content

Commit 1fe867b

Browse files
committed
update extract_argument to use Bound APIs
1 parent d772303 commit 1fe867b

File tree

14 files changed

+362
-160
lines changed

14 files changed

+362
-160
lines changed

guide/src/class.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ impl<'a, 'py> pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'py> for &'a
12231223
type Holder = ::std::option::Option<pyo3::PyRef<'py, MyClass>>;
12241224

12251225
#[inline]
1226-
fn extract(obj: &'py pyo3::PyAny, holder: &'a mut Self::Holder) -> pyo3::PyResult<Self> {
1226+
fn extract(obj: pyo3::impl_::extract_argument::PyArg<'py>, holder: &'a mut Self::Holder) -> pyo3::PyResult<Self> {
12271227
pyo3::impl_::extract_argument::extract_pyclass_ref(obj, holder)
12281228
}
12291229
}
@@ -1233,7 +1233,7 @@ impl<'a, 'py> pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'py> for &'a
12331233
type Holder = ::std::option::Option<pyo3::PyRefMut<'py, MyClass>>;
12341234

12351235
#[inline]
1236-
fn extract(obj: &'py pyo3::PyAny, holder: &'a mut Self::Holder) -> pyo3::PyResult<Self> {
1236+
fn extract(obj: pyo3::impl_::extract_argument::PyArg<'py>, holder: &'a mut Self::Holder) -> pyo3::PyResult<Self> {
12371237
pyo3::impl_::extract_argument::extract_pyclass_ref_mut(obj, holder)
12381238
}
12391239
}

pyo3-macros-backend/src/method.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl SelfType {
191191
});
192192
error_mode.handle_error(quote_spanned! { *span =>
193193
_pyo3::impl_::extract_argument::#method::<#cls>(
194-
#py.from_borrowed_ptr::<_pyo3::PyAny>(#slf),
194+
_pyo3::impl_::extract_argument::PyArg::from_ptr(#py, #slf),
195195
&mut #holder,
196196
)
197197
})

pyo3-macros-backend/src/params.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ pub fn impl_arg_params(
4444
.collect::<Result<_>>()?;
4545
return Ok((
4646
quote! {
47-
let _args = py.from_borrowed_ptr::<_pyo3::types::PyTuple>(_args);
48-
let _kwargs: ::std::option::Option<&_pyo3::types::PyDict> = py.from_borrowed_ptr_or_opt(_kwargs);
47+
let _args = _pyo3::impl_::extract_argument::PyArg::from_ptr(py, _args);
48+
let _kwargs = _pyo3::impl_::extract_argument::PyArg::from_ptr_or_opt(py, _kwargs);
4949
},
5050
arg_convert,
5151
));
@@ -132,7 +132,7 @@ pub fn impl_arg_params(
132132
keyword_only_parameters: &[#(#keyword_only_parameters),*],
133133
};
134134
let mut #args_array = [::std::option::Option::None; #num_params];
135-
let (_args, _kwargs) = #extract_expression;
135+
let (_args, _kwargs) = &#extract_expression;
136136
},
137137
param_conversion,
138138
))
@@ -180,7 +180,8 @@ fn impl_arg_param(
180180
let holder = push_holder();
181181
return Ok(quote_arg_span! {
182182
_pyo3::impl_::extract_argument::extract_argument(
183-
_args,
183+
#[allow(clippy::useless_conversion)]
184+
::std::convert::From::from(_args),
184185
&mut #holder,
185186
#name_str
186187
)?
@@ -193,7 +194,8 @@ fn impl_arg_param(
193194
let holder = push_holder();
194195
return Ok(quote_arg_span! {
195196
_pyo3::impl_::extract_argument::extract_optional_argument(
196-
_kwargs.map(::std::convert::AsRef::as_ref),
197+
#[allow(clippy::useless_conversion, clippy::redundant_closure)]
198+
_kwargs.as_ref().map(|kwargs| ::std::convert::From::from(kwargs)),
197199
&mut #holder,
198200
#name_str,
199201
|| ::std::option::Option::None

pyo3-macros-backend/src/pyclass.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,7 +1369,7 @@ impl<'a> PyClassImplsBuilder<'a> {
13691369
type Holder = ::std::option::Option<_pyo3::PyRef<'py, #cls>>;
13701370

13711371
#[inline]
1372-
fn extract(obj: &'py _pyo3::PyAny, holder: &'a mut Self::Holder) -> _pyo3::PyResult<Self> {
1372+
fn extract(obj: _pyo3::impl_::extract_argument::PyArg<'py>, holder: &'a mut Self::Holder) -> _pyo3::PyResult<Self> {
13731373
_pyo3::impl_::extract_argument::extract_pyclass_ref(obj, holder)
13741374
}
13751375
}
@@ -1381,7 +1381,7 @@ impl<'a> PyClassImplsBuilder<'a> {
13811381
type Holder = ::std::option::Option<_pyo3::PyRef<'py, #cls>>;
13821382

13831383
#[inline]
1384-
fn extract(obj: &'py _pyo3::PyAny, holder: &'a mut Self::Holder) -> _pyo3::PyResult<Self> {
1384+
fn extract(obj: _pyo3::impl_::extract_argument::PyArg<'py>, holder: &'a mut Self::Holder) -> _pyo3::PyResult<Self> {
13851385
_pyo3::impl_::extract_argument::extract_pyclass_ref(obj, holder)
13861386
}
13871387
}
@@ -1391,7 +1391,7 @@ impl<'a> PyClassImplsBuilder<'a> {
13911391
type Holder = ::std::option::Option<_pyo3::PyRefMut<'py, #cls>>;
13921392

13931393
#[inline]
1394-
fn extract(obj: &'py _pyo3::PyAny, holder: &'a mut Self::Holder) -> _pyo3::PyResult<Self> {
1394+
fn extract(obj: _pyo3::impl_::extract_argument::PyArg<'py>, holder: &'a mut Self::Holder) -> _pyo3::PyResult<Self> {
13951395
_pyo3::impl_::extract_argument::extract_pyclass_ref_mut(obj, holder)
13961396
}
13971397
}

pyo3-macros-backend/src/pymethod.rs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -930,39 +930,31 @@ impl Ty {
930930
extract_error_mode,
931931
holders,
932932
&name_str,
933-
quote! {
934-
py.from_borrowed_ptr::<_pyo3::PyAny>(#ident)
935-
},
933+
quote! { #ident },
936934
),
937935
Ty::MaybeNullObject => extract_object(
938936
extract_error_mode,
939937
holders,
940938
&name_str,
941939
quote! {
942-
py.from_borrowed_ptr::<_pyo3::PyAny>(
943-
if #ident.is_null() {
944-
_pyo3::ffi::Py_None()
945-
} else {
946-
#ident
947-
}
948-
)
940+
if #ident.is_null() {
941+
_pyo3::ffi::Py_None()
942+
} else {
943+
#ident
944+
}
949945
},
950946
),
951947
Ty::NonNullObject => extract_object(
952948
extract_error_mode,
953949
holders,
954950
&name_str,
955-
quote! {
956-
py.from_borrowed_ptr::<_pyo3::PyAny>(#ident.as_ptr())
957-
},
951+
quote! { #ident.as_ptr() },
958952
),
959953
Ty::IPowModulo => extract_object(
960954
extract_error_mode,
961955
holders,
962956
&name_str,
963-
quote! {
964-
#ident.to_borrowed_any(py)
965-
},
957+
quote! { #ident.as_ptr() },
966958
),
967959
Ty::CompareOp => extract_error_mode.handle_error(
968960
quote! {
@@ -988,7 +980,7 @@ fn extract_object(
988980
extract_error_mode: ExtractErrorMode,
989981
holders: &mut Vec<TokenStream>,
990982
name: &str,
991-
source: TokenStream,
983+
source_ptr: TokenStream,
992984
) -> TokenStream {
993985
let holder = syn::Ident::new(&format!("holder_{}", holders.len()), Span::call_site());
994986
holders.push(quote! {
@@ -997,7 +989,7 @@ fn extract_object(
997989
});
998990
extract_error_mode.handle_error(quote! {
999991
_pyo3::impl_::extract_argument::extract_argument(
1000-
#source,
992+
_pyo3::impl_::extract_argument::PyArg::from_ptr(py, #source_ptr),
1001993
&mut #holder,
1002994
#name
1003995
)

pyo3-macros-backend/src/quotes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub(crate) fn ok_wrap(obj: TokenStream) -> TokenStream {
1616

1717
pub(crate) fn map_result_into_ptr(result: TokenStream) -> TokenStream {
1818
quote! {
19-
_pyo3::impl_::wrap::map_result_into_ptr(py, #result)
19+
let result = _pyo3::impl_::wrap::map_result_into_ptr(py, #result);
20+
result
2021
}
2122
}

pytests/src/pyfunctions.rs

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,62 +4,66 @@ use pyo3::types::{PyDict, PyTuple};
44
#[pyfunction(signature = ())]
55
fn none() {}
66

7+
type Any<'py> = Bound<'py, PyAny>;
8+
type Dict<'py> = Bound<'py, PyDict>;
9+
type Tuple<'py> = Bound<'py, PyTuple>;
10+
711
#[pyfunction(signature = (a, b = None, *, c = None))]
8-
fn simple<'a>(
9-
a: &'a PyAny,
10-
b: Option<&'a PyAny>,
11-
c: Option<&'a PyAny>,
12-
) -> (&'a PyAny, Option<&'a PyAny>, Option<&'a PyAny>) {
12+
fn simple<'py>(
13+
a: Any<'py>,
14+
b: Option<Any<'py>>,
15+
c: Option<Any<'py>>,
16+
) -> (Any<'py>, Option<Any<'py>>, Option<Any<'py>>) {
1317
(a, b, c)
1418
}
1519

1620
#[pyfunction(signature = (a, b = None, *args, c = None))]
17-
fn simple_args<'a>(
18-
a: &'a PyAny,
19-
b: Option<&'a PyAny>,
20-
args: &'a PyTuple,
21-
c: Option<&'a PyAny>,
22-
) -> (&'a PyAny, Option<&'a PyAny>, &'a PyTuple, Option<&'a PyAny>) {
21+
fn simple_args<'py>(
22+
a: Any<'py>,
23+
b: Option<Any<'py>>,
24+
args: Tuple<'py>,
25+
c: Option<Any<'py>>,
26+
) -> (Any<'py>, Option<Any<'py>>, Tuple<'py>, Option<Any<'py>>) {
2327
(a, b, args, c)
2428
}
2529

2630
#[pyfunction(signature = (a, b = None, c = None, **kwargs))]
27-
fn simple_kwargs<'a>(
28-
a: &'a PyAny,
29-
b: Option<&'a PyAny>,
30-
c: Option<&'a PyAny>,
31-
kwargs: Option<&'a PyDict>,
31+
fn simple_kwargs<'py>(
32+
a: Any<'py>,
33+
b: Option<Any<'py>>,
34+
c: Option<Any<'py>>,
35+
kwargs: Option<Dict<'py>>,
3236
) -> (
33-
&'a PyAny,
34-
Option<&'a PyAny>,
35-
Option<&'a PyAny>,
36-
Option<&'a PyDict>,
37+
Any<'py>,
38+
Option<Any<'py>>,
39+
Option<Any<'py>>,
40+
Option<Dict<'py>>,
3741
) {
3842
(a, b, c, kwargs)
3943
}
4044

4145
#[pyfunction(signature = (a, b = None, *args, c = None, **kwargs))]
42-
fn simple_args_kwargs<'a>(
43-
a: &'a PyAny,
44-
b: Option<&'a PyAny>,
45-
args: &'a PyTuple,
46-
c: Option<&'a PyAny>,
47-
kwargs: Option<&'a PyDict>,
46+
fn simple_args_kwargs<'py>(
47+
a: Any<'py>,
48+
b: Option<Any<'py>>,
49+
args: Tuple<'py>,
50+
c: Option<Any<'py>>,
51+
kwargs: Option<Dict<'py>>,
4852
) -> (
49-
&'a PyAny,
50-
Option<&'a PyAny>,
51-
&'a PyTuple,
52-
Option<&'a PyAny>,
53-
Option<&'a PyDict>,
53+
Any<'py>,
54+
Option<Any<'py>>,
55+
Tuple<'py>,
56+
Option<Any<'py>>,
57+
Option<Dict<'py>>,
5458
) {
5559
(a, b, args, c, kwargs)
5660
}
5761

5862
#[pyfunction(signature = (*args, **kwargs))]
59-
fn args_kwargs<'a>(
60-
args: &'a PyTuple,
61-
kwargs: Option<&'a PyDict>,
62-
) -> (&'a PyTuple, Option<&'a PyDict>) {
63+
fn args_kwargs<'py>(
64+
args: Tuple<'py>,
65+
kwargs: Option<Dict<'py>>,
66+
) -> (Tuple<'py>, Option<Dict<'py>>) {
6367
(args, kwargs)
6468
}
6569

src/err/mod.rs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
exceptions::{self, PyBaseException},
88
ffi,
99
};
10-
use crate::{IntoPy, Py, PyAny, PyNativeType, PyObject, Python, ToPyObject};
10+
use crate::{Borrowed, IntoPy, Py, PyAny, PyNativeType, PyObject, Python, ToPyObject};
1111
use std::borrow::Cow;
1212
use std::cell::UnsafeCell;
1313
use std::ffi::CString;
@@ -46,34 +46,47 @@ unsafe impl Sync for PyErr {}
4646
pub type PyResult<T> = Result<T, PyErr>;
4747

4848
/// Error that indicates a failure to convert a PyAny to a more specific Python type.
49-
#[derive(Debug)]
50-
pub struct PyDowncastError<'a> {
51-
from: &'a PyAny,
52-
to: Cow<'static, str>,
53-
}
49+
pub struct PyDowncastError<'py>(DowncastError<'py, 'py>);
5450

5551
impl<'a> PyDowncastError<'a> {
5652
/// Create a new `PyDowncastError` representing a failure to convert the object
5753
/// `from` into the type named in `to`.
5854
pub fn new(from: &'a PyAny, to: impl Into<Cow<'static, str>>) -> Self {
59-
PyDowncastError {
60-
from,
61-
to: to.into(),
62-
}
55+
PyDowncastError(DowncastError::new_from_borrowed(from.as_borrowed(), to))
56+
}
57+
}
58+
59+
impl std::fmt::Debug for PyDowncastError<'_> {
60+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61+
f.debug_struct("PyDowncastError")
62+
.field("from", &self.0.from)
63+
.field("to", &self.0.to)
64+
.finish()
6365
}
6466
}
6567

6668
/// Error that indicates a failure to convert a PyAny to a more specific Python type.
6769
#[derive(Debug)]
6870
pub struct DowncastError<'a, 'py> {
69-
from: &'a Bound<'py, PyAny>,
71+
from: Borrowed<'a, 'py, PyAny>,
7072
to: Cow<'static, str>,
7173
}
7274

7375
impl<'a, 'py> DowncastError<'a, 'py> {
7476
/// Create a new `PyDowncastError` representing a failure to convert the object
7577
/// `from` into the type named in `to`.
7678
pub fn new(from: &'a Bound<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
79+
DowncastError {
80+
from: from.as_borrowed(),
81+
to: to.into(),
82+
}
83+
}
84+
85+
/// Similar to [`DowncastError::new`], but from a `Borrowed` instead of a `Bound`.
86+
pub(crate) fn new_from_borrowed(
87+
from: Borrowed<'a, 'py, PyAny>,
88+
to: impl Into<Cow<'static, str>>,
89+
) -> Self {
7790
DowncastError {
7891
from,
7992
to: to.into(),
@@ -829,20 +842,15 @@ impl PyErrArguments for PyDowncastErrorArguments {
829842
/// Convert `PyDowncastError` to Python `TypeError`.
830843
impl<'a> std::convert::From<PyDowncastError<'a>> for PyErr {
831844
fn from(err: PyDowncastError<'_>) -> PyErr {
832-
let args = PyDowncastErrorArguments {
833-
from: err.from.get_type().into(),
834-
to: err.to,
835-
};
836-
837-
exceptions::PyTypeError::new_err(args)
845+
PyErr::from(err.0)
838846
}
839847
}
840848

841849
impl<'a> std::error::Error for PyDowncastError<'a> {}
842850

843851
impl<'a> std::fmt::Display for PyDowncastError<'a> {
844852
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
845-
display_downcast_error(f, &self.from.as_borrowed(), &self.to)
853+
self.0.fmt(f)
846854
}
847855
}
848856

@@ -882,13 +890,13 @@ impl std::error::Error for DowncastIntoError<'_> {}
882890

883891
impl std::fmt::Display for DowncastIntoError<'_> {
884892
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
885-
display_downcast_error(f, &self.from, &self.to)
893+
display_downcast_error(f, self.from.as_borrowed(), &self.to)
886894
}
887895
}
888896

889897
fn display_downcast_error(
890898
f: &mut std::fmt::Formatter<'_>,
891-
from: &Bound<'_, PyAny>,
899+
from: Borrowed<'_, '_, PyAny>,
892900
to: &str,
893901
) -> std::fmt::Result {
894902
write!(

0 commit comments

Comments
 (0)