add some safety notes

This commit is contained in:
Nicholas Sim 2021-01-15 22:31:40 +08:00
parent b6f595ba01
commit 66dc262949
4 changed files with 79 additions and 0 deletions

View file

@ -290,6 +290,10 @@ pub trait PyTryFrom<'v>: Sized + PyNativeType {
/// Cast a PyAny to a specific type of PyObject. The caller must
/// have already verified the reference is for this type.
///
/// # Safety
///
/// Callers must ensure that the type is valid or risk type confusion.
unsafe fn try_from_unchecked<V: Into<&'v PyAny>>(value: V) -> &'v Self;
}
@ -387,24 +391,64 @@ impl IntoPy<Py<PyTuple>> for () {
/// Raw level conversion between `*mut ffi::PyObject` and PyO3 types.
pub unsafe trait FromPyPointer<'p>: Sized {
/// Convert from an arbitrary `PyObject`.
///
/// # Safety
///
/// Implementations must ensure the object does not get freed during `'p` and avoid type confusion.
unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<&'p Self>;
/// Convert from an arbitrary `PyObject` or panic.
///
/// # Safety
///
/// Relies on unsafe fn `from_owned_ptr_or_opt`.
unsafe fn from_owned_ptr_or_panic(py: Python<'p>, ptr: *mut ffi::PyObject) -> &'p Self {
Self::from_owned_ptr_or_opt(py, ptr).unwrap_or_else(|| err::panic_after_error(py))
}
/// Convert from an arbitrary `PyObject` or panic.
///
/// # Safety
///
/// Relies on unsafe fn `from_owned_ptr_or_opt`.
unsafe fn from_owned_ptr(py: Python<'p>, ptr: *mut ffi::PyObject) -> &'p Self {
Self::from_owned_ptr_or_panic(py, ptr)
}
/// Convert from an arbitrary `PyObject`.
///
/// # Safety
///
/// Relies on unsafe fn `from_owned_ptr_or_opt`.
unsafe fn from_owned_ptr_or_err(py: Python<'p>, ptr: *mut ffi::PyObject) -> PyResult<&'p Self> {
Self::from_owned_ptr_or_opt(py, ptr).ok_or_else(|| err::PyErr::fetch(py))
}
/// Convert from an arbitrary borrowed `PyObject`.
///
/// # Safety
///
/// Implementations must ensure the object does not get freed during `'p` and avoid type confusion.
unsafe fn from_borrowed_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject)
-> Option<&'p Self>;
/// Convert from an arbitrary borrowed `PyObject`.
///
/// # Safety
///
/// Relies on unsafe fn `from_borrowed_ptr_or_opt`.
unsafe fn from_borrowed_ptr_or_panic(py: Python<'p>, ptr: *mut ffi::PyObject) -> &'p Self {
Self::from_borrowed_ptr_or_opt(py, ptr).unwrap_or_else(|| err::panic_after_error(py))
}
/// Convert from an arbitrary borrowed `PyObject`.
///
/// # Safety
///
/// Relies on unsafe fn `from_borrowed_ptr_or_opt`.
unsafe fn from_borrowed_ptr(py: Python<'p>, ptr: *mut ffi::PyObject) -> &'p Self {
Self::from_borrowed_ptr_or_panic(py, ptr)
}
/// Convert from an arbitrary borrowed `PyObject`.
///
/// # Safety
///
/// Relies on unsafe fn `from_borrowed_ptr_or_opt`.
unsafe fn from_borrowed_ptr_or_err(
py: Python<'p>,
ptr: *mut ffi::PyObject,

View file

@ -356,6 +356,9 @@ impl<T> Py<T> {
}
/// Deprecated alias for [`from_owned_ptr`](#method.from_owned_ptr).
///
/// # Safety
/// `ptr` must be a pointer to a Python object of type T.
#[inline]
#[deprecated = "this is a deprecated alias for Py::from_owned_ptr"]
pub unsafe fn from_owned_ptr_or_panic(py: Python, ptr: *mut ffi::PyObject) -> Py<T> {

View file

@ -448,6 +448,10 @@ impl<'p> Python<'p> {
/// Registers the object in the release pool, and does an unchecked downcast
/// to the specific type.
///
/// # Safety
///
/// Callers must ensure that ensure that the cast is valid.
pub unsafe fn cast_as<T>(self, obj: PyObject) -> &'p T
where
T: PyNativeType + PyTypeInfo,
@ -458,6 +462,10 @@ impl<'p> Python<'p> {
/// Registers the object pointer in the release pool,
/// and does an unchecked downcast to the specific type.
///
/// # Safety
///
/// Callers must ensure that ensure that the cast is valid.
#[allow(clippy::wrong_self_convention)]
pub unsafe fn from_owned_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p T
where
@ -470,6 +478,10 @@ impl<'p> Python<'p> {
///
/// Returns `Err(PyErr)` if the pointer is NULL.
/// Does an unchecked downcast to the specific type.
///
/// # Safety
///
/// Callers must ensure that ensure that the cast is valid.
#[allow(clippy::wrong_self_convention)]
pub unsafe fn from_owned_ptr_or_err<T>(self, ptr: *mut ffi::PyObject) -> PyResult<&'p T>
where
@ -482,6 +494,10 @@ impl<'p> Python<'p> {
///
/// Returns `None` if the pointer is NULL.
/// Does an unchecked downcast to the specific type.
///
/// # Safety
///
/// Callers must ensure that ensure that the cast is valid.
#[allow(clippy::wrong_self_convention)]
pub unsafe fn from_owned_ptr_or_opt<T>(self, ptr: *mut ffi::PyObject) -> Option<&'p T>
where
@ -493,6 +509,10 @@ impl<'p> Python<'p> {
/// Does an unchecked downcast to the specific type.
///
/// Panics if the pointer is NULL.
///
/// # Safety
///
/// Callers must ensure that ensure that the cast is valid.
#[allow(clippy::wrong_self_convention)]
pub unsafe fn from_borrowed_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p T
where
@ -504,6 +524,10 @@ impl<'p> Python<'p> {
/// Does an unchecked downcast to the specific type.
///
/// Returns `Err(PyErr)` if the pointer is NULL.
///
/// # Safety
///
/// Callers must ensure that ensure that the cast is valid.
#[allow(clippy::wrong_self_convention)]
pub unsafe fn from_borrowed_ptr_or_err<T>(self, ptr: *mut ffi::PyObject) -> PyResult<&'p T>
where
@ -515,6 +539,10 @@ impl<'p> Python<'p> {
/// Does an unchecked downcast to the specific type.
///
/// Returns `None` if the pointer is NULL.
///
/// # Safety
///
/// Callers must ensure that ensure that the cast is valid.
#[allow(clippy::wrong_self_convention)]
pub unsafe fn from_borrowed_ptr_or_opt<T>(self, ptr: *mut ffi::PyObject) -> Option<&'p T>
where

View file

@ -67,6 +67,10 @@ impl PyBytes {
/// Creates a new Python byte string object from a raw pointer and length.
///
/// Panics if out of memory.
///
/// # Safety
///
/// Unsafe as it deferences the raw pointer `ptr`.
pub unsafe fn from_ptr(py: Python<'_>, ptr: *const u8, len: usize) -> &PyBytes {
py.from_owned_ptr(ffi::PyBytes_FromStringAndSize(
ptr as *const _,