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 3, 2019
1 parent 9e53418 commit 76e30b5
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 11 deletions.
3 changes: 3 additions & 0 deletions pyo3-derive-backend/src/py_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ fn impl_class(
}
}

<<<<<<< HEAD
impl ::pyo3::ToPyObject for #cls {
fn to_object(&self, py: ::pyo3::Python) -> ::pyo3::PyObject {
use ::pyo3::python::ToPyPointer;
Expand All @@ -235,6 +236,8 @@ fn impl_class(

#inventory_impl

=======
>>>>>>> Remove ToPyPointer and so on from pyclass
#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
76 changes: 71 additions & 5 deletions src/instance.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Copyright (c) 2017-present PyO3 Project and Contributors

use crate::conversion::{FromPyObject, IntoPyObject, ToPyObject};
use crate::err::{PyErr, PyResult};
use crate::ffi;
Expand All @@ -12,6 +11,7 @@ use crate::typeob::PyTypeCreate;
use crate::typeob::{PyTypeInfo, PyTypeObject};
use crate::types::PyObjectRef;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;

/// Any instance that is managed Python can have access to `gil`.
Expand All @@ -25,6 +25,72 @@ 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 @@ -184,28 +250,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
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 @@ -89,7 +89,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 @@ -262,7 +261,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 @@ -273,7 +272,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 @@ -165,7 +165,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 @@ -262,7 +262,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 76e30b5

Please sign in to comment.