Skip to content

Commit

Permalink
Merge pull request #887 from kngwyu/new-nativetypes
Browse files Browse the repository at this point in the history
New Native Types and Lighter GILPool
  • Loading branch information
kngwyu committed May 3, 2020
2 parents 17cf97d + 75c807f commit e9bec07
Show file tree
Hide file tree
Showing 27 changed files with 224 additions and 403 deletions.
6 changes: 4 additions & 2 deletions guide/src/rust_cpython.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ impl MyClass {

## Ownership and lifetimes

All objects are owned by the PyO3 library and all APIs available with references, while in rust-cpython, you own python objects.
While in rust-cpython you always own python objects, PyO3 allows efficient *borrowed objects*
and most APIs are available with references.

Here is an example of the PyList API:

Expand All @@ -73,7 +74,8 @@ impl PyList {
}
```

Because PyO3 allows only references to Python objects, all references have the GIL lifetime. So the owned Python object is not required, and it is safe to have functions like `fn py<'p>(&'p self) -> Python<'p> {}`.
In PyO3, all object references are bounded by the GIL lifetime.
So the owned Python object is not required, and it is safe to have functions like `fn py<'p>(&'p self) -> Python<'p> {}`.

## Error handling

Expand Down
28 changes: 7 additions & 21 deletions src/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Conversions between various states of Rust and Python types and their wrappers.
use crate::err::{self, PyDowncastError, PyResult};
use crate::object::PyObject;
use crate::type_object::{PyDowncastImpl, PyTypeInfo};
use crate::type_object::PyTypeInfo;
use crate::types::PyTuple;
use crate::{ffi, gil, Py, PyAny, PyCell, PyClass, PyNativeType, PyRef, PyRefMut, Python};
use std::ptr::NonNull;
Expand Down Expand Up @@ -311,7 +311,7 @@ where
/// If `T` implements `PyTryFrom`, we can convert `&PyAny` to `&T`.
///
/// This trait is similar to `std::convert::TryFrom`
pub trait PyTryFrom<'v>: Sized + PyDowncastImpl {
pub trait PyTryFrom<'v>: Sized + PyNativeType {
/// Cast from a concrete Python object type to PyObject.
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, PyDowncastError>;

Expand Down Expand Up @@ -348,7 +348,7 @@ where

impl<'v, T> PyTryFrom<'v> for T
where
T: PyDowncastImpl + PyTypeInfo + PyNativeType,
T: PyTypeInfo + PyNativeType,
{
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, PyDowncastError> {
let value = value.into();
Expand Down Expand Up @@ -460,28 +460,14 @@ where
T: 'p + crate::PyNativeType,
{
unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<&'p Self> {
NonNull::new(ptr).map(|p| Self::unchecked_downcast(gil::register_owned(py, p)))
gil::register_owned(py, NonNull::new(ptr)?);
Some(&*(ptr as *mut Self))
}
unsafe fn from_borrowed_ptr_or_opt(
py: Python<'p>,
ptr: *mut ffi::PyObject,
) -> Option<&'p Self> {
NonNull::new(ptr).map(|p| Self::unchecked_downcast(gil::register_borrowed(py, p)))
}
}

unsafe impl<'p, T> FromPyPointer<'p> for PyCell<T>
where
T: PyClass,
{
unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<&'p Self> {
NonNull::new(ptr).map(|p| &*(gil::register_owned(py, p).as_ptr() as *const PyCell<T>))
}
unsafe fn from_borrowed_ptr_or_opt(
py: Python<'p>,
_py: Python<'p>,
ptr: *mut ffi::PyObject,
) -> Option<&'p Self> {
NonNull::new(ptr).map(|p| &*(gil::register_borrowed(py, p).as_ptr() as *const PyCell<T>))
NonNull::new(ptr as *mut Self).map(|p| &*p.as_ptr())
}
}

Expand Down
Loading

0 comments on commit e9bec07

Please sign in to comment.