pythonize
pythonize copied to clipboard
IntoPy and FromPyObject integration
As currently designed, pythonize and depythonize on structs with both Serialize and IntoPy implementations will always use the Serialize implementation.
I'm not sure if that's surprising - it's certainly predictable though.
Open point of discussion as to whether pythonize should attempt to re-use existing IntoPy implementations, and if so, how could this be implemented?
I had a crate (closed source unfortunately) that does the same as pythonize. The idea is to opt in to custom serialization/deserialization.
I exposed a choice as there are pros and cons with each:
- A module that can be used at the field level with
#[serde(serialize_with = "as_py_object")] - A
SerdePyObject<T>wrapper which has its ownSerializeandDeserialize, implemented in terms of the sameas_py_objectmodule
(1) is transparent on the struct as it requires no changes to field types, whereas (2) is finer grained and can be applied like things: HashMap<String, SerdePyObject<MyThing>>.
In terms of implementation, serialization works as follows:
- Borrow a pointer from the
PyObject - Write a struct with a specially named
[u8]field like{ "__pyobject_ptr": [ /* 8 pointer bytes go here */ ] }
Deserialization works by looking for the specially named field and treating it as a pointer.
I would certainly appreciate this. My use case is as follows:
- Define a rust enum that can be exposed to python using the pyclass attribute
- Include that enum in a rust struct
- Use pythonize to convert struct to python dict
Example:
use pyo3::prelude::*;
#[pyclass]
enum E {
Foo,
Bar,
}
#[derive(Serialize)]
struct S {
other_field: String
enum_field: E,
}
let s = S {
other_field: "potato".to_owned(),
enum_field: E:Foo,
}
pythonize::pythonize(py, &s)
Then in python, this results in a str for the enum field, which can't be compared with the strongly-typed E.Foo.
out = {'other_field': 'potato', 'enum_field': 'Foo'}
from rust_module import E
E.Foo == out['enum_field'] # False :(
At the moment I'm too busy to look into this myself; contributions are welcome. The proposal by @1tgr sounds like it could work as an opt-in mechanism!
(I think to have something work automatically would require specialization, though I haven't thought too hard!)