|
1 | | -use crate::PyObject; |
2 | | -use crate::pystate::with_vm; |
| 1 | +use crate::object::define_py_check; |
| 2 | +use crate::{PyObject, pystate::with_vm}; |
3 | 3 | use core::convert::Infallible; |
4 | 4 | use core::ffi::{CStr, c_char, c_int}; |
5 | 5 | use core::ptr::NonNull; |
@@ -96,6 +96,8 @@ define_exception_statics! { |
96 | 96 | PyExc_EncodingWarning => encoding_warning, |
97 | 97 | } |
98 | 98 |
|
| 99 | +define_py_check!(fn PyExceptionInstance_Check, exceptions.base_exception_type); |
| 100 | + |
99 | 101 | #[unsafe(no_mangle)] |
100 | 102 | pub extern "C" fn PyErr_Occurred() -> *mut PyObject { |
101 | 103 | with_vm(|vm| { |
@@ -191,6 +193,15 @@ pub unsafe extern "C" fn PyErr_WriteUnraisable(obj: *mut PyObject) { |
191 | 193 | }) |
192 | 194 | } |
193 | 195 |
|
| 196 | +#[unsafe(no_mangle)] |
| 197 | +pub unsafe extern "C" fn PyExceptionClass_Check(obj: *mut PyObject) -> c_int { |
| 198 | + with_vm(|vm| unsafe { |
| 199 | + obj.as_ref() |
| 200 | + .and_then(|obj| obj.downcast_ref::<PyType>()) |
| 201 | + .is_some_and(|ty| ty.is_subtype(vm.ctx.exceptions.base_exception_type)) |
| 202 | + }) |
| 203 | +} |
| 204 | + |
194 | 205 | #[unsafe(no_mangle)] |
195 | 206 | pub unsafe extern "C" fn PyErr_NewException( |
196 | 207 | name: *const c_char, |
@@ -252,6 +263,42 @@ pub unsafe extern "C" fn PyErr_GivenExceptionMatches( |
252 | 263 | }) |
253 | 264 | } |
254 | 265 |
|
| 266 | +#[unsafe(no_mangle)] |
| 267 | +pub unsafe extern "C" fn PyException_GetTraceback(exc: *mut PyObject) -> *mut PyObject { |
| 268 | + with_vm(|vm| { |
| 269 | + let exc = unsafe { &*exc }.try_downcast_ref::<PyBaseException>(vm)?; |
| 270 | + let tb = exc |
| 271 | + .__traceback__() |
| 272 | + .map(|tb| tb.into_object().into_raw().as_ptr()) |
| 273 | + .unwrap_or_default(); |
| 274 | + Ok(tb) |
| 275 | + }) |
| 276 | +} |
| 277 | + |
| 278 | +#[unsafe(no_mangle)] |
| 279 | +pub unsafe extern "C" fn PyException_GetCause(exc: *mut PyObject) -> *mut PyObject { |
| 280 | + with_vm(|vm| { |
| 281 | + let exc = unsafe { &*exc }.try_downcast_ref::<PyBaseException>(vm)?; |
| 282 | + let cause = exc |
| 283 | + .__cause__() |
| 284 | + .map(|cause| cause.into_object().into_raw().as_ptr()) |
| 285 | + .unwrap_or_default(); |
| 286 | + Ok(cause) |
| 287 | + }) |
| 288 | +} |
| 289 | + |
| 290 | +#[unsafe(no_mangle)] |
| 291 | +pub unsafe extern "C" fn PyException_GetContext(exc: *mut PyObject) -> *mut PyObject { |
| 292 | + with_vm(|vm| { |
| 293 | + let exc = unsafe { &*exc }.try_downcast_ref::<PyBaseException>(vm)?; |
| 294 | + let context = exc |
| 295 | + .__context__() |
| 296 | + .map(|context| context.into_object().into_raw().as_ptr()) |
| 297 | + .unwrap_or_default(); |
| 298 | + Ok(context) |
| 299 | + }) |
| 300 | +} |
| 301 | + |
255 | 302 | #[cfg(test)] |
256 | 303 | mod tests { |
257 | 304 | use pyo3::exceptions::PyTypeError; |
|
0 commit comments