From 4278c9ef1c741c20d56955694bb6afe11e582ba1 Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Sun, 25 Aug 2024 00:27:37 +0200 Subject: [PATCH] restrict `IntoPyObject::Error` to convert into `PyErr` --- src/conversion.rs | 4 +- src/conversions/chrono.rs | 1 - src/conversions/either.rs | 4 -- src/conversions/hashbrown.rs | 12 ++-- src/conversions/indexmap.rs | 10 ++- src/conversions/smallvec.rs | 2 - src/conversions/std/array.rs | 2 - src/conversions/std/map.rs | 20 +++--- src/conversions/std/set.rs | 4 -- src/conversions/std/slice.rs | 2 - src/conversions/std/vec.rs | 2 - src/impl_/pyclass.rs | 48 ++++--------- src/impl_/wrap.rs | 6 +- src/instance.rs | 6 -- src/types/any.rs | 128 +++++++++-------------------------- src/types/mapping.rs | 20 ++---- src/types/tuple.rs | 3 +- 17 files changed, 71 insertions(+), 203 deletions(-) diff --git a/src/conversion.rs b/src/conversion.rs index ffa290903d4..c74c529bbb8 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -284,7 +284,7 @@ pub trait IntoPyObject<'py>: Sized { /// used to minimize reference counting overhead. type Output: BoundObject<'py, Self::Target>; /// The type returned in the event of a conversion error. - type Error; + type Error: Into; /// Performs the conversion. fn into_pyobject(self, py: Python<'py>) -> Result; @@ -300,7 +300,6 @@ pub trait IntoPyObject<'py>: Sized { where I: IntoIterator + AsRef<[Self]>, I::IntoIter: ExactSizeIterator, - PyErr: From, { let mut iter = iter.into_iter().map(|e| { e.into_pyobject(py) @@ -324,7 +323,6 @@ pub trait IntoPyObject<'py>: Sized { Self: private::Reference, I: IntoIterator + AsRef<[::BaseType]>, I::IntoIter: ExactSizeIterator, - PyErr: From, { let mut iter = iter.into_iter().map(|e| { e.into_pyobject(py) diff --git a/src/conversions/chrono.rs b/src/conversions/chrono.rs index 42126bcb950..e33c12b93e7 100644 --- a/src/conversions/chrono.rs +++ b/src/conversions/chrono.rs @@ -1327,7 +1327,6 @@ mod tests { fn new_py_datetime_ob<'py, A>(py: Python<'py>, name: &str, args: A) -> Bound<'py, PyAny> where A: IntoPyObject<'py, Target = PyTuple>, - A::Error: Into, { py.import("datetime") .unwrap() diff --git a/src/conversions/either.rs b/src/conversions/either.rs index 3d4aeafa32b..43822347c81 100644 --- a/src/conversions/either.rs +++ b/src/conversions/either.rs @@ -71,8 +71,6 @@ impl<'py, L, R> IntoPyObject<'py> for Either where L: IntoPyObject<'py>, R: IntoPyObject<'py>, - L::Error: Into, - R::Error: Into, { type Target = PyAny; type Output = Bound<'py, Self::Target>; @@ -99,8 +97,6 @@ impl<'a, 'py, L, R> IntoPyObject<'py> for &'a Either where &'a L: IntoPyObject<'py>, &'a R: IntoPyObject<'py>, - <&'a L as IntoPyObject<'py>>::Error: Into, - <&'a R as IntoPyObject<'py>>::Error: Into, { type Target = PyAny; type Output = Bound<'py, Self::Target>; diff --git a/src/conversions/hashbrown.rs b/src/conversions/hashbrown.rs index 4189ee52a2e..84c9e888ca9 100644 --- a/src/conversions/hashbrown.rs +++ b/src/conversions/hashbrown.rs @@ -59,7 +59,6 @@ where K: IntoPyObject<'py> + cmp::Eq + hash::Hash, V: IntoPyObject<'py>, H: hash::BuildHasher, - PyErr: From + From, { type Target = PyDict; type Output = Bound<'py, Self::Target>; @@ -69,8 +68,8 @@ where let dict = PyDict::new(py); for (k, v) in self { dict.set_item( - k.into_pyobject(py)?.into_bound(), - v.into_pyobject(py)?.into_bound(), + k.into_pyobject(py).map_err(Into::into)?.into_bound(), + v.into_pyobject(py).map_err(Into::into)?.into_bound(), )?; } Ok(dict) @@ -82,7 +81,6 @@ where &'a K: IntoPyObject<'py> + cmp::Eq + hash::Hash, &'a V: IntoPyObject<'py>, H: hash::BuildHasher, - PyErr: From<<&'a K as IntoPyObject<'py>>::Error> + From<<&'a V as IntoPyObject<'py>>::Error>, { type Target = PyDict; type Output = Bound<'py, Self::Target>; @@ -92,8 +90,8 @@ where let dict = PyDict::new(py); for (k, v) in self { dict.set_item( - k.into_pyobject(py)?.into_bound(), - v.into_pyobject(py)?.into_bound(), + k.into_pyobject(py).map_err(Into::into)?.into_bound(), + v.into_pyobject(py).map_err(Into::into)?.into_bound(), )?; } Ok(dict) @@ -143,7 +141,6 @@ impl<'py, K, H> IntoPyObject<'py> for hashbrown::HashSet where K: IntoPyObject<'py> + cmp::Eq + hash::Hash, H: hash::BuildHasher, - PyErr: From, { type Target = PySet; type Output = Bound<'py, Self::Target>; @@ -166,7 +163,6 @@ impl<'a, 'py, K, H> IntoPyObject<'py> for &'a hashbrown::HashSet where &'a K: IntoPyObject<'py> + cmp::Eq + hash::Hash, H: hash::BuildHasher, - PyErr: From<<&'a K as IntoPyObject<'py>>::Error>, { type Target = PySet; type Output = Bound<'py, Self::Target>; diff --git a/src/conversions/indexmap.rs b/src/conversions/indexmap.rs index bd45d4d3164..03aba0e0fc3 100644 --- a/src/conversions/indexmap.rs +++ b/src/conversions/indexmap.rs @@ -122,7 +122,6 @@ where K: IntoPyObject<'py> + cmp::Eq + hash::Hash, V: IntoPyObject<'py>, H: hash::BuildHasher, - PyErr: From + From, { type Target = PyDict; type Output = Bound<'py, Self::Target>; @@ -132,8 +131,8 @@ where let dict = PyDict::new(py); for (k, v) in self { dict.set_item( - k.into_pyobject(py)?.into_bound(), - v.into_pyobject(py)?.into_bound(), + k.into_pyobject(py).map_err(Into::into)?.into_bound(), + v.into_pyobject(py).map_err(Into::into)?.into_bound(), )?; } Ok(dict) @@ -145,7 +144,6 @@ where &'a K: IntoPyObject<'py> + cmp::Eq + hash::Hash, &'a V: IntoPyObject<'py>, H: hash::BuildHasher, - PyErr: From<<&'a K as IntoPyObject<'py>>::Error> + From<<&'a V as IntoPyObject<'py>>::Error>, { type Target = PyDict; type Output = Bound<'py, Self::Target>; @@ -155,8 +153,8 @@ where let dict = PyDict::new(py); for (k, v) in self { dict.set_item( - k.into_pyobject(py)?.into_bound(), - v.into_pyobject(py)?.into_bound(), + k.into_pyobject(py).map_err(Into::into)?.into_bound(), + v.into_pyobject(py).map_err(Into::into)?.into_bound(), )?; } Ok(dict) diff --git a/src/conversions/smallvec.rs b/src/conversions/smallvec.rs index bffa54d00b9..8c13c7e8299 100644 --- a/src/conversions/smallvec.rs +++ b/src/conversions/smallvec.rs @@ -60,7 +60,6 @@ impl<'py, A> IntoPyObject<'py> for SmallVec where A: Array, A::Item: IntoPyObject<'py>, - PyErr: From<>::Error>, { type Target = PyAny; type Output = Bound<'py, Self::Target>; @@ -80,7 +79,6 @@ impl<'a, 'py, A> IntoPyObject<'py> for &'a SmallVec where A: Array, &'a A::Item: IntoPyObject<'py>, - PyErr: From<<&'a A::Item as IntoPyObject<'py>>::Error>, { type Target = PyAny; type Output = Bound<'py, Self::Target>; diff --git a/src/conversions/std/array.rs b/src/conversions/std/array.rs index 5645d87cfe5..5a07b224c5b 100644 --- a/src/conversions/std/array.rs +++ b/src/conversions/std/array.rs @@ -40,7 +40,6 @@ where impl<'py, T, const N: usize> IntoPyObject<'py> for [T; N] where T: IntoPyObject<'py>, - PyErr: From, { type Target = PyAny; type Output = Bound<'py, Self::Target>; @@ -59,7 +58,6 @@ where impl<'a, 'py, T, const N: usize> IntoPyObject<'py> for &'a [T; N] where &'a T: IntoPyObject<'py>, - PyErr: From<<&'a T as IntoPyObject<'py>>::Error>, { type Target = PyAny; type Output = Bound<'py, Self::Target>; diff --git a/src/conversions/std/map.rs b/src/conversions/std/map.rs index e1638150518..4aba5066ffe 100644 --- a/src/conversions/std/map.rs +++ b/src/conversions/std/map.rs @@ -54,7 +54,6 @@ where K: IntoPyObject<'py> + cmp::Eq + hash::Hash, V: IntoPyObject<'py>, H: hash::BuildHasher, - PyErr: From + From, { type Target = PyDict; type Output = Bound<'py, Self::Target>; @@ -64,8 +63,8 @@ where let dict = PyDict::new(py); for (k, v) in self { dict.set_item( - k.into_pyobject(py)?.into_bound(), - v.into_pyobject(py)?.into_bound(), + k.into_pyobject(py).map_err(Into::into)?.into_bound(), + v.into_pyobject(py).map_err(Into::into)?.into_bound(), )?; } Ok(dict) @@ -77,7 +76,6 @@ where &'a K: IntoPyObject<'py> + cmp::Eq + hash::Hash, &'a V: IntoPyObject<'py>, H: hash::BuildHasher, - PyErr: From<<&'a K as IntoPyObject<'py>>::Error> + From<<&'a V as IntoPyObject<'py>>::Error>, { type Target = PyDict; type Output = Bound<'py, Self::Target>; @@ -87,8 +85,8 @@ where let dict = PyDict::new(py); for (k, v) in self { dict.set_item( - k.into_pyobject(py)?.into_bound(), - v.into_pyobject(py)?.into_bound(), + k.into_pyobject(py).map_err(Into::into)?.into_bound(), + v.into_pyobject(py).map_err(Into::into)?.into_bound(), )?; } Ok(dict) @@ -117,7 +115,6 @@ impl<'py, K, V> IntoPyObject<'py> for collections::BTreeMap where K: IntoPyObject<'py> + cmp::Eq, V: IntoPyObject<'py>, - PyErr: From + From, { type Target = PyDict; type Output = Bound<'py, Self::Target>; @@ -127,8 +124,8 @@ where let dict = PyDict::new(py); for (k, v) in self { dict.set_item( - k.into_pyobject(py)?.into_bound(), - v.into_pyobject(py)?.into_bound(), + k.into_pyobject(py).map_err(Into::into)?.into_bound(), + v.into_pyobject(py).map_err(Into::into)?.into_bound(), )?; } Ok(dict) @@ -139,7 +136,6 @@ impl<'a, 'py, K, V> IntoPyObject<'py> for &'a collections::BTreeMap where &'a K: IntoPyObject<'py> + cmp::Eq, &'a V: IntoPyObject<'py>, - PyErr: From<<&'a K as IntoPyObject<'py>>::Error> + From<<&'a V as IntoPyObject<'py>>::Error>, { type Target = PyDict; type Output = Bound<'py, Self::Target>; @@ -149,8 +145,8 @@ where let dict = PyDict::new(py); for (k, v) in self { dict.set_item( - k.into_pyobject(py)?.into_bound(), - v.into_pyobject(py)?.into_bound(), + k.into_pyobject(py).map_err(Into::into)?.into_bound(), + v.into_pyobject(py).map_err(Into::into)?.into_bound(), )?; } Ok(dict) diff --git a/src/conversions/std/set.rs b/src/conversions/std/set.rs index 7108787370b..f0ea51f59ac 100644 --- a/src/conversions/std/set.rs +++ b/src/conversions/std/set.rs @@ -58,7 +58,6 @@ impl<'py, K, S> IntoPyObject<'py> for collections::HashSet where K: IntoPyObject<'py> + Eq + hash::Hash, S: hash::BuildHasher + Default, - PyErr: From, { type Target = PySet; type Output = Bound<'py, Self::Target>; @@ -81,7 +80,6 @@ impl<'a, 'py, K, H> IntoPyObject<'py> for &'a collections::HashSet where &'a K: IntoPyObject<'py> + Eq + hash::Hash, H: hash::BuildHasher, - PyErr: From<<&'a K as IntoPyObject<'py>>::Error>, { type Target = PySet; type Output = Bound<'py, Self::Target>; @@ -143,7 +141,6 @@ where impl<'py, K> IntoPyObject<'py> for collections::BTreeSet where K: IntoPyObject<'py> + cmp::Ord, - PyErr: From, { type Target = PySet; type Output = Bound<'py, Self::Target>; @@ -165,7 +162,6 @@ where impl<'a, 'py, K> IntoPyObject<'py> for &'a collections::BTreeSet where &'a K: IntoPyObject<'py> + cmp::Ord, - PyErr: From<<&'a K as IntoPyObject<'py>>::Error>, { type Target = PySet; type Output = Bound<'py, Self::Target>; diff --git a/src/conversions/std/slice.rs b/src/conversions/std/slice.rs index 9b9eb3dd3ec..a90d70a49f7 100644 --- a/src/conversions/std/slice.rs +++ b/src/conversions/std/slice.rs @@ -22,7 +22,6 @@ impl<'a> IntoPy for &'a [u8] { impl<'a, 'py, T> IntoPyObject<'py> for &'a [T] where &'a T: IntoPyObject<'py>, - PyErr: From<<&'a T as IntoPyObject<'py>>::Error>, { type Target = PyAny; type Output = Bound<'py, Self::Target>; @@ -86,7 +85,6 @@ impl<'py, T> IntoPyObject<'py> for Cow<'_, [T]> where T: Clone, for<'a> &'a T: IntoPyObject<'py>, - for<'a> PyErr: From<<&'a T as IntoPyObject<'py>>::Error>, { type Target = PyAny; type Output = Bound<'py, Self::Target>; diff --git a/src/conversions/std/vec.rs b/src/conversions/std/vec.rs index 40ad7eea8a0..1548f604e42 100644 --- a/src/conversions/std/vec.rs +++ b/src/conversions/std/vec.rs @@ -43,7 +43,6 @@ where impl<'py, T> IntoPyObject<'py> for Vec where T: IntoPyObject<'py>, - PyErr: From, { type Target = PyAny; type Output = Bound<'py, Self::Target>; @@ -62,7 +61,6 @@ where impl<'a, 'py, T> IntoPyObject<'py> for &'a Vec where &'a T: IntoPyObject<'py>, - PyErr: From<<&'a T as IntoPyObject<'py>>::Error>, { type Target = PyAny; type Output = Bound<'py, Self::Target>; diff --git a/src/impl_/pyclass.rs b/src/impl_/pyclass.rs index 86b6d4daf5b..1c47d01f9a2 100644 --- a/src/impl_/pyclass.rs +++ b/src/impl_/pyclass.rs @@ -1334,7 +1334,6 @@ where ClassT: PyClass, for<'a, 'py> &'a FieldT: IntoPyObject<'py>, Offset: OffsetCalculator, - for<'a, 'py> PyErr: From<<&'a FieldT as IntoPyObject<'py>>::Error>, { pub const fn generate(&self, name: &'static CStr, doc: &'static CStr) -> PyMethodDefType { PyMethodDefType::Getter(PyGetterDef { @@ -1362,7 +1361,6 @@ where ClassT: PyClass, Offset: OffsetCalculator, for<'py> FieldT: IntoPyObject<'py> + Clone, - for<'py> PyErr: std::convert::From<>::Error>, { pub const fn generate(&self, name: &'static CStr, doc: &'static CStr) -> PyMethodDefType { PyMethodDefType::Getter(PyGetterDef { @@ -1390,42 +1388,21 @@ where } } -#[cfg(diagnostic_namespace)] -#[diagnostic::on_unimplemented( - message = "`{Self}` cannot be converted to a Python object", - label = "required by `#[pyo3(get)]` to create a readable property from a field of type `{Self}`", - note = "implement `IntoPyObject` for `&{Self}` or `IntoPyObject + Clone` for `{Self}` to define the conversion" +#[cfg_attr( + diagnostic_namespace, + diagnostic::on_unimplemented( + message = "`{Self}` cannot be converted to a Python object", + label = "required by `#[pyo3(get)]` to create a readable property from a field of type `{Self}`", + note = "implement `IntoPyObject` for `&{Self}` or `IntoPyObject + Clone` for `{Self}` to define the conversion" + ) )] -pub trait PyO3GetField<'py>: IntoPyObject<'py, Error: Into> + Clone {} - -#[cfg(diagnostic_namespace)] -impl<'py, T> PyO3GetField<'py> for T -where - T: IntoPyObject<'py> + Clone, - PyErr: std::convert::From<>::Error>, -{ -} +pub trait PyO3GetField<'py>: IntoPyObject<'py> + Clone {} +impl<'py, T> PyO3GetField<'py> for T where T: IntoPyObject<'py> + Clone {} /// Base case attempts to use IntoPyObject + Clone impl> PyClassGetterGenerator { - #[cfg(not(diagnostic_namespace))] - pub const fn generate(&self, _name: &'static CStr, _doc: &'static CStr) -> PyMethodDefType - // The bound goes here rather than on the block so that this impl is always available - // if no specialization is used instead - where - for<'py> FieldT: IntoPyObject<'py> + Clone, - for<'py> PyErr: std::convert::From<>::Error>, - { - // unreachable not allowed in const - panic!( - "exists purely to emit diagnostics on unimplemented traits. When `ToPyObject` \ - and `IntoPy` are fully removed this will be replaced by the temporary `IntoPyObject` case above." - ) - } - - #[cfg(diagnostic_namespace)] pub const fn generate(&self, _name: &'static CStr, _doc: &'static CStr) -> PyMethodDefType // The bound goes here rather than on the block so that this impl is always available // if no specialization is used instead @@ -1541,14 +1518,16 @@ where ClassT: PyClass, for<'a, 'py> &'a FieldT: IntoPyObject<'py>, Offset: OffsetCalculator, - for<'a, 'py> PyErr: From<<&'a FieldT as IntoPyObject<'py>>::Error>, { let _holder = unsafe { ensure_no_mutable_alias::(py, &obj)? }; let value = field_from_object::(obj); // SAFETY: Offset is known to describe the location of the value, and // _holder is preventing mutable aliasing - Ok((unsafe { &*value }).into_pyobject(py)?.into_ptr()) + Ok((unsafe { &*value }) + .into_pyobject(py) + .map_err(Into::into)? + .into_ptr()) } fn pyo3_get_value_into_pyobject( @@ -1559,7 +1538,6 @@ where ClassT: PyClass, for<'py> FieldT: IntoPyObject<'py> + Clone, Offset: OffsetCalculator, - for<'py> >::Error: Into, { let _holder = unsafe { ensure_no_mutable_alias::(py, &obj)? }; let value = field_from_object::(obj); diff --git a/src/impl_/wrap.rs b/src/impl_/wrap.rs index f32faaf5b2b..c999cf40249 100644 --- a/src/impl_/wrap.rs +++ b/src/impl_/wrap.rs @@ -1,8 +1,8 @@ use std::{convert::Infallible, marker::PhantomData, ops::Deref}; use crate::{ - conversion::IntoPyObject, ffi, types::PyNone, Bound, BoundObject, IntoPy, PyErr, PyObject, - PyResult, Python, + conversion::IntoPyObject, ffi, types::PyNone, Bound, BoundObject, IntoPy, PyObject, PyResult, + Python, }; /// Used to wrap values in `Option` for default arguments. @@ -95,7 +95,6 @@ impl<'py, T: IntoPyObject<'py>, E> IntoPyObjectConverter> { pub fn map_into_pyobject(&self, py: Python<'py>, obj: PyResult) -> PyResult where T: IntoPyObject<'py>, - PyErr: From, { obj.and_then(|obj| obj.into_pyobject(py).map_err(Into::into)) .map(BoundObject::into_any) @@ -106,7 +105,6 @@ impl<'py, T: IntoPyObject<'py>, E> IntoPyObjectConverter> { pub fn map_into_ptr(&self, py: Python<'py>, obj: PyResult) -> PyResult<*mut ffi::PyObject> where T: IntoPyObject<'py>, - PyErr: From, { obj.and_then(|obj| obj.into_pyobject(py).map_err(Into::into)) .map(BoundObject::into_bound) diff --git a/src/instance.rs b/src/instance.rs index d6b9a0fb1e9..2517ff12d6b 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -1412,7 +1412,6 @@ impl Py { pub fn getattr<'py, N>(&self, py: Python<'py>, attr_name: N) -> PyResult where N: IntoPyObject<'py, Target = PyString>, - N::Error: Into, { self.bind(py).as_any().getattr(attr_name).map(Bound::unbind) } @@ -1443,8 +1442,6 @@ impl Py { where N: IntoPyObject<'py, Target = PyString>, V: IntoPyObject<'py>, - N::Error: Into, - V::Error: Into, { self.bind(py).as_any().setattr(attr_name, value) } @@ -1497,7 +1494,6 @@ impl Py { where N: IntoPyObject<'py, Target = PyString>, A: IntoPy>, - N::Error: Into, { self.bind(py) .as_any() @@ -1515,7 +1511,6 @@ impl Py { where N: IntoPyObject<'py, Target = PyString>, A: IntoPy>, - N::Error: Into, { self.bind(py) .as_any() @@ -1532,7 +1527,6 @@ impl Py { pub fn call_method0<'py, N>(&self, py: Python<'py>, name: N) -> PyResult where N: IntoPyObject<'py, Target = PyString>, - N::Error: Into, { self.bind(py).as_any().call_method0(name).map(Bound::unbind) } diff --git a/src/types/any.rs b/src/types/any.rs index 801b651ac1a..f71973d4417 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -81,8 +81,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// ``` fn hasattr(&self, attr_name: N) -> PyResult where - N: IntoPyObject<'py, Target = PyString>, - N::Error: Into; + N: IntoPyObject<'py, Target = PyString>; /// Retrieves an attribute value. /// @@ -108,8 +107,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// ``` fn getattr(&self, attr_name: N) -> PyResult> where - N: IntoPyObject<'py, Target = PyString>, - N::Error: Into; + N: IntoPyObject<'py, Target = PyString>; /// Sets an attribute value. /// @@ -136,9 +134,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { fn setattr(&self, attr_name: N, value: V) -> PyResult<()> where N: IntoPyObject<'py, Target = PyString>, - V: IntoPyObject<'py>, - N::Error: Into, - V::Error: Into; + V: IntoPyObject<'py>; /// Deletes an attribute. /// @@ -148,8 +144,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// to intern `attr_name`. fn delattr(&self, attr_name: N) -> PyResult<()> where - N: IntoPyObject<'py, Target = PyString>, - N::Error: Into; + N: IntoPyObject<'py, Target = PyString>; /// Returns an [`Ordering`] between `self` and `other`. /// @@ -199,8 +194,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// ``` fn compare(&self, other: O) -> PyResult where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Tests whether two Python objects obey a given [`CompareOp`]. /// @@ -238,8 +232,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// ``` fn rich_compare(&self, other: O, compare_op: CompareOp) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes the negative of self. /// @@ -264,135 +257,114 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// This is equivalent to the Python expression `self < other`. fn lt(&self, other: O) -> PyResult where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Tests whether this object is less than or equal to another. /// /// This is equivalent to the Python expression `self <= other`. fn le(&self, other: O) -> PyResult where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Tests whether this object is equal to another. /// /// This is equivalent to the Python expression `self == other`. fn eq(&self, other: O) -> PyResult where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Tests whether this object is not equal to another. /// /// This is equivalent to the Python expression `self != other`. fn ne(&self, other: O) -> PyResult where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Tests whether this object is greater than another. /// /// This is equivalent to the Python expression `self > other`. fn gt(&self, other: O) -> PyResult where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Tests whether this object is greater than or equal to another. /// /// This is equivalent to the Python expression `self >= other`. fn ge(&self, other: O) -> PyResult where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self + other`. fn add(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self - other`. fn sub(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self * other`. fn mul(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self @ other`. fn matmul(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self / other`. fn div(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self // other`. fn floor_div(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self % other`. fn rem(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `divmod(self, other)`. fn divmod(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self << other`. fn lshift(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self >> other`. fn rshift(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self ** other % modulus` (`pow(self, other, modulus)`). /// `py.None()` may be passed for the `modulus`. fn pow(&self, other: O1, modulus: O2) -> PyResult> where O1: IntoPyObject<'py>, - O2: IntoPyObject<'py>, - O1::Error: Into, - O2::Error: Into; + O2: IntoPyObject<'py>; /// Computes `self & other`. fn bitand(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self | other`. fn bitor(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Computes `self ^ other`. fn bitxor(&self, other: O) -> PyResult> where - O: IntoPyObject<'py>, - O::Error: Into; + O: IntoPyObject<'py>; /// Determines whether this object appears callable. /// @@ -559,8 +531,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { ) -> PyResult> where N: IntoPyObject<'py, Target = PyString>, - A: IntoPy>, - N::Error: Into; + A: IntoPy>; /// Calls a method on the object without arguments. /// @@ -597,8 +568,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// ``` fn call_method0(&self, name: N) -> PyResult> where - N: IntoPyObject<'py, Target = PyString>, - N::Error: Into; + N: IntoPyObject<'py, Target = PyString>; /// Calls a method on the object with only positional arguments. /// @@ -637,8 +607,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { fn call_method1(&self, name: N, args: A) -> PyResult> where N: IntoPyObject<'py, Target = PyString>, - A: IntoPy>, - N::Error: Into; + A: IntoPy>; /// Returns whether the object is considered to be true. /// @@ -666,8 +635,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// This is equivalent to the Python expression `self[key]`. fn get_item(&self, key: K) -> PyResult> where - K: IntoPyObject<'py>, - K::Error: Into; + K: IntoPyObject<'py>; /// Sets a collection item value. /// @@ -675,17 +643,14 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { fn set_item(&self, key: K, value: V) -> PyResult<()> where K: IntoPyObject<'py>, - V: IntoPyObject<'py>, - K::Error: Into, - V::Error: Into; + V: IntoPyObject<'py>; /// Deletes an item from the collection. /// /// This is equivalent to the Python expression `del self[key]`. fn del_item(&self, key: K) -> PyResult<()> where - K: IntoPyObject<'py>, - K::Error: Into; + K: IntoPyObject<'py>; /// Takes an object and returns an iterator for it. /// @@ -897,8 +862,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// This is equivalent to the Python expression `value in self`. fn contains(&self, value: V) -> PyResult where - V: IntoPyObject<'py>, - V::Error: Into; + V: IntoPyObject<'py>; /// Return a proxy object that delegates method calls to a parent or sibling class of type. /// @@ -913,7 +877,6 @@ macro_rules! implement_binop { fn $name(&self, other: O) -> PyResult> where O: IntoPyObject<'py>, - O::Error: Into, { fn inner<'py>( any: &Bound<'py, PyAny>, @@ -944,7 +907,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn hasattr(&self, attr_name: N) -> PyResult where N: IntoPyObject<'py, Target = PyString>, - N::Error: Into, { // PyObject_HasAttr suppresses all exceptions, which was the behaviour of `hasattr` in Python 2. // Use an implementation which suppresses only AttributeError, which is consistent with `hasattr` in Python 3. @@ -962,7 +924,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn getattr(&self, attr_name: N) -> PyResult> where N: IntoPyObject<'py, Target = PyString>, - N::Error: Into, { fn inner<'py>( any: &Bound<'py, PyAny>, @@ -987,8 +948,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { where N: IntoPyObject<'py, Target = PyString>, V: IntoPyObject<'py>, - N::Error: Into, - V::Error: Into, { fn inner( any: &Bound<'_, PyAny>, @@ -1018,7 +977,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn delattr(&self, attr_name: N) -> PyResult<()> where N: IntoPyObject<'py, Target = PyString>, - N::Error: Into, { fn inner(any: &Bound<'_, PyAny>, attr_name: &Bound<'_, PyString>) -> PyResult<()> { err::error_on_minusone(any.py(), unsafe { @@ -1039,7 +997,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn compare(&self, other: O) -> PyResult where O: IntoPyObject<'py>, - O::Error: Into, { fn inner(any: &Bound<'_, PyAny>, other: &Bound<'_, PyAny>) -> PyResult { let other = other.as_ptr(); @@ -1077,7 +1034,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn rich_compare(&self, other: O, compare_op: CompareOp) -> PyResult> where O: IntoPyObject<'py>, - O::Error: Into, { fn inner<'py>( any: &Bound<'py, PyAny>, @@ -1133,7 +1089,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn lt(&self, other: O) -> PyResult where O: IntoPyObject<'py>, - O::Error: Into, { self.rich_compare(other, CompareOp::Lt) .and_then(|any| any.is_truthy()) @@ -1142,7 +1097,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn le(&self, other: O) -> PyResult where O: IntoPyObject<'py>, - O::Error: Into, { self.rich_compare(other, CompareOp::Le) .and_then(|any| any.is_truthy()) @@ -1151,7 +1105,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn eq(&self, other: O) -> PyResult where O: IntoPyObject<'py>, - O::Error: Into, { self.rich_compare(other, CompareOp::Eq) .and_then(|any| any.is_truthy()) @@ -1160,7 +1113,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn ne(&self, other: O) -> PyResult where O: IntoPyObject<'py>, - O::Error: Into, { self.rich_compare(other, CompareOp::Ne) .and_then(|any| any.is_truthy()) @@ -1169,7 +1121,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn gt(&self, other: O) -> PyResult where O: IntoPyObject<'py>, - O::Error: Into, { self.rich_compare(other, CompareOp::Gt) .and_then(|any| any.is_truthy()) @@ -1178,7 +1129,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn ge(&self, other: O) -> PyResult where O: IntoPyObject<'py>, - O::Error: Into, { self.rich_compare(other, CompareOp::Ge) .and_then(|any| any.is_truthy()) @@ -1201,7 +1151,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn divmod(&self, other: O) -> PyResult> where O: IntoPyObject<'py>, - O::Error: Into, { fn inner<'py>( any: &Bound<'py, PyAny>, @@ -1229,8 +1178,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { where O1: IntoPyObject<'py>, O2: IntoPyObject<'py>, - O1::Error: Into, - O2::Error: Into, { fn inner<'py>( any: &Bound<'py, PyAny>, @@ -1297,7 +1244,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { where N: IntoPyObject<'py, Target = PyString>, A: IntoPy>, - N::Error: Into, { // Don't `args.into_py()`! This will lose the optimization of vectorcall. match kwargs { @@ -1312,7 +1258,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn call_method0(&self, name: N) -> PyResult> where N: IntoPyObject<'py, Target = PyString>, - N::Error: Into, { let py = self.py(); let name = name.into_pyobject(py).map_err(Into::into)?.into_bound(); @@ -1326,7 +1271,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { where N: IntoPyObject<'py, Target = PyString>, A: IntoPy>, - N::Error: Into, { args.__py_call_method_vectorcall1( self.py(), @@ -1360,7 +1304,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn get_item(&self, key: K) -> PyResult> where K: IntoPyObject<'py>, - K::Error: Into, { fn inner<'py>( any: &Bound<'py, PyAny>, @@ -1385,8 +1328,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { where K: IntoPyObject<'py>, V: IntoPyObject<'py>, - K::Error: Into, - V::Error: Into, { fn inner( any: &Bound<'_, PyAny>, @@ -1416,7 +1357,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn del_item(&self, key: K) -> PyResult<()> where K: IntoPyObject<'py>, - K::Error: Into, { fn inner(any: &Bound<'_, PyAny>, key: &Bound<'_, PyAny>) -> PyResult<()> { err::error_on_minusone(any.py(), unsafe { @@ -1581,7 +1521,6 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { fn contains(&self, value: V) -> PyResult where V: IntoPyObject<'py>, - V::Error: Into, { fn inner(any: &Bound<'_, PyAny>, value: &Bound<'_, PyAny>) -> PyResult { match unsafe { ffi::PySequence_Contains(any.as_ptr(), value.as_ptr()) } { @@ -1623,7 +1562,6 @@ impl<'py> Bound<'py, PyAny> { pub(crate) fn lookup_special(&self, attr_name: N) -> PyResult>> where N: IntoPyObject<'py, Target = PyString>, - N::Error: Into, { let py = self.py(); let self_type = self.get_type(); diff --git a/src/types/mapping.rs b/src/types/mapping.rs index 609bd80295a..009c5c0e5e2 100644 --- a/src/types/mapping.rs +++ b/src/types/mapping.rs @@ -7,7 +7,7 @@ use crate::sync::GILOnceCell; use crate::type_object::PyTypeInfo; use crate::types::any::PyAnyMethods; use crate::types::{PyAny, PyDict, PySequence, PyType}; -use crate::{ffi, Py, PyErr, PyTypeCheck, Python}; +use crate::{ffi, Py, PyTypeCheck, Python}; /// Represents a reference to a Python object supporting the mapping protocol. /// @@ -51,8 +51,7 @@ pub trait PyMappingMethods<'py>: crate::sealed::Sealed { /// This is equivalent to the Python expression `key in self`. fn contains(&self, key: K) -> PyResult where - K: IntoPyObject<'py>, - K::Error: Into; + K: IntoPyObject<'py>; /// Gets the item in self with key `key`. /// @@ -61,8 +60,7 @@ pub trait PyMappingMethods<'py>: crate::sealed::Sealed { /// This is equivalent to the Python expression `self[key]`. fn get_item(&self, key: K) -> PyResult> where - K: IntoPyObject<'py>, - K::Error: Into; + K: IntoPyObject<'py>; /// Sets the item in self with key `key`. /// @@ -70,17 +68,14 @@ pub trait PyMappingMethods<'py>: crate::sealed::Sealed { fn set_item(&self, key: K, value: V) -> PyResult<()> where K: IntoPyObject<'py>, - V: IntoPyObject<'py>, - K::Error: Into, - V::Error: Into; + V: IntoPyObject<'py>; /// Deletes the item with key `key`. /// /// This is equivalent to the Python statement `del self[key]`. fn del_item(&self, key: K) -> PyResult<()> where - K: IntoPyObject<'py>, - K::Error: Into; + K: IntoPyObject<'py>; /// Returns a sequence containing all keys in the mapping. fn keys(&self) -> PyResult>; @@ -108,7 +103,6 @@ impl<'py> PyMappingMethods<'py> for Bound<'py, PyMapping> { fn contains(&self, key: K) -> PyResult where K: IntoPyObject<'py>, - K::Error: Into, { PyAnyMethods::contains(&**self, key) } @@ -117,7 +111,6 @@ impl<'py> PyMappingMethods<'py> for Bound<'py, PyMapping> { fn get_item(&self, key: K) -> PyResult> where K: IntoPyObject<'py>, - K::Error: Into, { PyAnyMethods::get_item(&**self, key) } @@ -127,8 +120,6 @@ impl<'py> PyMappingMethods<'py> for Bound<'py, PyMapping> { where K: IntoPyObject<'py>, V: IntoPyObject<'py>, - K::Error: Into, - V::Error: Into, { PyAnyMethods::set_item(&**self, key, value) } @@ -137,7 +128,6 @@ impl<'py> PyMappingMethods<'py> for Bound<'py, PyMapping> { fn del_item(&self, key: K) -> PyResult<()> where K: IntoPyObject<'py>, - K::Error: Into, { PyAnyMethods::del_item(&**self, key) } diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 832cf85d2fc..d54bdf79f8d 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -532,14 +532,13 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+ impl <'py, $($T),+> IntoPyObject<'py> for ($($T,)+) where $($T: IntoPyObject<'py>,)+ - PyErr: $(From<$T::Error> + )+ { type Target = PyTuple; type Output = Bound<'py, Self::Target>; type Error = PyErr; fn into_pyobject(self, py: Python<'py>) -> Result { - Ok(array_into_tuple(py, [$(self.$n.into_pyobject(py)?.into_any().unbind()),+]).into_bound(py)) + Ok(array_into_tuple(py, [$(self.$n.into_pyobject(py).map_err(Into::into)?.into_any().unbind()),+]).into_bound(py)) } }