Skip to content

Commit

Permalink
Add a trait bound to From<Bound<'py, T>> for PyErr
Browse files Browse the repository at this point in the history
  • Loading branch information
LilyFoote committed Feb 23, 2024
1 parent 41c79ad commit 2a0bfad
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/coroutine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl Coroutine {
(Some(exc), Some(cb)) => cb.throw(exc),
(Some(exc), None) => {
self.close();
return Err(exc.into_bound(py).into());
return Err(PyErr::from_value_bound(exc.into_bound(py)));
}
(None, _) => {}
}
Expand Down
13 changes: 12 additions & 1 deletion src/err/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,18 @@ impl PyErrArguments for PyDowncastErrorArguments {
}
}

impl<'py, T> std::convert::From<Bound<'py, T>> for PyErr {
/// Python exceptions that can be converted to [`PyErr`].
///
/// This is used to implement [`From<Bound<'_, T>> for PyErr`].
///
/// Users should not need to implement this trait directly. It is implemented automatically in the
/// [`import_exception!`] and [`create_exception!`] macros.
pub trait ToPyErr {}

impl<'py, T> std::convert::From<Bound<'py, T>> for PyErr
where
T: ToPyErr,
{
#[inline]
fn from(err: Bound<'py, T>) -> PyErr {
PyErr::from_value_bound(err.into_any())
Expand Down
2 changes: 2 additions & 0 deletions src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ macro_rules! impl_exception_boilerplate {
}
}
}

impl $crate::ToPyErr for $name {}
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ pub use crate::conversion::{AsPyPointer, FromPyObject, FromPyPointer, IntoPy, To
#[allow(deprecated)]
pub use crate::conversion::{PyTryFrom, PyTryInto};
pub use crate::err::{
DowncastError, DowncastIntoError, PyDowncastError, PyErr, PyErrArguments, PyResult,
DowncastError, DowncastIntoError, PyDowncastError, PyErr, PyErrArguments, PyResult, ToPyErr,
};
pub use crate::gil::GILPool;
#[cfg(not(PyPy))]
Expand Down
4 changes: 2 additions & 2 deletions src/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ mod inner {
#[pymethods(crate = "pyo3")]
impl UnraisableCapture {
pub fn hook(&mut self, unraisable: Bound<'_, PyAny>) {
let err = unraisable.getattr("exc_value").unwrap();
let err = PyErr::from_value_bound(unraisable.getattr("exc_value").unwrap());
let instance = unraisable.getattr("object").unwrap();
self.capture = Some((err.into(), instance.into()));
self.capture = Some((err, instance.into()));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/types/traceback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ except Exception as e:
Some(&locals),
)
.unwrap();
let err: PyErr = locals.get_item("err").unwrap().unwrap().into();
let err = PyErr::from_value_bound(locals.get_item("err").unwrap().unwrap());
let traceback = err.value_bound(py).getattr("__traceback__").unwrap();
assert!(err.traceback_bound(py).unwrap().is(&traceback));
})
Expand Down

0 comments on commit 2a0bfad

Please sign in to comment.