I am trying to implement a cache for the private variable of any python class.
Let's suppose I have this:
#[pyclass] struct ClassA { pv: Py<PyAny>, // GIL independent type, storable in another #[pyclass] field_a: Py<PyAny>, } #[pyclass] struct ClassB { class_a: Py<ClassA>, field_b: Py<PyAny>, } In the impls of ClassA, I have a method attempting to 'put' a reference of the ClassA object into the ClassB's class_a field. And return a newly instantiated ClassB object.
#[pymethods] impl ClassA { fn ret_class_b(&self, field_b: &PyAny) -> PyResult<ClassB> { let class_a: Py<ClassA> = Py::clone_ref(self, field_b.py()); ClassB { class_a: class_a, field_b: field_b.into_py(), } } } The above does not compile.
The issue is how do I get &Py<ClassA> from the receiver of the method so as to return another object where the receiver is referred to as a field in that object?
Edit / Update
Thanks to @cafce25 for his reminder on giving fully reproducible codes and the error from the compiler.
Here is it:
use pyo3::{ prelude::{*, Py, PyAny}, }; #[pymodule] fn stackoverflowqn(py: Python, pymod: &PyModule) -> PyResult<()> { #[pyclass(name = "class_a")] #[derive(Clone, Debug)] pub struct ClassA { pv: Option<Py<PyAny>>, // private value field_a: Py<PyAny>, } #[pyclass] #[derive(Clone, Debug)] pub struct ClassB { class_a: Py<ClassA>, field_b: Py<PyAny>, } #[pymethods] impl ClassA { #[new] pub fn __new__(_slf: PyRef<'_, Self>, field_a: PyObject) -> PyResult<ClassA> { Ok(ClassA { pv: None, field_a: field_a, }) } fn ret_class_b {&self, field_b: &PyAny) -> PyResult<ClassB> { let class_a: Py<ClassA> = Py::clone_ref(self, field_b.py()); Ok(ClassB { class_a: class_a, field_b: field_b.into_py(), }) } } } Here is the compiler error:
error[E0277]: the trait bound `ClassA: pyo3::IntoPy<pyo3::Py<ClassA>>` is not satisfied --> crates\cached-property\src\stackoverflow.rs:36:53 | 36 | pyo3::IntoPy::<Py<ClassA>>::into_py(pty_getter, py); | ----------------------------------- ^^^^^^^^^^ the trait `pyo3::IntoPy<pyo3::Py<ClassA>>` is not implemented for `ClassA` | | | required by a bound introduced by this call | = help: the trait `pyo3::IntoPy<pyo3::Py<PyAny>>` is implemented for `ClassA`