diff --git a/capnp/lib/capnp.pyx b/capnp/lib/capnp.pyx index 564edbd..8b10804 100644 --- a/capnp/lib/capnp.pyx +++ b/capnp/lib/capnp.pyx @@ -845,6 +845,9 @@ cdef class _MessageSize: self.word_count = word_count self.cap_count = cap_count +def _struct_reducer(schema_id, data): + return _global_schema_parser.modules_by_id[schema_id].from_bytes(data) + cdef class _DynamicStructReader: """Reads Cap'n Proto structs @@ -924,6 +927,9 @@ cdef class _DynamicStructReader: size = self.thisptr.totalSize() return _MessageSize(size.wordCount, size.capCount) + def __reduce__(self): + return _struct_reducer, (self.schema.node.id, self.as_builder().to_bytes()) + cdef class _DynamicStructBuilder: """Builds Cap'n Proto structs @@ -1179,6 +1185,9 @@ cdef class _DynamicStructBuilder: size = self.thisptr.totalSize() return _MessageSize(size.wordCount, size.capCount) + def __reduce__(self): + return _struct_reducer, (self.schema.node.id, self.to_bytes()) + cdef class _DynamicStructPipeline: """Reads Cap'n Proto structs @@ -2322,8 +2331,11 @@ cdef class SchemaParser: Do not use this class unless you're sure you know what you're doing. Use the convenience method :func:`load` instead. """ cdef C_SchemaParser * thisptr + cdef public dict modules_by_id + def __cinit__(self): self.thisptr = new C_SchemaParser() + self.modules_by_id = {} def __dealloc__(self): del self.thisptr @@ -2381,6 +2393,8 @@ cdef class SchemaParser: nodeProto = nodeSchema.get_proto() module._nodeProto = nodeProto + self.modules_by_id[nodeProto.id] = module + for node in nodeProto.nestedNodes: local_module = _ModuleType(node.name)