Macro rigetti_pyo3::py_wrap_data_struct
source · macro_rules! py_wrap_data_struct { ( $(#[$meta: meta])* $name: ident($rs_inner: ty) $(as $class_name: literal)? { $( $field_name: ident: $field_rs_type: ty $(=> $convert: ty)+ ),+ } ) => { ... }; }
Expand description
Wraps a data struct and makes (some of) its fields available to Python.
§Implements
- Everything implemented by
py_wrap_type. PyWrapperMut.get_fooandset_foomethods for fieldfoo, which translate to@propertyand@foo.setterin Python, i.e. allowing access to the field as a property.
§Warning!
The mutability of exposed fields may not work as you expect.
Since objects are converted back and forth along the FFI boundary using Clones,
pointers are not shared like in native Python. In native Python, this code runs
without issue:
class Test:
def __init__(self):
self.inner = {}
@property
def foo(self):
return self.inner
@foo.setter
def foo(self, value):
self.inner = value
c = Test()
d = c.inner
d["a"] = ["a"]
assert "a" in c.inner
d = c.foo
d["b"] = "b"
assert "b" in c.inner
Using these bindings, assuming that this macro was used to create Test, the
equivalent would be:
c = Test()
d = c.foo
d["a"] = ["a"]
assert "a" not in c.foo
c.foo = d
assert "a" in c.foo
§Example
use rigetti_pyo3::pyo3::{Py, types::{PyInt, PyString}};
use rigetti_pyo3::py_wrap_data_struct;
#[derive(Clone)]
pub struct Person {
pub name: String,
pub age: u8,
}
py_wrap_data_struct! {
PyPerson(Person) as "Person" {
name: String => Py<PyString>,
age: u8 => Py<PyInt>
}
}