I'm writing a custom MessagePack serializer to add to an old Python project that uses MessagePack extensively. In particular, I often have lists of objects built up that I need to serialize all at once, but the GIL prevents this, so I want to use Rust to do it, and be fast in other ways besides.
I have already gotten fundamental Python types to serialize this way, but I want to serialize some of the custom classes that my Python app has, as well, and would prefer not to port those into Rust—even though pyO3 would make that easy to do, I'm nervous about adding a hard dependency on this Rust code, and would like a fallback to the standard Python MessagePack library.
So I started by writing a struct to represent a singleton:
struct PyFinalRule(PyAny);
unsafe impl PyTypeInfo for PyFinalRule {
const NAME: &'static str = "FinalRule";
const MODULE: Option<&'static str> = Option::Some("LiSE.util");
type AsRefTarget = PyAny;
fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject {
let modu = py.import("LiSE.util").unwrap();
let final_rule = modu.getattr("FinalRule").unwrap();
final_rule.get_type_ptr()
}
}
unsafe impl PyNativeType for PyFinalRule {}
I was expecting to be able to use PyFinalRule::is_type_of to check when a PyAny object is really an instance of FinalRule. Instead, PyFinalRule::is_type_of always returns false when passed the one instance of the FinalRule singleton. It returns true when passed the FinalRule type object, but that's not very useful, since the app serializes the instance and not the type object.
How do I get PyFinalRule::is_type_of to really check the type?
Here's what I ended up with for
type_object_raw:Adapted a bit from Adesoji Alu's answer.