Merge pull request #976 from davidhewitt/prefer-py
Add PyClass borrow methods to Py
This commit is contained in:
commit
6ea834526b
|
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||||
### Added
|
### Added
|
||||||
- Add FFI definition `PyObject_AsFileDescriptor` [#938](https://github.com/PyO3/pyo3/pull/938)
|
- Add FFI definition `PyObject_AsFileDescriptor` [#938](https://github.com/PyO3/pyo3/pull/938)
|
||||||
- Add `PyByteArray::data`, `PyByteArray::as_bytes`, and `PyByteArray::as_bytes_mut`. [#967](https://github.com/PyO3/pyo3/pull/967)
|
- Add `PyByteArray::data`, `PyByteArray::as_bytes`, and `PyByteArray::as_bytes_mut`. [#967](https://github.com/PyO3/pyo3/pull/967)
|
||||||
|
- Add `Py::borrow`, `Py::borrow_mut`, `Py::try_borrow`, and `Py::try_borrow_mut` for accessing `#[pyclass]` values. [#976](https://github.com/PyO3/pyo3/pull/976)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Simplify internals of `#[pyo3(get)]` attribute. (Remove the hidden API `GetPropertyValue`.) [#934](https://github.com/PyO3/pyo3/pull/934)
|
- Simplify internals of `#[pyo3(get)]` attribute. (Remove the hidden API `GetPropertyValue`.) [#934](https://github.com/PyO3/pyo3/pull/934)
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
use crate::err::{PyErr, PyResult};
|
use crate::err::{PyErr, PyResult};
|
||||||
use crate::gil;
|
use crate::gil;
|
||||||
use crate::object::PyObject;
|
use crate::object::PyObject;
|
||||||
|
use crate::pycell::{PyBorrowError, PyBorrowMutError, PyCell};
|
||||||
use crate::type_object::PyBorrowFlagLayout;
|
use crate::type_object::PyBorrowFlagLayout;
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi, AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, PyAny, PyCell, PyClass,
|
ffi, AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, PyAny, PyClass, PyClassInitializer,
|
||||||
PyClassInitializer, PyRef, PyRefMut, PyTypeInfo, Python, ToPyObject,
|
PyRef, PyRefMut, PyTypeInfo, Python, ToPyObject,
|
||||||
};
|
};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -49,14 +50,13 @@ unsafe impl<T> Send for Py<T> {}
|
||||||
|
|
||||||
unsafe impl<T> Sync for Py<T> {}
|
unsafe impl<T> Sync for Py<T> {}
|
||||||
|
|
||||||
impl<T> Py<T> {
|
impl<T> Py<T>
|
||||||
/// Create a new instance `Py<T>`.
|
where
|
||||||
///
|
T: PyClass,
|
||||||
/// You can crate [`PyCell::new`](../pycell/struct.PyCell.html#method.new) and `Py::from`,
|
{
|
||||||
/// but this method can be more efficient.
|
/// Create a new instance `Py<T>` of a `#[pyclass]` on the Python heap.
|
||||||
pub fn new(py: Python, value: impl Into<PyClassInitializer<T>>) -> PyResult<Py<T>>
|
pub fn new(py: Python, value: impl Into<PyClassInitializer<T>>) -> PyResult<Py<T>>
|
||||||
where
|
where
|
||||||
T: PyClass,
|
|
||||||
T::BaseLayout: PyBorrowFlagLayout<T::BaseType>,
|
T::BaseLayout: PyBorrowFlagLayout<T::BaseType>,
|
||||||
{
|
{
|
||||||
let initializer = value.into();
|
let initializer = value.into();
|
||||||
|
@ -65,6 +65,57 @@ impl<T> Py<T> {
|
||||||
Ok(ob)
|
Ok(ob)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Immutably borrows the value `T`. This borrow lasts untill the returned `PyRef` exists.
|
||||||
|
///
|
||||||
|
/// Equivalent to `self.as_ref(py).borrow()` -
|
||||||
|
/// see [`PyCell::borrow`](../pycell/struct.PyCell.html#method.borrow)
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
|
||||||
|
/// [`try_borrow`](#method.try_borrow).
|
||||||
|
pub fn borrow<'py>(&'py self, py: Python<'py>) -> PyRef<'py, T> {
|
||||||
|
self.as_ref(py).borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mutably borrows the value `T`. This borrow lasts untill the returned `PyRefMut` exists.
|
||||||
|
///
|
||||||
|
/// Equivalent to `self.as_ref(py).borrow_mut()` -
|
||||||
|
/// see [`PyCell::borrow_mut`](../pycell/struct.PyCell.html#method.borrow_mut)
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
|
||||||
|
/// [`try_borrow_mut`](#method.try_borrow_mut).
|
||||||
|
pub fn borrow_mut<'py>(&'py self, py: Python<'py>) -> PyRefMut<'py, T> {
|
||||||
|
self.as_ref(py).borrow_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Immutably borrows the value `T`, returning an error if the value is currently
|
||||||
|
/// mutably borrowed. This borrow lasts untill the returned `PyRef` exists.
|
||||||
|
///
|
||||||
|
/// This is the non-panicking variant of [`borrow`](#method.borrow).
|
||||||
|
///
|
||||||
|
/// Equivalent to `self.as_ref(py).try_borrow()` -
|
||||||
|
/// see [`PyCell::try_borrow`](../pycell/struct.PyCell.html#method.try_borrow)
|
||||||
|
pub fn try_borrow<'py>(&'py self, py: Python<'py>) -> Result<PyRef<'py, T>, PyBorrowError> {
|
||||||
|
self.as_ref(py).try_borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mutably borrows the value `T`, returning an error if the value is currently borrowed.
|
||||||
|
/// This borrow lasts untill the returned `PyRefMut` exists.
|
||||||
|
///
|
||||||
|
/// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
|
||||||
|
///
|
||||||
|
/// Equivalent to `self.as_ref(py).try_borrow_mut() -
|
||||||
|
/// see [`PyCell::try_borrow_mut`](../pycell/struct.PyCell.html#method.try_borrow_mut)
|
||||||
|
pub fn try_borrow_mut<'py>(
|
||||||
|
&'py self,
|
||||||
|
py: Python<'py>,
|
||||||
|
) -> Result<PyRefMut<'py, T>, PyBorrowMutError> {
|
||||||
|
self.as_ref(py).try_borrow_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Py<T> {
|
||||||
/// Creates a `Py<T>` instance for the given FFI pointer.
|
/// Creates a `Py<T>` instance for the given FFI pointer.
|
||||||
///
|
///
|
||||||
/// This moves ownership over the pointer into the `Py<T>`.
|
/// This moves ownership over the pointer into the `Py<T>`.
|
||||||
|
|
|
@ -166,8 +166,11 @@ pub struct PyCell<T: PyClass> {
|
||||||
unsafe impl<T: PyClass> PyNativeType for PyCell<T> {}
|
unsafe impl<T: PyClass> PyNativeType for PyCell<T> {}
|
||||||
|
|
||||||
impl<T: PyClass> PyCell<T> {
|
impl<T: PyClass> PyCell<T> {
|
||||||
/// Make new `PyCell` on the Python heap and returns the reference of it.
|
/// Make a new `PyCell` on the Python heap and return the reference to it.
|
||||||
///
|
///
|
||||||
|
/// In cases where the value in the cell does not need to be accessed immediately after
|
||||||
|
/// creation, consider [`Py::new`](../instance/struct.Py.html#method.new) as a more efficient
|
||||||
|
/// alternative.
|
||||||
pub fn new(py: Python, value: impl Into<PyClassInitializer<T>>) -> PyResult<&Self>
|
pub fn new(py: Python, value: impl Into<PyClassInitializer<T>>) -> PyResult<&Self>
|
||||||
where
|
where
|
||||||
T::BaseLayout: PyBorrowFlagLayout<T::BaseType>,
|
T::BaseLayout: PyBorrowFlagLayout<T::BaseType>,
|
||||||
|
|
|
@ -73,7 +73,11 @@ pub unsafe fn tp_free_fallback(obj: *mut ffi::PyObject) {
|
||||||
/// The `#[pyclass]` attribute automatically implements this trait for your Rust struct,
|
/// The `#[pyclass]` attribute automatically implements this trait for your Rust struct,
|
||||||
/// so you don't have to use this trait directly.
|
/// so you don't have to use this trait directly.
|
||||||
pub trait PyClass:
|
pub trait PyClass:
|
||||||
PyTypeInfo<Layout = PyCell<Self>> + Sized + PyClassAlloc + PyMethods + Send
|
PyTypeInfo<Layout = PyCell<Self>, AsRefTarget = PyCell<Self>>
|
||||||
|
+ Sized
|
||||||
|
+ PyClassAlloc
|
||||||
|
+ PyMethods
|
||||||
|
+ Send
|
||||||
{
|
{
|
||||||
/// Specify this class has `#[pyclass(dict)]` or not.
|
/// Specify this class has `#[pyclass(dict)]` or not.
|
||||||
type Dict: PyClassDict;
|
type Dict: PyClassDict;
|
||||||
|
|
Loading…
Reference in a new issue