Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/5472.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecate `PyAnyMethods::downcast` functions in favour of `Bound::cast` functions
12 changes: 8 additions & 4 deletions src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2186,7 +2186,7 @@ impl Py<PyAny> {
/// })
/// # }
/// ```
// FIXME(icxolu) deprecate in favor of `Py::cast_bound`
#[deprecated(since = "0.27.0", note = "use `Py::cast_bound` instead")]
#[inline]
pub fn downcast_bound<'py, T>(
&self,
Expand All @@ -2195,18 +2195,22 @@ impl Py<PyAny> {
where
T: PyTypeCheck,
{
self.cast_bound(py)
#[allow(deprecated)]
self.bind(py).downcast()
}

/// Casts the `Py<PyAny>` to a concrete Python object type without checking validity.
///
/// # Safety
///
/// Callers must ensure that the type is valid or risk type confusion.
// FIXME(icxolu) deprecate in favor of `Py::cast_bound_unchecked`
#[deprecated(since = "0.27.0", note = "use `Py::cast_bound_unchecked` instead")]
#[inline]
pub unsafe fn downcast_bound_unchecked<'py, T>(&self, py: Python<'py>) -> &Bound<'py, T> {
unsafe { self.cast_bound_unchecked(py) }
#[allow(deprecated)]
unsafe {
self.bind(py).downcast_unchecked()
}
}
}

Expand Down
44 changes: 34 additions & 10 deletions src/types/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed {
/// })
/// # }
/// ```
// FIXME(icxolu) deprecate in favor of `Bound::cast`
#[deprecated(since = "0.27.0", note = "use `Bound::cast` instead")]
fn downcast<T>(&self) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
where
T: PyTypeCheck;
Expand Down Expand Up @@ -800,7 +800,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed {
/// assert!(obj.downcast_into::<PyDict>().is_ok());
/// })
/// ```
// FIXME(icxolu) deprecate in favor of `Bound::cast_into`
#[deprecated(since = "0.27.0", note = "use `Bound::cast_into` instead")]
fn downcast_into<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
where
T: PyTypeCheck;
Expand Down Expand Up @@ -836,13 +836,13 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed {
/// assert!(any.downcast_exact::<PyBool>().is_ok());
/// });
/// ```
// FIXME(icxolu) deprecate in favor of `Bound::cast_exact`
#[deprecated(since = "0.27.0", note = "use `Bound::cast_exact` instead")]
fn downcast_exact<T>(&self) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
where
T: PyTypeInfo;

/// Like `downcast_exact` but takes ownership of `self`.
// FIXME(icxolu) deprecate in favor of `Bound::cast_into_exact`
#[deprecated(since = "0.27.0", note = "use `Bound::cast_into_exact` instead")]
fn downcast_into_exact<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
where
T: PyTypeInfo;
Expand All @@ -852,15 +852,15 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed {
/// # Safety
///
/// Callers must ensure that the type is valid or risk type confusion.
// FIXME(icxolu) deprecate in favor of `Bound::cast_unchecked`
#[deprecated(since = "0.27.0", note = "use `Bound::cast_unchecked` instead")]
unsafe fn downcast_unchecked<T>(&self) -> &Bound<'py, T>;

/// Like `downcast_unchecked` but takes ownership of `self`.
///
/// # Safety
///
/// Callers must ensure that the type is valid or risk type confusion.
// FIXME(icxolu) deprecate in favor of `Bound::cast_into_unchecked`
#[deprecated(since = "0.27.0", note = "use `Bound::cast_into_unchecked` instead")]
unsafe fn downcast_into_unchecked<T>(self) -> Bound<'py, T>;

/// Extracts some type from the Python object.
Expand Down Expand Up @@ -1449,31 +1449,55 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
where
T: PyTypeCheck,
{
self.cast()
if T::type_check(self) {
// Safety: type_check is responsible for ensuring that the type is correct
Ok(unsafe { self.cast_unchecked() })
} else {
#[allow(deprecated)]
Err(DowncastError::new(self, T::NAME))
}
}

#[inline]
fn downcast_into<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
where
T: PyTypeCheck,
{
self.cast_into()
if T::type_check(&self) {
// Safety: type_check is responsible for ensuring that the type is correct
Ok(unsafe { self.cast_into_unchecked() })
} else {
#[allow(deprecated)]
Err(DowncastIntoError::new(self, T::NAME))
}
}

#[inline]
fn downcast_exact<T>(&self) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
where
T: PyTypeInfo,
{
self.cast_exact()
if T::is_exact_type_of(self) {
// Safety: is_exact_type_of is responsible for ensuring that the type is correct
Ok(unsafe { self.cast_unchecked() })
} else {
#[allow(deprecated)]
Err(DowncastError::new(self, T::NAME))
}
}

#[inline]
fn downcast_into_exact<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
where
T: PyTypeInfo,
{
self.cast_into_exact()
if T::is_exact_type_of(&self) {
// Safety: is_exact_type_of is responsible for ensuring that the type is correct
Ok(unsafe { self.cast_into_unchecked() })
} else {
#[allow(deprecated)]
Err(DowncastIntoError::new(self, T::NAME))
}
}

#[inline]
Expand Down
Loading