1
- //! Traits and structs for `#[pyclass]` .
1
+ //! Includes `PyCell` implementation .
2
2
use crate :: conversion:: { AsPyPointer , FromPyPointer , ToPyObject } ;
3
3
use crate :: pyclass_init:: PyClassInitializer ;
4
4
use crate :: pyclass_slots:: { PyClassDict , PyClassWeakRef } ;
@@ -90,12 +90,19 @@ impl<T: PyClass> PyCellInner<T> {
90
90
}
91
91
}
92
92
93
- // TODO(kngwyu): Mutability example
94
- /// `PyCell` represents the concrete layout of `T: PyClass` when it is converted
95
- /// to a Python class.
93
+ /// `PyCell` is the container type for [`PyClass`](trait.PyClass.html).
96
94
///
97
- /// You can use it to test your `#[pyclass]` correctly works.
95
+ /// From Python side, `PyCell<T>` is the concrete layout of `T: PyClass` in the Python heap,
96
+ /// which means we can convert `*const PyClass<T>` to `*mut ffi::PyObject`.
98
97
///
98
+ /// From Rust side, `PyCell<T>` is the mutable container of `T`.
99
+ /// Since `PyCell<T: PyClass>` is always on the Python heap, we don't have the ownership of it.
100
+ /// Thus, to mutate the data behind `&PyCell<T>` safely, we employ the
101
+ /// [Interior Mutability Pattern](https://doc.rust-lang.org/book/ch15-05-interior-mutability.html)
102
+ /// like [std::cell::RefCell](https://doc.rust-lang.org/std/cell/struct.RefCell.html).
103
+ ///
104
+ /// In most cases, `PyCell` is hidden behind `#[pymethods]`.
105
+ /// However, you can construct `&PyCell` directly to test your pyclass in Rust code.
99
106
/// ```
100
107
/// # use pyo3::prelude::*;
101
108
/// # use pyo3::{py_run, PyCell};
@@ -112,6 +119,7 @@ impl<T: PyClass> PyCellInner<T> {
112
119
/// author: "Philip Kindred Dick",
113
120
/// };
114
121
/// let book_cell = PyCell::new(py, book).unwrap();
122
+ /// // you can expose PyCell to Python snippets
115
123
/// py_run!(py, book_cell, "assert book_cell.name[-6:] == 'Castle'");
116
124
/// ```
117
125
#[ repr( C ) ]
@@ -254,6 +262,9 @@ impl<T: PyClass + fmt::Debug> fmt::Debug for PyCell<T> {
254
262
}
255
263
}
256
264
265
+ /// Wraps a borrowed reference to a value in a `PyCell<T>`.
266
+ ///
267
+ /// See the [`PyCell`](struct.PyCell.html) documentation for more.
257
268
pub struct PyRef < ' p , T : PyClass > {
258
269
inner : & ' p PyCellInner < T > ,
259
270
}
@@ -319,6 +330,9 @@ impl<T: PyClass + fmt::Debug> fmt::Debug for PyRef<'_, T> {
319
330
}
320
331
}
321
332
333
+ /// Wraps a mutable borrowed reference to a value in a `PyCell<T>`.
334
+ ///
335
+ /// See the [`PyCell`](struct.PyCell.html) documentation for more.
322
336
pub struct PyRefMut < ' p , T : PyClass > {
323
337
inner : & ' p PyCellInner < T > ,
324
338
}
0 commit comments