[Python] PyO3 pass mutable rust struct between Rust and Python callbacks

Discussão em 'Python' iniciado por Stack, Setembro 15, 2024.

  1. Stack

    Stack Membro Participativo

    I am trying to use Python as a scripting engine for my Rust project. I have some Rust code which calls a Python function which in turn should call some Rust functions. The problem is that there is mutable state that I need to keep track of in Rust-land.

    The way I have it set up right now is that Descriptor::eval calls the python

    impl Descriptor {
    ...
    fn eval(&self, &PyRefMut<Context>) -> String {
    Python::with_gil(|py| {
    // inner is a Py<PyAny>
    self.inner.call_method(py, "to_string", (ctx,), None)
    .unwrap()
    .downcast_bound::<PyString>(py)
    .unwrap()
    .to_str()
    .unwrap()
    .to_string()
    })
    }
    }


    The python then calls back into the Rust:

    class Class(object):
    @staticmethod
    def to_string(ctx):
    return rust.eval_template(ctx, '$foo')


    #[pyfunction]
    fn eval_template(mut ctx: PyRefMut<ReprContext>, s: &str) -> String {
    // do stuff with s and ctx
    }


    The problem is that when the python code tries to call rust.eval_template, the dynamic borrow checker says that ctx is already borrowed.

    What I'm guessing is happening is that call_method borrows ctx and since rust.eval_template is called before that function returns, eval_template then also tries to borrow ctx. Though I'm a bit unclear as to what is happening on the whole.

    Continue reading...

Compartilhe esta Página