Skip to content

Commit

Permalink
Remove ToPyPointer and so on from pyclass
Browse files Browse the repository at this point in the history
  • Loading branch information
kngwyu committed Feb 1, 2019
1 parent ee4fc3b commit 7d7e55d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 33 deletions.
23 changes: 0 additions & 23 deletions pyo3-derive-backend/src/py_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,29 +171,6 @@ fn impl_class(
}
}

impl ::pyo3::ToPyObject for #cls {
fn to_object(&self, py: ::pyo3::Python) -> ::pyo3::PyObject {
use ::pyo3::python::ToPyPointer;
unsafe { ::pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
}
}

impl ::pyo3::ToPyPointer for #cls {
fn as_ptr(&self) -> *mut ::pyo3::ffi::PyObject {
unsafe {
{self as *const _ as *mut u8}
.offset(-<#cls as ::pyo3::typeob::PyTypeInfo>::OFFSET) as *mut ::pyo3::ffi::PyObject
}
}
}

impl<'a> ::pyo3::ToPyObject for &'a mut #cls {
fn to_object(&self, py: ::pyo3::Python) -> ::pyo3::PyObject {
use ::pyo3::python::ToPyPointer;
unsafe { ::pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
}
}

#extra
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ impl<T: IntoPyObject> ReturnTypeIntoPyResult for PyResult<T> {
}
}



#[cfg(test)]
mod test {
use super::PyTryFrom;
Expand Down
84 changes: 80 additions & 4 deletions src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std;
use std::mem;
use std::ptr::NonNull;
use std::ops::{Deref, DerefMut};

use crate::conversion::{FromPyObject, IntoPyObject, ToPyObject};
use crate::err::{PyErr, PyResult};
Expand All @@ -27,6 +28,80 @@ pub trait PyObjectWithGIL: Sized {
#[doc(hidden)]
pub trait PyNativeType: PyObjectWithGIL {}

#[derive(Debug)]
pub struct PyRef<'a, T> {
inner: &'a T,
}

impl<'a, T> PyRef<'a, T> {
pub(crate) fn new(t: &'a T) -> Self {
PyRef { inner: t }
}
}

impl<'a, T: PyTypeInfo> ToPyPointer for PyRef<'a, T> {
fn as_ptr(&self) -> *mut ffi::PyObject {
unsafe{
(self.inner as *const _ as *mut u8).offset(-T::OFFSET) as *mut _
}
}
}

impl<'a, T: PyTypeInfo> ToPyObject for PyRef<'a, T> {
fn to_object(&self, py: Python) -> PyObject {
unsafe{
PyObject::from_borrowed_ptr(py, self.as_ptr())
}
}
}

impl<'a, T> Deref for PyRef<'a, T> {
type Target = T;
fn deref(&self) -> &T {
self.inner
}
}

#[derive(Debug)]
pub struct PyRefMut<'a, T> {
inner: &'a mut T,
}

impl<'a, T> PyRefMut<'a, T> {
pub(crate) fn new(t: &'a mut T) -> Self {
PyRefMut { inner: t }
}
}

impl<'a, T: PyTypeInfo> ToPyPointer for PyRefMut<'a, T> {
fn as_ptr(&self) -> *mut ffi::PyObject {
unsafe{
(self.inner as *const _ as *mut u8).offset(-T::OFFSET) as *mut _
}
}
}

impl<'a, T: PyTypeInfo> ToPyObject for PyRefMut<'a, T> {
fn to_object(&self, py: Python) -> PyObject {
unsafe{
PyObject::from_borrowed_ptr(py, self.as_ptr())
}
}
}

impl<'a, T> Deref for PyRefMut<'a, T> {
type Target = T;
fn deref(&self) -> &T {
self.inner
}
}

impl<'a, T> DerefMut for PyRefMut<'a, T> {
fn deref_mut(&mut self) -> &mut T {
self.inner
}
}

