feat: add #[pyo3(get, set)] for Cell
This commit is contained in:
parent
59bbb40a35
commit
a629e8267a
|
@ -437,6 +437,8 @@ To use these annotations, your field type must implement some conversion traits:
|
|||
- For `get` the field type must implement both `IntoPy<PyObject>` and `Clone`.
|
||||
- For `set` the field type must implement `FromPyObject`.
|
||||
|
||||
For example, implementations of those traits are provided for the `Cell` type, if the inner type also implements the trait. This means you can use `#[pyo3(get, set)]` on fields wrapped in a `Cell`.
|
||||
|
||||
### Object properties using `#[getter]` and `#[setter]`
|
||||
|
||||
For cases which don't satisfy the `#[pyo3(get, set)]` trait requirements, or need side effects, descriptor methods can be defined in a `#[pymethods]` `impl` block.
|
||||
|
|
1
newsfragments/3014.added.md
Normal file
1
newsfragments/3014.added.md
Normal file
|
@ -0,0 +1 @@
|
|||
Add an `IntoPy<PyObject>`, `ToPyObject` and `FromPyObject` impl for `Cell`.
|
|
@ -10,6 +10,7 @@ use crate::types::PyTuple;
|
|||
use crate::{
|
||||
ffi, gil, Py, PyAny, PyCell, PyClass, PyNativeType, PyObject, PyRef, PyRefMut, Python,
|
||||
};
|
||||
use std::cell::Cell;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
/// Returns a borrowed pointer to a Python object.
|
||||
|
@ -370,6 +371,24 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + ToPyObject> ToPyObject for Cell<T> {
|
||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||
self.get().to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + IntoPy<PyObject>> IntoPy<PyObject> for Cell<T> {
|
||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||
self.get().into_py(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: FromPyObject<'a>> FromPyObject<'a> for Cell<T> {
|
||||
fn extract(ob: &'a PyAny) -> PyResult<Self> {
|
||||
T::extract(ob).map(Cell::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> FromPyObject<'a> for &'a PyCell<T>
|
||||
where
|
||||
T: PyClass,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#![cfg(feature = "macros")]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::py_run;
|
||||
use pyo3::types::{IntoPyDict, PyList};
|
||||
|
@ -189,3 +191,28 @@ fn get_all_and_set() {
|
|||
py_run!(py, inst, "inst.num = 20; assert inst.num == 20");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct CellGetterSetter {
|
||||
#[pyo3(get, set)]
|
||||
cell_inner: Cell<i32>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cell_getter_setter() {
|
||||
let c = CellGetterSetter {
|
||||
cell_inner: Cell::new(10),
|
||||
};
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(py, c).unwrap().to_object(py);
|
||||
let cell = Cell::new(20).to_object(py);
|
||||
|
||||
py_run!(py, cell, "assert cell == 20");
|
||||
py_run!(py, inst, "assert inst.cell_inner == 10");
|
||||
py_run!(
|
||||
py,
|
||||
inst,
|
||||
"inst.cell_inner = 20; assert inst.cell_inner == 20"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue