Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 8 additions & 2 deletions guide/src/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Before:
struct MyWrapper<T>(T);

impl<'py, T> FromPyObject<'py> for MyWrapper<T>
where
where
T: FromPyObject<'py>
{
fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult<Self> {
Expand All @@ -66,7 +66,7 @@ where
}
```

After:
After:
```rust
# use pyo3::prelude::*;
# #[allow(dead_code)]
Expand Down Expand Up @@ -133,6 +133,12 @@ This is very similar to `serde`s [`Deserialize`] and [`DeserializeOwned`] traits
[`DeserializeOwned`]: https://docs.rs/serde/latest/serde/de/trait.DeserializeOwned.html
</details>

## `PyTypeCheck` is now an `unsafe trait`

Because `PyTypeCheck` is the trait used to guard the `.cast()` functions to treat Python objects as specific concrete types, the trait is `unsafe` to implement.

This should always have been the case, it was an unfortunate omission from its original implementation which is being corrected in this release.

## from 0.25.* to 0.26
### Rename of `Python::with_gil`, `Python::allow_threads`, and `pyo3::prepare_freethreaded_python`
<details open>
Expand Down
1 change: 1 addition & 0 deletions newsfragments/5473.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make `PyTypeCheck` an `unsafe trait`.
14 changes: 12 additions & 2 deletions src/type_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ pub trait PySizedLayout<T>: PyLayout<T> + Sized {}
///
/// Implementations must provide an implementation for `type_object_raw` which infallibly produces a
/// non-null pointer to the corresponding Python type object.
///
/// `is_type_of` must only return true for objects which can safely be treated as instances of `Self`.
///
/// `is_exact_type_of` must only return true for objects whose type is exactly `Self`.
pub unsafe trait PyTypeInfo: Sized {
/// Class name.
const NAME: &'static str;
Expand Down Expand Up @@ -85,7 +89,13 @@ pub unsafe trait PyTypeInfo: Sized {
}

/// Implemented by types which can be used as a concrete Python type inside `Py<T>` smart pointers.
pub trait PyTypeCheck {
///
/// # Safety
///
/// This trait is used to determine whether [`Bound::cast`] and similar functions can safely cast
/// to a concrete type. The implementor is responsible for ensuring that `type_check` only returns
/// true for objects which can safely be treated as Python instances of `Self`.
pub unsafe trait PyTypeCheck {
/// Name of self. This is used in error messages, for example.
#[deprecated(
since = "0.27.0",
Expand All @@ -108,7 +118,7 @@ pub trait PyTypeCheck {
fn classinfo_object(py: Python<'_>) -> Bound<'_, PyAny>;
}

impl<T> PyTypeCheck for T
unsafe impl<T> PyTypeCheck for T
where
T: PyTypeInfo,
{
Expand Down
2 changes: 1 addition & 1 deletion src/types/weakref/anyref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pyobject_native_type_named!(PyWeakref);
// #[cfg(not(Py_LIMITED_API))]
// pyobject_native_type_sized!(PyWeakref, ffi::PyWeakReference);

impl PyTypeCheck for PyWeakref {
unsafe impl PyTypeCheck for PyWeakref {
const NAME: &'static str = "weakref";

#[cfg(feature = "experimental-inspect")]
Expand Down
2 changes: 1 addition & 1 deletion src/types/weakref/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pyobject_native_type_named!(PyWeakrefProxy);
// #[cfg(not(Py_LIMITED_API))]
// pyobject_native_type_sized!(PyWeakrefProxy, ffi::PyWeakReference);

impl PyTypeCheck for PyWeakrefProxy {
unsafe impl PyTypeCheck for PyWeakrefProxy {
const NAME: &'static str = "weakref.ProxyTypes";

#[cfg(feature = "experimental-inspect")]
Expand Down
Loading