/// Trait implements object reference extraction from python managed pointer.
pub trait AsPyRef<T>: Sized {
/// Return reference to object.
Expand Down Expand Up @@ -186,28 +261,28 @@ where

/// Create new instance of `T` and move it under python management.
/// Returns references to `T`
pub fn new_ref<F>(py: Python, f: F) -> PyResult<&T>
pub fn new_ref<F>(py: Python, f: F) -> PyResult<PyRef<T>>
where
F: FnOnce() -> T,
T: PyTypeObject + PyTypeInfo,
{
let ob = <T as PyTypeCreate>::create(py)?;
ob.init(f)?;

unsafe { Ok(py.from_owned_ptr(ob.into_ptr())) }
unsafe { Ok(PyRef::new(py.from_owned_ptr(ob.into_ptr()))) }
}

/// Create new instance of `T` and move it under python management.
/// Returns mutable references to `T`
pub fn new_mut<F>(py: Python, f: F) -> PyResult<&mut T>
pub fn new_mut<F>(py: Python, f: F) -> PyResult<PyRefMut<T>>
where
F: FnOnce() -> T,
T: PyTypeObject + PyTypeInfo,
{
let ob = <T as PyTypeCreate>::create(py)?;
ob.init(f)?;

unsafe { Ok(py.mut_from_owned_ptr(ob.into_ptr())) }
unsafe { Ok(PyRefMut::new(py.mut_from_owned_ptr(ob.into_ptr()))) }
}
}

Expand Down Expand Up @@ -359,3 +434,4 @@ where
}
}
}

7 changes: 3 additions & 4 deletions src/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use crate::conversion::PyTryFrom;
use crate::err::{PyDowncastError, PyErr, PyResult};
use crate::ffi;
use crate::instance::{AsPyRef, Py};
use crate::instance::{AsPyRef, Py, PyRef, PyRefMut};
use crate::object::PyObject;
use crate::pythonrun::{self, GILGuard};
use crate::typeob::PyTypeCreate;
Expand Down Expand Up @@ -90,7 +90,6 @@ where
}
}

/// Gets the underlying FFI pointer, returns a borrowed pointer.
impl<'a, T> IntoPyPointer for &'a T
where
T: ToPyPointer,
Expand Down Expand Up @@ -263,7 +262,7 @@ impl<'p> Python<'p> {
/// Create new instance of `T` and move it under python management.
/// Created object get registered in release pool. Returns references to `T`
#[inline]
pub fn init_ref<T, F>(self, f: F) -> PyResult<&'p T>
pub fn init_ref<T, F>(self, f: F) -> PyResult<PyRef<'p, T>>
where
F: FnOnce() -> T,
T: PyTypeCreate,
Expand All @@ -274,7 +273,7 @@ impl<'p> Python<'p> {
/// Create new instance of `T` and move it under python management.
/// Created object get registered in release pool. Returns mutable references to `T`
#[inline]
pub fn init_mut<T, F>(self, f: F) -> PyResult<&'p mut T>
pub fn init_mut<T, F>(self, f: F) -> PyResult<PyRefMut<'p, T>>
where
F: FnOnce() -> T,
T: PyTypeCreate,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ fn gc_integration() {
})
.unwrap();

*inst.self_ref.borrow_mut() = inst.into();
*inst.self_ref.borrow_mut() = inst.to_object(py);
}

let gil = Python::acquire_gil();
Expand Down Expand Up @@ -267,7 +267,7 @@ fn inheritance_with_new_methods_with_drop() {
obj.data = Some(Arc::clone(&drop_called1));

let base: &mut <SubClassWithDrop as pyo3::PyTypeInfo>::BaseType =
unsafe { py.mut_from_borrowed_ptr(obj.as_ptr()) };
unsafe { py.mut_from_borrowed_ptr(inst.as_ptr()) };
base.data = Some(Arc::clone(&drop_called2));
}

Expand Down

0 comments on commit 7d7e55d

Please sign in to comment.