Merge pull request #3358 from alex/ptr-unsafe-trait

fixes #3325 -- mark `AsPyPointer` as `unsafe trait`
This commit is contained in:
David Hewitt 2023-09-04 05:05:56 +00:00 committed by GitHub
commit e67b283b25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 16 additions and 9 deletions

View File

@ -66,6 +66,10 @@ fn add(a: u64, b: u64) -> u64 {
The trait `IntoPyPointer`, which provided the `into_ptr` method on many types, has been removed. `into_ptr` is now available as an inherent method on all types that previously implemented this trait. The trait `IntoPyPointer`, which provided the `into_ptr` method on many types, has been removed. `into_ptr` is now available as an inherent method on all types that previously implemented this trait.
### `AsPyPointer` now `unsafe` trait
The trait `AsPyPointer` is now `unsafe trait`, meaning any external implementation of it must be marked as `unsafe impl`, and ensure that they uphold the invariant of returning valid pointers.
## from 0.18.* to 0.19 ## from 0.18.* to 0.19
### Access to `Python` inside `__traverse__` implementations are now forbidden ### Access to `Python` inside `__traverse__` implementations are now forbidden

View File

@ -0,0 +1 @@
`AsPyPointer` is now `unsafe trait`.

View File

@ -34,7 +34,7 @@ use std::ptr::NonNull;
/// ///
/// # Safety /// # Safety
/// ///
/// It is your responsibility to make sure that the underlying Python object is not dropped too /// For callers, it is your responsibility to make sure that the underlying Python object is not dropped too
/// early. For example, the following code will cause undefined behavior: /// early. For example, the following code will cause undefined behavior:
/// ///
/// ```rust,no_run /// ```rust,no_run
@ -56,13 +56,15 @@ use std::ptr::NonNull;
/// and the Python object is dropped immediately after the `0xabad1dea_u32.into_py(py).as_ptr()` /// and the Python object is dropped immediately after the `0xabad1dea_u32.into_py(py).as_ptr()`
/// expression is evaluated. To fix the problem, bind Python object to a local variable like earlier /// expression is evaluated. To fix the problem, bind Python object to a local variable like earlier
/// to keep the Python object alive until the end of its scope. /// to keep the Python object alive until the end of its scope.
pub trait AsPyPointer { ///
/// Implementors must ensure this returns a valid pointer to a Python object, which borrows a reference count from `&self`.
pub unsafe trait AsPyPointer {
/// Returns the underlying FFI pointer as a borrowed pointer. /// Returns the underlying FFI pointer as a borrowed pointer.
fn as_ptr(&self) -> *mut ffi::PyObject; fn as_ptr(&self) -> *mut ffi::PyObject;
} }
/// Convert `None` into a null pointer. /// Convert `None` into a null pointer.
impl<T> AsPyPointer for Option<T> unsafe impl<T> AsPyPointer for Option<T>
where where
T: AsPyPointer, T: AsPyPointer,
{ {

View File

@ -932,7 +932,7 @@ impl<T> IntoPy<PyObject> for &'_ Py<T> {
} }
} }
impl<T> crate::AsPyPointer for Py<T> { unsafe impl<T> crate::AsPyPointer for Py<T> {
/// Gets the underlying FFI pointer, returns a borrowed pointer. /// Gets the underlying FFI pointer, returns a borrowed pointer.
#[inline] #[inline]
fn as_ptr(&self) -> *mut ffi::PyObject { fn as_ptr(&self) -> *mut ffi::PyObject {

View File

@ -528,7 +528,7 @@ impl<T: PyClassImpl> PyCell<T> {
unsafe impl<T: PyClassImpl> PyLayout<T> for PyCell<T> {} unsafe impl<T: PyClassImpl> PyLayout<T> for PyCell<T> {}
impl<T: PyClass> PySizedLayout<T> for PyCell<T> {} impl<T: PyClass> PySizedLayout<T> for PyCell<T> {}
impl<T: PyClass> AsPyPointer for PyCell<T> { unsafe impl<T: PyClass> AsPyPointer for PyCell<T> {
fn as_ptr(&self) -> *mut ffi::PyObject { fn as_ptr(&self) -> *mut ffi::PyObject {
(self as *const _) as *mut _ (self as *const _) as *mut _
} }
@ -756,7 +756,7 @@ impl<'a, T: PyClass> std::convert::TryFrom<&'a PyCell<T>> for crate::PyRef<'a, T
} }
} }
impl<'a, T: PyClass> AsPyPointer for PyRef<'a, T> { unsafe impl<'a, T: PyClass> AsPyPointer for PyRef<'a, T> {
fn as_ptr(&self) -> *mut ffi::PyObject { fn as_ptr(&self) -> *mut ffi::PyObject {
self.inner.as_ptr() self.inner.as_ptr()
} }
@ -879,7 +879,7 @@ impl<T: PyClass<Frozen = False>> IntoPy<PyObject> for &'_ PyRefMut<'_, T> {
} }
} }
impl<'a, T: PyClass<Frozen = False>> AsPyPointer for PyRefMut<'a, T> { unsafe impl<'a, T: PyClass<Frozen = False>> AsPyPointer for PyRefMut<'a, T> {
fn as_ptr(&self) -> *mut ffi::PyObject { fn as_ptr(&self) -> *mut ffi::PyObject {
self.inner.as_ptr() self.inner.as_ptr()
} }

View File

@ -36,7 +36,7 @@ use std::os::raw::c_int;
#[repr(transparent)] #[repr(transparent)]
pub struct PyAny(UnsafeCell<ffi::PyObject>); pub struct PyAny(UnsafeCell<ffi::PyObject>);
impl AsPyPointer for PyAny { unsafe impl AsPyPointer for PyAny {
#[inline] #[inline]
fn as_ptr(&self) -> *mut ffi::PyObject { fn as_ptr(&self) -> *mut ffi::PyObject {
self.0.get() self.0.get()

View File

@ -147,7 +147,7 @@ macro_rules! pyobject_native_type_named (
} }
} }
impl<$($generics,)*> $crate::AsPyPointer for $name { unsafe impl<$($generics,)*> $crate::AsPyPointer for $name {
/// Gets the underlying FFI pointer, returns a borrowed pointer. /// Gets the underlying FFI pointer, returns a borrowed pointer.
#[inline] #[inline]
fn as_ptr(&self) -> *mut $crate::ffi::PyObject { fn as_ptr(&self) -> *mut $crate::ffi::PyObject {