-
Notifications
You must be signed in to change notification settings - Fork 851
add IntoPyObjectExt
trait
#4708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
8fc5e98
942cc97
5b3b4a7
8636c68
f3c1723
b2778a2
8b7c258
d1820dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -180,6 +180,9 @@ pub trait IntoPy<T>: Sized { | |
/// | ||
/// It functions similarly to std's [`TryInto`] trait, but requires a [GIL token](Python) | ||
/// as an argument. | ||
/// | ||
/// The [`into_pyobject`][IntoPyObject::into_pyobject] method is designed for maximum flexibility and efficiency; it | ||
/// - allows for a concrete Python type to be returned (the [`Target`][IntoPyObject::Target] associated type) | ||
#[cfg_attr( | ||
diagnostic_namespace, | ||
diagnostic::on_unimplemented( | ||
|
@@ -227,12 +230,7 @@ pub trait IntoPyObject<'py>: Sized { | |
I: IntoIterator<Item = Self> + AsRef<[Self]>, | ||
I::IntoIter: ExactSizeIterator<Item = Self>, | ||
{ | ||
let mut iter = iter.into_iter().map(|e| { | ||
e.into_pyobject(py) | ||
.map(BoundObject::into_any) | ||
.map(BoundObject::into_bound) | ||
.map_err(Into::into) | ||
}); | ||
let mut iter = iter.into_iter().map(|e| e.into_py_any(py)); | ||
let list = crate::types::list::try_new_from_iter(py, &mut iter); | ||
list.map(Bound::into_any) | ||
} | ||
|
@@ -250,12 +248,7 @@ pub trait IntoPyObject<'py>: Sized { | |
I: IntoIterator<Item = Self> + AsRef<[<Self as private::Reference>::BaseType]>, | ||
I::IntoIter: ExactSizeIterator<Item = Self>, | ||
{ | ||
let mut iter = iter.into_iter().map(|e| { | ||
e.into_pyobject(py) | ||
.map(BoundObject::into_any) | ||
.map(BoundObject::into_bound) | ||
.map_err(Into::into) | ||
}); | ||
let mut iter = iter.into_iter().map(|e| e.into_py_any(py)); | ||
let list = crate::types::list::try_new_from_iter(py, &mut iter); | ||
list.map(Bound::into_any) | ||
} | ||
|
@@ -347,6 +340,45 @@ where | |
} | ||
} | ||
|
||
mod into_pyobject_ext { | ||
pub trait Sealed {} | ||
impl<'py, T> Sealed for T where T: super::IntoPyObject<'py> {} | ||
} | ||
|
||
/// Convenience methods for common usages of [`IntoPyObject`]. Every type that implements | ||
/// [`IntoPyObject`] also implements this trait. | ||
/// | ||
/// These methods: | ||
/// - Drop type information from the output, returning a `PyAny` object. | ||
/// - Always convert the `Error` type to `PyErr`, which may incur a performance penalty but it | ||
/// more convenient in contexts where the `?` operator would produce a `PyErr` anyway. | ||
pub trait IntoPyObjectExt<'py>: IntoPyObject<'py> + into_pyobject_ext::Sealed { | ||
/// Converts `self` into an owned Python object, dropping type information. | ||
#[inline] | ||
fn into_py_any(self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> { | ||
self.into_pyobject(py) | ||
.map(|obj| obj.into_any().into_bound()) | ||
.map_err(Into::into) | ||
} | ||
|
||
/// Converts `self` into a Python object, dropping type information. | ||
/// | ||
/// This is typically only useful when the resulting output is going to be passed | ||
/// to another function that only needs to borrow the output. | ||
#[inline] | ||
fn into_bound_object_py_any( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The name of this method is open to bikeshedding, I think I'm happy with this but there's probably a better one. |
||
self, | ||
py: Python<'py>, | ||
) -> PyResult<<Self::Output as BoundObject<'py, Self::Target>>::Any> { | ||
match self.into_pyobject(py) { | ||
Ok(obj) => Ok(obj.into_any()), | ||
Err(err) => Err(err.into()), | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That seems reasonable to me; it certainly is common to |
||
} | ||
|
||
impl<'py, T> IntoPyObjectExt<'py> for T where T: IntoPyObject<'py> {} | ||
|
||
/// Extract a type from a Python object. | ||
/// | ||
/// | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to finish this list, had to run from my pc just now