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
|
||||
- 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 `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
|
||||
- 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::gil;
|
||||
use crate::object::PyObject;
|
||||
use crate::pycell::{PyBorrowError, PyBorrowMutError, PyCell};
|
||||
use crate::type_object::PyBorrowFlagLayout;
|
||||
use crate::{
|
||||
ffi, AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, PyAny, PyCell, PyClass,
|
||||
PyClassInitializer, PyRef, PyRefMut, PyTypeInfo, Python, ToPyObject,
|
||||
ffi, AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, PyAny, PyClass, PyClassInitializer,
|
||||
PyRef, PyRefMut, PyTypeInfo, Python, ToPyObject,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
|
@ -49,14 +50,13 @@ unsafe impl<T> Send for Py<T> {}
|
|||
|
||||
unsafe impl<T> Sync for Py<T> {}
|
||||
|
||||
impl<T> Py<T> {
|
||||
/// Create a new instance `Py<T>`.
|
||||
///
|
||||
/// You can crate [`PyCell::new`](../pycell/struct.PyCell.html#method.new) and `Py::from`,
|
||||
/// but this method can be more efficient.
|
||||
pub fn new(py: Python, value: impl Into<PyClassInitializer<T>>) -> PyResult<Py<T>>
|
||||
impl<T> Py<T>
|
||||
where
|
||||
T: PyClass,
|
||||
{
|
||||
/// 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>>
|
||||
where
|
||||
T::BaseLayout: PyBorrowFlagLayout<T::BaseType>,
|
||||
{
|
||||
let initializer = value.into();
|
||||
|
@ -65,6 +65,57 @@ impl<T> Py<T> {
|
|||
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.
|
||||
///
|
||||
/// 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> {}
|
||||
|
||||
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>
|
||||
where
|
||||
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,
|
||||
/// so you don't have to use this trait directly.
|
||||
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.
|
||||
type Dict: PyClassDict;
|
||||
|
|
Loading…
Reference in a new issue