implement `PyErr::write_unraisable_bound`
This commit is contained in:
parent
7d245842d4
commit
877e34ac86
|
@ -42,6 +42,7 @@
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
use crate::exceptions::{PyTypeError, PyUserWarning, PyValueError};
|
use crate::exceptions::{PyTypeError, PyUserWarning, PyValueError};
|
||||||
|
use crate::instance::Bound;
|
||||||
#[cfg(Py_LIMITED_API)]
|
#[cfg(Py_LIMITED_API)]
|
||||||
use crate::sync::GILOnceCell;
|
use crate::sync::GILOnceCell;
|
||||||
#[cfg(not(Py_LIMITED_API))]
|
#[cfg(not(Py_LIMITED_API))]
|
||||||
|
@ -465,7 +466,7 @@ fn warn_truncated_leap_second(obj: &PyAny) {
|
||||||
"ignored leap-second, `datetime` does not support leap-seconds",
|
"ignored leap-second, `datetime` does not support leap-seconds",
|
||||||
0,
|
0,
|
||||||
) {
|
) {
|
||||||
e.write_unraisable(py, Some(obj))
|
e.write_unraisable_bound(py, Some(Bound::borrowed_from_gil_ref(&obj)))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -535,6 +535,16 @@ impl PyErr {
|
||||||
.restore(py)
|
.restore(py)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deprecated form of `PyErr::write_unraisable_bound`.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.21.0",
|
||||||
|
note = "`PyErr::write_unraisable` will be replaced by `PyErr::write_unraisable_bound` in a future PyO3 version"
|
||||||
|
)]
|
||||||
|
#[inline]
|
||||||
|
pub fn write_unraisable(self, py: Python<'_>, obj: Option<&PyAny>) {
|
||||||
|
self.write_unraisable_bound(py, obj.as_ref().map(Bound::borrowed_from_gil_ref))
|
||||||
|
}
|
||||||
|
|
||||||
/// Reports the error as unraisable.
|
/// Reports the error as unraisable.
|
||||||
///
|
///
|
||||||
/// This calls `sys.unraisablehook()` using the current exception and obj argument.
|
/// This calls `sys.unraisablehook()` using the current exception and obj argument.
|
||||||
|
@ -557,16 +567,16 @@ impl PyErr {
|
||||||
/// # fn main() -> PyResult<()> {
|
/// # fn main() -> PyResult<()> {
|
||||||
/// Python::with_gil(|py| {
|
/// Python::with_gil(|py| {
|
||||||
/// match failing_function() {
|
/// match failing_function() {
|
||||||
/// Err(pyerr) => pyerr.write_unraisable(py, None),
|
/// Err(pyerr) => pyerr.write_unraisable_bound(py, None),
|
||||||
/// Ok(..) => { /* do something here */ }
|
/// Ok(..) => { /* do something here */ }
|
||||||
/// }
|
/// }
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// })
|
/// })
|
||||||
/// # }
|
/// # }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn write_unraisable(self, py: Python<'_>, obj: Option<&PyAny>) {
|
pub fn write_unraisable_bound(self, py: Python<'_>, obj: Option<&Bound<'_, PyAny>>) {
|
||||||
self.restore(py);
|
self.restore(py);
|
||||||
unsafe { ffi::PyErr_WriteUnraisable(obj.map_or(std::ptr::null_mut(), |x| x.as_ptr())) }
|
unsafe { ffi::PyErr_WriteUnraisable(obj.map_or(std::ptr::null_mut(), Bound::as_ptr)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Issues a warning message.
|
/// Issues a warning message.
|
||||||
|
|
|
@ -1067,7 +1067,7 @@ impl ThreadCheckerImpl {
|
||||||
"{} is unsendable, but is being dropped on another thread",
|
"{} is unsendable, but is being dropped on another thread",
|
||||||
type_name
|
type_name
|
||||||
))
|
))
|
||||||
.write_unraisable(py, None);
|
.write_unraisable_bound(py, None);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
callback::PyCallbackOutput, ffi, impl_::panic::PanicTrap, methods::IPowModulo,
|
callback::PyCallbackOutput, ffi, ffi_ptr_ext::FfiPtrExt, impl_::panic::PanicTrap,
|
||||||
panic::PanicException, types::PyModule, GILPool, Py, PyResult, Python,
|
methods::IPowModulo, panic::PanicException, types::PyModule, GILPool, Py, PyResult, Python,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -224,7 +224,7 @@ where
|
||||||
if let Err(py_err) = panic::catch_unwind(move || body(py))
|
if let Err(py_err) = panic::catch_unwind(move || body(py))
|
||||||
.unwrap_or_else(|payload| Err(PanicException::from_panic_payload(payload)))
|
.unwrap_or_else(|payload| Err(PanicException::from_panic_payload(payload)))
|
||||||
{
|
{
|
||||||
py_err.write_unraisable(py, py.from_borrowed_ptr_or_opt(ctx));
|
py_err.write_unraisable_bound(py, ctx.assume_borrowed_or_opt(py).as_deref());
|
||||||
}
|
}
|
||||||
trap.disarm();
|
trap.disarm();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::pycell::{PyBorrowError, PyBorrowMutError, PyCell};
|
||||||
use crate::pyclass::boolean_struct::{False, True};
|
use crate::pyclass::boolean_struct::{False, True};
|
||||||
use crate::type_object::HasPyGilRef;
|
use crate::type_object::HasPyGilRef;
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
|
use crate::types::string::PyStringMethods;
|
||||||
use crate::types::{PyDict, PyString, PyTuple};
|
use crate::types::{PyDict, PyString, PyTuple};
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyClass, PyClassInitializer, PyRef, PyRefMut,
|
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyClass, PyClassInitializer, PyRef, PyRefMut,
|
||||||
|
@ -97,10 +98,8 @@ fn python_format(
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
f: &mut std::fmt::Formatter<'_>,
|
||||||
) -> Result<(), std::fmt::Error> {
|
) -> Result<(), std::fmt::Error> {
|
||||||
match format_result {
|
match format_result {
|
||||||
Result::Ok(s) => return f.write_str(&s.as_gil_ref().to_string_lossy()),
|
Result::Ok(s) => return f.write_str(&s.to_string_lossy()),
|
||||||
Result::Err(err) => {
|
Result::Err(err) => err.write_unraisable_bound(any.py(), Some(any)),
|
||||||
err.write_unraisable(any.py(), std::option::Option::Some(any.as_gil_ref()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match any.get_type().name() {
|
match any.get_type().name() {
|
||||||
|
|
|
@ -257,7 +257,10 @@ impl PyTypeCheck for PyMapping {
|
||||||
|| get_mapping_abc(object.py())
|
|| get_mapping_abc(object.py())
|
||||||
.and_then(|abc| object.is_instance(abc))
|
.and_then(|abc| object.is_instance(abc))
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
err.write_unraisable(object.py(), Some(object));
|
err.write_unraisable_bound(
|
||||||
|
object.py(),
|
||||||
|
Some(Bound::borrowed_from_gil_ref(&object)),
|
||||||
|
);
|
||||||
false
|
false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ macro_rules! pyobject_native_type_base(
|
||||||
{
|
{
|
||||||
match self.str() {
|
match self.str() {
|
||||||
::std::result::Result::Ok(s) => return f.write_str(&s.to_string_lossy()),
|
::std::result::Result::Ok(s) => return f.write_str(&s.to_string_lossy()),
|
||||||
::std::result::Result::Err(err) => err.write_unraisable(self.py(), ::std::option::Option::Some(self)),
|
::std::result::Result::Err(err) => err.write_unraisable_bound(self.py(), ::std::option::Option::Some($crate::Bound::borrowed_from_gil_ref(&self))),
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.get_type().name() {
|
match self.get_type().name() {
|
||||||
|
|
|
@ -541,7 +541,10 @@ impl PyTypeCheck for PySequence {
|
||||||
|| get_sequence_abc(object.py())
|
|| get_sequence_abc(object.py())
|
||||||
.and_then(|abc| object.is_instance(abc))
|
.and_then(|abc| object.is_instance(abc))
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
err.write_unraisable(object.py(), Some(object));
|
err.write_unraisable_bound(
|
||||||
|
object.py(),
|
||||||
|
Some(Bound::borrowed_from_gil_ref(&object)),
|
||||||
|
);
|
||||||
false
|
false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ fn test_exception_nosegfault() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(Py_3_8)]
|
#[cfg(Py_3_8)]
|
||||||
|
#[allow(deprecated)]
|
||||||
fn test_write_unraisable() {
|
fn test_write_unraisable() {
|
||||||
use common::UnraisableCapture;
|
use common::UnraisableCapture;
|
||||||
use pyo3::{exceptions::PyRuntimeError, ffi};
|
use pyo3::{exceptions::PyRuntimeError, ffi};
|
||||||
|
|
Loading…
Reference in New Issue