feature gate deprecated APIs for `PyErr` and exceptions (#4136)
This commit is contained in:
parent
d5452bcd8d
commit
22c5cff039
108
src/err/mod.rs
108
src/err/mod.rs
|
@ -24,9 +24,9 @@ use err_state::{PyErrState, PyErrStateLazyFnOutput, PyErrStateNormalized};
|
|||
/// compatibility with `?` and other Rust errors) this type supports creating exceptions instances
|
||||
/// in a lazy fashion, where the full Python object for the exception is created only when needed.
|
||||
///
|
||||
/// Accessing the contained exception in any way, such as with [`value`](PyErr::value),
|
||||
/// [`get_type`](PyErr::get_type), or [`is_instance`](PyErr::is_instance) will create the full
|
||||
/// exception object if it was not already created.
|
||||
/// Accessing the contained exception in any way, such as with [`value_bound`](PyErr::value_bound),
|
||||
/// [`get_type_bound`](PyErr::get_type_bound), or [`is_instance_bound`](PyErr::is_instance_bound)
|
||||
/// will create the full exception object if it was not already created.
|
||||
pub struct PyErr {
|
||||
// Safety: can only hand out references when in the "normalized" state. Will never change
|
||||
// after normalization.
|
||||
|
@ -136,7 +136,7 @@ impl PyErr {
|
|||
///
|
||||
/// This exception instance will be initialized lazily. This avoids the need for the Python GIL
|
||||
/// to be held, but requires `args` to be `Send` and `Sync`. If `args` is not `Send` or `Sync`,
|
||||
/// consider using [`PyErr::from_value`] instead.
|
||||
/// consider using [`PyErr::from_value_bound`] instead.
|
||||
///
|
||||
/// If `T` does not inherit from `BaseException`, then a `TypeError` will be returned.
|
||||
///
|
||||
|
@ -192,12 +192,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of [`PyErr::from_type_bound`]
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::from_type` will be replaced by `PyErr::from_type_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::from_type` will be replaced by `PyErr::from_type_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn from_type<A>(ty: &PyType, args: A) -> PyErr
|
||||
where
|
||||
|
@ -224,12 +222,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of [`PyErr::from_value_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::from_value` will be replaced by `PyErr::from_value_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::from_value` will be replaced by `PyErr::from_value_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn from_value(obj: &PyAny) -> PyErr {
|
||||
PyErr::from_value_bound(obj.as_borrowed().to_owned())
|
||||
|
@ -284,12 +280,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of [`PyErr::get_type_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::get_type` will be replaced by `PyErr::get_type_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::get_type` will be replaced by `PyErr::get_type_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn get_type<'py>(&'py self, py: Python<'py>) -> &'py PyType {
|
||||
self.get_type_bound(py).into_gil_ref()
|
||||
|
@ -311,12 +305,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of [`PyErr::value_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::value` will be replaced by `PyErr::value_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::value` will be replaced by `PyErr::value_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn value<'py>(&'py self, py: Python<'py>) -> &'py PyBaseException {
|
||||
self.value_bound(py).as_gil_ref()
|
||||
|
@ -355,12 +347,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of [`PyErr::traceback_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::traceback` will be replaced by `PyErr::traceback_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::traceback` will be replaced by `PyErr::traceback_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn traceback<'py>(&'py self, py: Python<'py>) -> Option<&'py PyTraceback> {
|
||||
self.normalized(py).ptraceback(py).map(|b| b.into_gil_ref())
|
||||
|
@ -508,12 +498,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of [`PyErr::new_type_bound`]
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::new_type` will be replaced by `PyErr::new_type_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::new_type` will be replaced by `PyErr::new_type_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn new_type(
|
||||
py: Python<'_>,
|
||||
|
@ -636,12 +624,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of `PyErr::is_instance_bound`.
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::is_instance` will be replaced by `PyErr::is_instance_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::is_instance` will be replaced by `PyErr::is_instance_bound` in a future PyO3 version"
|
||||
)]
|
||||
#[inline]
|
||||
pub fn is_instance(&self, py: Python<'_>, ty: &PyAny) -> bool {
|
||||
|
@ -675,12 +661,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of `PyErr::write_unraisable_bound`.
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::write_unraisable` will be replaced by `PyErr::write_unraisable_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[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>) {
|
||||
|
@ -722,12 +706,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of [`PyErr::warn_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::warn` will be replaced by `PyErr::warn_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::warn` will be replaced by `PyErr::warn_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn warn(py: Python<'_>, category: &PyAny, message: &str, stacklevel: i32) -> PyResult<()> {
|
||||
Self::warn_bound(py, &category.as_borrowed(), message, stacklevel)
|
||||
|
@ -771,12 +753,10 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Deprecated form of [`PyErr::warn_explicit_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::warn_explicit` will be replaced by `PyErr::warn_explicit_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyErr::warn_explicit` will be replaced by `PyErr::warn_explicit_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn warn_explicit(
|
||||
py: Python<'_>,
|
||||
|
|
|
@ -21,6 +21,7 @@ macro_rules! impl_exception_boilerplate {
|
|||
($name: ident) => {
|
||||
// FIXME https://github.com/PyO3/pyo3/issues/3903
|
||||
#[allow(unknown_lints, non_local_definitions)]
|
||||
#[cfg(feature = "gil-refs")]
|
||||
impl ::std::convert::From<&$name> for $crate::PyErr {
|
||||
#[inline]
|
||||
fn from(err: &$name) -> $crate::PyErr {
|
||||
|
@ -650,12 +651,10 @@ impl_windows_native_exception!(
|
|||
|
||||
impl PyUnicodeDecodeError {
|
||||
/// Deprecated form of [`PyUnicodeDecodeError::new_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyUnicodeDecodeError::new` will be replaced by `PyUnicodeDecodeError::new_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyUnicodeDecodeError::new` will be replaced by `PyUnicodeDecodeError::new_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn new<'p>(
|
||||
py: Python<'p>,
|
||||
|
@ -692,12 +691,10 @@ impl PyUnicodeDecodeError {
|
|||
}
|
||||
|
||||
/// Deprecated form of [`PyUnicodeDecodeError::new_utf8_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyUnicodeDecodeError::new_utf8` will be replaced by `PyUnicodeDecodeError::new_utf8_bound` in a future PyO3 version"
|
||||
)
|
||||
#[cfg(feature = "gil-refs")]
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyUnicodeDecodeError::new_utf8` will be replaced by `PyUnicodeDecodeError::new_utf8_bound` in a future PyO3 version"
|
||||
)]
|
||||
pub fn new_utf8<'p>(
|
||||
py: Python<'p>,
|
||||
|
@ -808,7 +805,7 @@ macro_rules! test_exception {
|
|||
use super::$exc_ty;
|
||||
|
||||
$crate::Python::with_gil(|py| {
|
||||
use std::error::Error;
|
||||
use $crate::types::PyAnyMethods;
|
||||
let err: $crate::PyErr = {
|
||||
None
|
||||
$(
|
||||
|
@ -819,13 +816,19 @@ macro_rules! test_exception {
|
|||
|
||||
assert!(err.is_instance_of::<$exc_ty>(py));
|
||||
|
||||
let value: &$exc_ty = err.value_bound(py).clone().into_gil_ref().downcast().unwrap();
|
||||
assert!(value.source().is_none());
|
||||
let value = err.value_bound(py).as_any().downcast::<$exc_ty>().unwrap();
|
||||
|
||||
err.set_cause(py, Some($crate::exceptions::PyValueError::new_err("a cause")));
|
||||
assert!(value.source().is_some());
|
||||
#[cfg(feature = "gil-refs")]
|
||||
{
|
||||
use std::error::Error;
|
||||
let value = value.as_gil_ref();
|
||||
assert!(value.source().is_none());
|
||||
|
||||
assert!($crate::PyErr::from(value).is_instance_of::<$exc_ty>(py));
|
||||
err.set_cause(py, Some($crate::exceptions::PyValueError::new_err("a cause")));
|
||||
assert!(value.source().is_some());
|
||||
}
|
||||
|
||||
assert!($crate::PyErr::from(value.clone()).is_instance_of::<$exc_ty>(py));
|
||||
})
|
||||
}
|
||||
};
|
||||
|
@ -1068,6 +1071,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "gil-refs")]
|
||||
fn native_exception_chain() {
|
||||
use std::error::Error;
|
||||
|
||||
|
|
|
@ -100,10 +100,9 @@ fn test_exception_nosegfault() {
|
|||
|
||||
#[test]
|
||||
#[cfg(Py_3_8)]
|
||||
#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))]
|
||||
fn test_write_unraisable() {
|
||||
use common::UnraisableCapture;
|
||||
use pyo3::{exceptions::PyRuntimeError, ffi};
|
||||
use pyo3::{exceptions::PyRuntimeError, ffi, types::PyNotImplemented};
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let capture = UnraisableCapture::install(py);
|
||||
|
@ -111,14 +110,14 @@ fn test_write_unraisable() {
|
|||
assert!(capture.borrow(py).capture.is_none());
|
||||
|
||||
let err = PyRuntimeError::new_err("foo");
|
||||
err.write_unraisable(py, None);
|
||||
err.write_unraisable_bound(py, None);
|
||||
|
||||
let (err, object) = capture.borrow_mut(py).capture.take().unwrap();
|
||||
assert_eq!(err.to_string(), "RuntimeError: foo");
|
||||
assert!(object.is_none(py));
|
||||
|
||||
let err = PyRuntimeError::new_err("bar");
|
||||
err.write_unraisable(py, Some(py.NotImplemented().as_ref(py)));
|
||||
err.write_unraisable_bound(py, Some(&PyNotImplemented::get_bound(py)));
|
||||
|
||||
let (err, object) = capture.borrow_mut(py).capture.take().unwrap();
|
||||
assert_eq!(err.to_string(), "RuntimeError: bar");
|
||||
|
|
Loading…
Reference in New Issue