Reputation: 31
I am trying to pass a Python object into rust and perform operations using the fields of the Python object.
Python:
class myclass(object):
def __init__(self):
self.a = 3
b = myclass()
print(b.a)
// 3
Rust:
#[pyfn(m, "rust_obj")]
fn rust_obj_py(py: Python, x: PyObject) -> PyResult<PyObject> {
let y = x.clone_ref(py);
y.a += 2;
Ok(y)
}
Expected result when calling from Python would be:
c = rust_obj(b)
print(c.a)
// 5
Instead Rust error out when compiling:
error[E0609]: no field `a` on type `pyo3::PyObject`
--> src\lib.rs:926:5
|
926 | y.a += 2;
| ^ unknown field
Is there a way to list the object fields and methods in rust and manipulate the fields?
Upvotes: 3
Views: 1100
Reputation: 1068
You are calling clone_ref
on y:
let y = x.clone_ref(py);
clone_ref
returns another PyObject
. Then you're invoking
y.a += 2;
And the compiler correctly tells you "no field a
on type pyo3::PyObject". Because PyObject
doesn't expose the fields you would expect in a Python object directly (It would be difficuly to do so since python is dynamically typed whereas rust is a statically typed language, so all members of PyObject have to be known at compile-time). The documentation is helpful in these cases to learn how to use PyObject
. There you'll see that you can still access a
, but you have to go through the getattr
method. In order to do the +=
I suspect you'd probably best call python's __iadd__
method explicitly through the call_method
API.
Upvotes: 1