diff --git a/src/err/mod.rs b/src/err/mod.rs index 3af7b92b..0855a4b6 100644 --- a/src/err/mod.rs +++ b/src/err/mod.rs @@ -181,12 +181,10 @@ impl PyErr { /// }); /// ``` pub fn from_value(obj: &PyAny) -> PyErr { - let ptr = obj.as_ptr(); - - let state = if unsafe { ffi::PyExceptionInstance_Check(ptr) } != 0 { + let state = if let Ok(obj) = obj.downcast::() { PyErrState::Normalized(PyErrStateNormalized { ptype: obj.get_type().into(), - pvalue: unsafe { Py::from_borrowed_ptr(obj.py(), obj.as_ptr()) }, + pvalue: obj.into(), ptraceback: None, }) } else if unsafe { ffi::PyExceptionClass_Check(obj.as_ptr()) } != 0 { diff --git a/src/exceptions.rs b/src/exceptions.rs index a345274c..b1b5ba00 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -260,13 +260,13 @@ macro_rules! create_exception_type_object { } macro_rules! impl_native_exception ( - ($name:ident, $exc_name:ident, $doc:expr, $layout:path) => ( + ($name:ident, $exc_name:ident, $doc:expr, $layout:path $(, #checkfunction=$checkfunction:path)?) => ( #[doc = $doc] #[allow(clippy::upper_case_acronyms)] pub struct $name($crate::PyAny); $crate::impl_exception_boilerplate!($name); - $crate::pyobject_native_type!($name, $layout, |_py| unsafe { $crate::ffi::$exc_name as *mut $crate::ffi::PyTypeObject }); + $crate::pyobject_native_type!($name, $layout, |_py| unsafe { $crate::ffi::$exc_name as *mut $crate::ffi::PyTypeObject } $(, #checkfunction=$checkfunction)?); ); ($name:ident, $exc_name:ident, $doc:expr) => ( impl_native_exception!($name, $exc_name, $doc, $crate::ffi::PyBaseExceptionObject); @@ -359,7 +359,9 @@ Python::with_gil(|py| { impl_native_exception!( PyBaseException, PyExc_BaseException, - native_doc!("BaseException") + native_doc!("BaseException"), + ffi::PyBaseExceptionObject, + #checkfunction=ffi::PyExceptionInstance_Check ); impl_native_exception!(PyException, PyExc_Exception, native_doc!("Exception")); impl_native_exception!(