deprecate `PyTryFrom` and `PyTryInto`
This commit is contained in:
parent
3583b9ac67
commit
bc87b7bac6
|
@ -16,6 +16,7 @@ To migrate, switch all type casts to use `obj.downcast()` instead of `try_from(o
|
|||
Before:
|
||||
|
||||
```rust
|
||||
# #![allow(deprecated)]
|
||||
# use pyo3::prelude::*;
|
||||
# use pyo3::types::{PyInt, PyList};
|
||||
# fn main() -> PyResult<()> {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Deprecate `PyTryFrom` and `PyTryInto` traits in favor of `any.downcast()` via the `PyTypeCheck` and `PyTypeInfo` traits.
|
|
@ -355,11 +355,20 @@ where
|
|||
/// If `T` implements `PyTryFrom`, we can convert `&PyAny` to `&T`.
|
||||
///
|
||||
/// This trait is similar to `std::convert::TryFrom`
|
||||
#[deprecated(since = "0.21.0")]
|
||||
pub trait PyTryFrom<'v>: Sized + PyNativeType {
|
||||
/// Cast from a concrete Python object type to PyObject.
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "use `value.downcast::<T>()` instead of `T::try_from(value)`"
|
||||
)]
|
||||
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, PyDowncastError<'v>>;
|
||||
|
||||
/// Cast from a concrete Python object type to PyObject. With exact type check.
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "use `value.downcast_exact::<T>()` instead of `T::try_from_exact(value)`"
|
||||
)]
|
||||
fn try_from_exact<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, PyDowncastError<'v>>;
|
||||
|
||||
/// Cast a PyAny to a specific type of PyObject. The caller must
|
||||
|
@ -368,19 +377,33 @@ pub trait PyTryFrom<'v>: Sized + PyNativeType {
|
|||
/// # Safety
|
||||
///
|
||||
/// Callers must ensure that the type is valid or risk type confusion.
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "use `value.downcast_unchecked::<T>()` instead of `T::try_from_unchecked(value)`"
|
||||
)]
|
||||
unsafe fn try_from_unchecked<V: Into<&'v PyAny>>(value: V) -> &'v Self;
|
||||
}
|
||||
|
||||
/// Trait implemented by Python object types that allow a checked downcast.
|
||||
/// This trait is similar to `std::convert::TryInto`
|
||||
#[deprecated(since = "0.21.0")]
|
||||
pub trait PyTryInto<T>: Sized {
|
||||
/// Cast from PyObject to a concrete Python object type.
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "use `value.downcast()` instead of `value.try_into()`"
|
||||
)]
|
||||
fn try_into(&self) -> Result<&T, PyDowncastError<'_>>;
|
||||
|
||||
/// Cast from PyObject to a concrete Python object type. With exact type check.
|
||||
#[deprecated(
|
||||
since = "0.21.0",
|
||||
note = "use `value.downcast()` instead of `value.try_into_exact()`"
|
||||
)]
|
||||
fn try_into_exact(&self) -> Result<&T, PyDowncastError<'_>>;
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
mod implementations {
|
||||
use super::*;
|
||||
|
||||
|
@ -555,47 +578,50 @@ mod test_no_clone {}
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::PyObject;
|
||||
use crate::{PyObject, Python};
|
||||
|
||||
use super::super::PyTryFrom;
|
||||
use crate::types::{IntoPyDict, PyAny, PyDict, PyList};
|
||||
use crate::{Python, ToPyObject};
|
||||
#[allow(deprecated)]
|
||||
mod deprecated {
|
||||
use super::super::PyTryFrom;
|
||||
use crate::types::{IntoPyDict, PyAny, PyDict, PyList};
|
||||
use crate::{Python, ToPyObject};
|
||||
|
||||
#[test]
|
||||
fn test_try_from() {
|
||||
Python::with_gil(|py| {
|
||||
let list: &PyAny = vec![3, 6, 5, 4, 7].to_object(py).into_ref(py);
|
||||
let dict: &PyAny = vec![("reverse", true)].into_py_dict(py).as_ref();
|
||||
#[test]
|
||||
fn test_try_from() {
|
||||
Python::with_gil(|py| {
|
||||
let list: &PyAny = vec![3, 6, 5, 4, 7].to_object(py).into_ref(py);
|
||||
let dict: &PyAny = vec![("reverse", true)].into_py_dict(py).as_ref();
|
||||
|
||||
assert!(<PyList as PyTryFrom<'_>>::try_from(list).is_ok());
|
||||
assert!(<PyDict as PyTryFrom<'_>>::try_from(dict).is_ok());
|
||||
assert!(<PyList as PyTryFrom<'_>>::try_from(list).is_ok());
|
||||
assert!(<PyDict as PyTryFrom<'_>>::try_from(dict).is_ok());
|
||||
|
||||
assert!(<PyAny as PyTryFrom<'_>>::try_from(list).is_ok());
|
||||
assert!(<PyAny as PyTryFrom<'_>>::try_from(dict).is_ok());
|
||||
});
|
||||
}
|
||||
assert!(<PyAny as PyTryFrom<'_>>::try_from(list).is_ok());
|
||||
assert!(<PyAny as PyTryFrom<'_>>::try_from(dict).is_ok());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_from_exact() {
|
||||
Python::with_gil(|py| {
|
||||
let list: &PyAny = vec![3, 6, 5, 4, 7].to_object(py).into_ref(py);
|
||||
let dict: &PyAny = vec![("reverse", true)].into_py_dict(py).as_ref();
|
||||
#[test]
|
||||
fn test_try_from_exact() {
|
||||
Python::with_gil(|py| {
|
||||
let list: &PyAny = vec![3, 6, 5, 4, 7].to_object(py).into_ref(py);
|
||||
let dict: &PyAny = vec![("reverse", true)].into_py_dict(py).as_ref();
|
||||
|
||||
assert!(PyList::try_from_exact(list).is_ok());
|
||||
assert!(PyDict::try_from_exact(dict).is_ok());
|
||||
assert!(PyList::try_from_exact(list).is_ok());
|
||||
assert!(PyDict::try_from_exact(dict).is_ok());
|
||||
|
||||
assert!(PyAny::try_from_exact(list).is_err());
|
||||
assert!(PyAny::try_from_exact(dict).is_err());
|
||||
});
|
||||
}
|
||||
assert!(PyAny::try_from_exact(list).is_err());
|
||||
assert!(PyAny::try_from_exact(dict).is_err());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_from_unchecked() {
|
||||
Python::with_gil(|py| {
|
||||
let list = PyList::new(py, [1, 2, 3]);
|
||||
let val = unsafe { <PyList as PyTryFrom>::try_from_unchecked(list.as_ref()) };
|
||||
assert!(list.is(val));
|
||||
});
|
||||
#[test]
|
||||
fn test_try_from_unchecked() {
|
||||
Python::with_gil(|py| {
|
||||
let list = PyList::new(py, [1, 2, 3]);
|
||||
let val = unsafe { <PyList as PyTryFrom>::try_from_unchecked(list.as_ref()) };
|
||||
assert!(list.is(val));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1614,7 +1614,7 @@ a = A()
|
|||
|
||||
#[cfg(feature = "macros")]
|
||||
mod using_macros {
|
||||
use crate::{PyCell, PyTryInto};
|
||||
use crate::PyCell;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -1642,7 +1642,9 @@ a = A()
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn cell_tryfrom() {
|
||||
use crate::PyTryInto;
|
||||
// More detailed tests of the underlying semantics in pycell.rs
|
||||
Python::with_gil(|py| {
|
||||
let instance: &PyAny = Py::new(py, SomeClass(0)).unwrap().into_ref(py);
|
||||
|
|
|
@ -295,6 +295,7 @@
|
|||
//! [`Ungil`]: crate::marker::Ungil
|
||||
pub use crate::class::*;
|
||||
pub use crate::conversion::{AsPyPointer, FromPyObject, FromPyPointer, IntoPy, ToPyObject};
|
||||
#[allow(deprecated)]
|
||||
pub use crate::conversion::{PyTryFrom, PyTryInto};
|
||||
pub use crate::err::{PyDowncastError, PyErr, PyErrArguments, PyResult};
|
||||
pub use crate::gil::GILPool;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
//! ```
|
||||
|
||||
pub use crate::conversion::{FromPyObject, IntoPy, ToPyObject};
|
||||
#[allow(deprecated)]
|
||||
pub use crate::conversion::{PyTryFrom, PyTryInto};
|
||||
pub use crate::err::{PyErr, PyResult};
|
||||
pub use crate::instance::{Py, PyObject};
|
||||
|
|
|
@ -23,7 +23,6 @@ pub trait PySizedLayout<T>: PyLayout<T> + Sized {}
|
|||
///
|
||||
/// This is expected to be deprecated in the near future, see <https://github.com/PyO3/pyo3/issues/3382>
|
||||
///
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - `Py<Self>::as_ref` will hand out references to `Self::AsRefTarget`.
|
||||
|
|
|
@ -79,6 +79,7 @@ impl PyTypeCheck for PyIterator {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'v> crate::PyTryFrom<'v> for PyIterator {
|
||||
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v PyIterator, PyDowncastError<'v>> {
|
||||
let value = value.into();
|
||||
|
|
|
@ -135,6 +135,7 @@ impl PyTypeCheck for PyMapping {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'v> crate::PyTryFrom<'v> for PyMapping {
|
||||
/// Downcasting to `PyMapping` requires the concrete class to be a subclass (or registered
|
||||
/// subclass) of `collections.abc.Mapping` (from the Python standard library) - i.e.
|
||||
|
@ -168,7 +169,7 @@ mod tests {
|
|||
use crate::{
|
||||
exceptions::PyKeyError,
|
||||
types::{PyDict, PyTuple},
|
||||
PyTryFrom, Python,
|
||||
Python,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
@ -318,7 +319,9 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn test_mapping_try_from() {
|
||||
use crate::PyTryFrom;
|
||||
Python::with_gil(|py| {
|
||||
let dict = PyDict::new(py);
|
||||
let _ = <PyMapping as PyTryFrom>::try_from(dict).unwrap();
|
||||
|
|
|
@ -549,6 +549,7 @@ impl PyTypeCheck for PySequence {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'v> crate::PyTryFrom<'v> for PySequence {
|
||||
/// Downcasting to `PySequence` requires the concrete class to be a subclass (or registered
|
||||
/// subclass) of `collections.abc.Sequence` (from the Python standard library) - i.e.
|
||||
|
@ -577,7 +578,7 @@ impl<'v> crate::PyTryFrom<'v> for PySequence {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::types::{PyList, PySequence, PyTuple};
|
||||
use crate::{PyObject, PyTryFrom, Python, ToPyObject};
|
||||
use crate::{PyObject, Python, ToPyObject};
|
||||
|
||||
fn get_object() -> PyObject {
|
||||
// Convenience function for getting a single unique object
|
||||
|
@ -1078,7 +1079,9 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn test_seq_try_from() {
|
||||
use crate::PyTryFrom;
|
||||
Python::with_gil(|py| {
|
||||
let list = PyList::empty(py);
|
||||
let _ = <PySequence as PyTryFrom>::try_from(list).unwrap();
|
||||
|
|
Loading…
Reference in New Issue