Add `Py2` variants of `PyDowncastError`
This commit is contained in:
parent
e727640ef3
commit
1451418ee4
101
src/err/mod.rs
101
src/err/mod.rs
|
@ -1,5 +1,7 @@
|
|||
use crate::instance::Py2;
|
||||
use crate::panic::PanicException;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::any::PyAnyMethods;
|
||||
use crate::types::{PyTraceback, PyType};
|
||||
use crate::{
|
||||
exceptions::{self, PyBaseException},
|
||||
|
@ -61,6 +63,42 @@ impl<'a> PyDowncastError<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Error that indicates a failure to convert a PyAny to a more specific Python type.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PyDowncastError2<'a, 'py> {
|
||||
from: &'a Py2<'py, PyAny>,
|
||||
to: Cow<'static, str>,
|
||||
}
|
||||
|
||||
impl<'a, 'py> PyDowncastError2<'a, 'py> {
|
||||
/// Create a new `PyDowncastError` representing a failure to convert the object
|
||||
/// `from` into the type named in `to`.
|
||||
pub fn new(from: &'a Py2<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
|
||||
PyDowncastError2 {
|
||||
from,
|
||||
to: to.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Error that indicates a failure to convert a PyAny to a more specific Python type.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PyDowncastIntoError<'py> {
|
||||
from: Py2<'py, PyAny>,
|
||||
to: Cow<'static, str>,
|
||||
}
|
||||
|
||||
impl<'py> PyDowncastIntoError<'py> {
|
||||
/// Create a new `PyDowncastIntoError` representing a failure to convert the object
|
||||
/// `from` into the type named in `to`.
|
||||
pub fn new(from: Py2<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
|
||||
PyDowncastIntoError {
|
||||
from,
|
||||
to: to.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PyErr {
|
||||
/// Creates a new PyErr of type `T`.
|
||||
///
|
||||
|
@ -773,18 +811,63 @@ impl<'a> std::error::Error for PyDowncastError<'a> {}
|
|||
|
||||
impl<'a> std::fmt::Display for PyDowncastError<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
write!(
|
||||
f,
|
||||
"'{}' object cannot be converted to '{}'",
|
||||
self.from
|
||||
.get_type()
|
||||
.qualname()
|
||||
.map_err(|_| std::fmt::Error)?,
|
||||
self.to
|
||||
)
|
||||
display_downcast_error(f, Py2::borrowed_from_gil_ref(&self.from), &self.to)
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert `PyDowncastError2` to Python `TypeError`.
|
||||
impl std::convert::From<PyDowncastError2<'_, '_>> for PyErr {
|
||||
fn from(err: PyDowncastError2<'_, '_>) -> PyErr {
|
||||
let args = PyDowncastErrorArguments {
|
||||
from: err.from.get_type().into(),
|
||||
to: err.to,
|
||||
};
|
||||
|
||||
exceptions::PyTypeError::new_err(args)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for PyDowncastError2<'_, '_> {}
|
||||
|
||||
impl std::fmt::Display for PyDowncastError2<'_, '_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
display_downcast_error(f, self.from, &self.to)
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert `PyDowncastIntoError` to Python `TypeError`.
|
||||
impl std::convert::From<PyDowncastIntoError<'_>> for PyErr {
|
||||
fn from(err: PyDowncastIntoError<'_>) -> PyErr {
|
||||
let args = PyDowncastErrorArguments {
|
||||
from: err.from.get_type().into(),
|
||||
to: err.to,
|
||||
};
|
||||
|
||||
exceptions::PyTypeError::new_err(args)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for PyDowncastIntoError<'_> {}
|
||||
|
||||
impl std::fmt::Display for PyDowncastIntoError<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
display_downcast_error(f, &self.from, &self.to)
|
||||
}
|
||||
}
|
||||
|
||||
fn display_downcast_error(
|
||||
f: &mut std::fmt::Formatter<'_>,
|
||||
from: &Py2<'_, PyAny>,
|
||||
to: &str,
|
||||
) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"'{}' object cannot be converted to '{}'",
|
||||
from.get_type().qualname().map_err(|_| std::fmt::Error)?,
|
||||
to
|
||||
)
|
||||
}
|
||||
|
||||
pub fn panic_after_error(_py: Python<'_>) -> ! {
|
||||
unsafe {
|
||||
ffi::PyErr_Print();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::class::basic::CompareOp;
|
||||
use crate::conversion::{AsPyPointer, FromPyObject, IntoPy, ToPyObject};
|
||||
use crate::err::{PyDowncastError, PyErr, PyResult};
|
||||
use crate::err::{PyDowncastError, PyDowncastError2, PyDowncastIntoError, PyErr, PyResult};
|
||||
use crate::exceptions::{PyAttributeError, PyTypeError};
|
||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||
use crate::instance::Py2;
|
||||
|
@ -1563,12 +1563,12 @@ pub(crate) trait PyAnyMethods<'py> {
|
|||
/// })
|
||||
/// # }
|
||||
/// ```
|
||||
fn downcast<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError<'py>>
|
||||
fn downcast<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError2<'_, 'py>>
|
||||
where
|
||||
T: PyTypeCheck;
|
||||
|
||||
/// Like `downcast` but takes ownership of `self`.
|
||||
fn downcast_into<T>(self) -> Result<Py2<'py, T>, PyDowncastError<'py>>
|
||||
fn downcast_into<T>(self) -> Result<Py2<'py, T>, PyDowncastIntoError<'py>>
|
||||
where
|
||||
T: PyTypeCheck;
|
||||
|
||||
|
@ -1602,12 +1602,12 @@ pub(crate) trait PyAnyMethods<'py> {
|
|||
/// assert!(any.downcast_exact::<PyBool>().is_ok());
|
||||
/// });
|
||||
/// ```
|
||||
fn downcast_exact<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError<'py>>
|
||||
fn downcast_exact<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError2<'_, 'py>>
|
||||
where
|
||||
T: PyTypeInfo;
|
||||
|
||||
/// Like `downcast_exact` but takes ownership of `self`.
|
||||
fn downcast_into_exact<T>(self) -> Result<Py2<'py, T>, PyDowncastError<'py>>
|
||||
fn downcast_into_exact<T>(self) -> Result<Py2<'py, T>, PyDowncastIntoError<'py>>
|
||||
where
|
||||
T: PyTypeInfo;
|
||||
|
||||
|
@ -2036,7 +2036,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn downcast<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError<'py>>
|
||||
fn downcast<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError2<'_, 'py>>
|
||||
where
|
||||
T: PyTypeCheck,
|
||||
{
|
||||
|
@ -2044,12 +2044,12 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
|
|||
// Safety: type_check is responsible for ensuring that the type is correct
|
||||
Ok(unsafe { self.downcast_unchecked() })
|
||||
} else {
|
||||
Err(PyDowncastError::new(self.clone().into_gil_ref(), T::NAME))
|
||||
Err(PyDowncastError2::new(self, T::NAME))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn downcast_into<T>(self) -> Result<Py2<'py, T>, PyDowncastError<'py>>
|
||||
fn downcast_into<T>(self) -> Result<Py2<'py, T>, PyDowncastIntoError<'py>>
|
||||
where
|
||||
T: PyTypeCheck,
|
||||
{
|
||||
|
@ -2057,12 +2057,12 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
|
|||
// Safety: type_check is responsible for ensuring that the type is correct
|
||||
Ok(unsafe { self.downcast_into_unchecked() })
|
||||
} else {
|
||||
Err(PyDowncastError::new(self.clone().into_gil_ref(), T::NAME))
|
||||
Err(PyDowncastIntoError::new(self, T::NAME))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn downcast_exact<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError<'py>>
|
||||
fn downcast_exact<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError2<'_, 'py>>
|
||||
where
|
||||
T: PyTypeInfo,
|
||||
{
|
||||
|
@ -2070,12 +2070,12 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
|
|||
// Safety: is_exact_instance_of is responsible for ensuring that the type is correct
|
||||
Ok(unsafe { self.downcast_unchecked() })
|
||||
} else {
|
||||
Err(PyDowncastError::new(self.clone().into_gil_ref(), T::NAME))
|
||||
Err(PyDowncastError2::new(self, T::NAME))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn downcast_into_exact<T>(self) -> Result<Py2<'py, T>, PyDowncastError<'py>>
|
||||
fn downcast_into_exact<T>(self) -> Result<Py2<'py, T>, PyDowncastIntoError<'py>>
|
||||
where
|
||||
T: PyTypeInfo,
|
||||
{
|
||||
|
@ -2083,7 +2083,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
|
|||
// Safety: is_exact_instance_of is responsible for ensuring that the type is correct
|
||||
Ok(unsafe { self.downcast_into_unchecked() })
|
||||
} else {
|
||||
Err(PyDowncastError::new(self.into_gil_ref(), T::NAME))
|
||||
Err(PyDowncastIntoError::new(self, T::NAME))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ error[E0277]: the trait bound `PyErr: From<MyError>` is not satisfied
|
|||
<PyErr as From<PyBorrowMutError>>
|
||||
<PyErr as From<std::io::Error>>
|
||||
<PyErr as From<PyDowncastError<'a>>>
|
||||
<PyErr as From<pyo3::err::PyDowncastError2<'_, '_>>>
|
||||
<PyErr as From<pyo3::err::PyDowncastIntoError<'_>>>
|
||||
<PyErr as From<NulError>>
|
||||
<PyErr as From<IntoStringError>>
|
||||
<PyErr as From<FromUtf8Error>>
|
||||
<PyErr as From<FromUtf16Error>>
|
||||
and $N others
|
||||
= note: required for `MyError` to implement `Into<PyErr>`
|
||||
= note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
Loading…
Reference in New Issue