Merge pull request #369 from kngwyu/hide-nativetype

Make PyNativeType unsafe
This commit is contained in:
konstin 2019-02-26 23:53:12 +01:00 committed by GitHub
commit dcce57f4f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 33 deletions

View file

@ -22,8 +22,10 @@ use std::rc::Rc;
///
/// pyo3 is designed in a way that that all references to those types are bound to the GIL,
/// which is why you can get a token from all references of those types.
pub trait PyNativeType: Sized {
fn py(&self) -> Python;
pub unsafe trait PyNativeType: Sized {
fn py(&self) -> Python {
unsafe { Python::assume_gil_acquired() }
}
}
/// A special reference of type `T`. `PyRef<T>` refers a instance of T, which exists in the Python
@ -58,6 +60,13 @@ pub trait PyNativeType: Sized {
#[derive(Debug)]
pub struct PyRef<'a, T: PyTypeInfo>(&'a T, PhantomData<Rc<()>>);
fn ref_to_ptr<T>(t: &T) -> *mut ffi::PyObject
where
T: PyTypeInfo,
{
unsafe { (t as *const _ as *mut u8).offset(-T::OFFSET) as *mut _ }
}
impl<'a, T: PyTypeInfo> PyRef<'a, T> {
pub(crate) fn from_ref(r: &'a T) -> Self {
PyRef(r, PhantomData)
@ -78,7 +87,7 @@ where
impl<'a, T: PyTypeInfo> AsPyPointer for PyRef<'a, T> {
fn as_ptr(&self) -> *mut ffi::PyObject {
self.0.as_ptr_dispatch()
ref_to_ptr(self.0)
}
}
@ -141,7 +150,7 @@ where
impl<'a, T: PyTypeInfo> AsPyPointer for PyRefMut<'a, T> {
fn as_ptr(&self) -> *mut ffi::PyObject {
(self.0 as &T).as_ptr_dispatch()
ref_to_ptr(self.0)
}
}
@ -182,22 +191,6 @@ where
}
}
/// Specialization workaround
trait PyRefDispatch<T: PyTypeInfo> {
#[allow(clippy::cast_ptr_alignment)]
fn as_ptr_dispatch(&self) -> *mut ffi::PyObject {
unsafe { (self as *const _ as *mut u8).offset(-T::OFFSET) as *mut _ }
}
}
impl<T: PyTypeInfo> PyRefDispatch<T> for T {}
impl<T: PyTypeInfo + PyNativeType> PyRefDispatch<T> for T {
fn as_ptr_dispatch(&self) -> *mut ffi::PyObject {
self as *const _ as *mut _
}
}
/// Trait implements object reference extraction from python managed pointer.
pub trait AsPyRef<T: PyTypeInfo>: Sized {
/// Return reference to object.
@ -355,13 +348,13 @@ trait AsPyRefDispatch<T: PyTypeInfo>: AsPyPointer {
fn as_ref_dispatch(&self, _py: Python) -> &T {
unsafe {
let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
ptr.as_ref().unwrap()
ptr.as_ref().expect("Py has a null pointer")
}
}
fn as_mut_dispatch(&mut self, _py: Python) -> &mut T {
unsafe {
let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
ptr.as_mut().unwrap()
ptr.as_mut().expect("Py has a null pointer")
}
}
}

View file

@ -172,12 +172,7 @@ impl IntoPyPointer for PyRawObject {
}
}
impl PyNativeType for PyRawObject {
#[inline]
fn py(&self) -> Python {
unsafe { Python::assume_gil_acquired() }
}
}
unsafe impl PyNativeType for PyRawObject {}
pub(crate) unsafe fn pytype_drop<T: PyTypeInfo>(py: Python, obj: *mut ffi::PyObject) {
if T::OFFSET != 0 {

View file

@ -64,11 +64,7 @@ macro_rules! pyobject_native_type_named (
}
}
impl<$($type_param,)*> $crate::PyNativeType for $name {
fn py(&self) -> $crate::Python {
unsafe { $crate::Python::assume_gil_acquired() }
}
}
unsafe impl<$($type_param,)*> $crate::PyNativeType for $name {}
impl<$($type_param,)*> $crate::AsPyPointer for $name {
/// Gets the underlying FFI pointer, returns a borrowed pointer.