diff --git a/capnp/capnp.pyx b/capnp/capnp.pyx index 9dc092e..b18a873 100644 --- a/capnp/capnp.pyx +++ b/capnp/capnp.pyx @@ -9,7 +9,7 @@ cimport cython cimport capnp_cpp as capnp cimport schema_cpp -from capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, fixMaybe, getEnumString, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan, DynamicObject as C_DynamicObject, WordArrayPtr +from capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, fixMaybe, getEnumString, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan, ObjectPointer as C_DynamicObject, WordArrayPtr from schema_cpp cimport Node as C_Node, EnumNode as C_EnumNode from cython.operator cimport dereference as deref @@ -382,7 +382,7 @@ cdef to_python_builder(C_DynamicValue.Builder self, object parent): elif type == capnp.TYPE_VOID: return None elif type == capnp.TYPE_OBJECT: - raise ValueError("Cannot convert type to Python. Type is 'Object', but is being used improperly. You can only get 'Object' types from a struct") + return _DynamicObjectBuilder()._init(self.asObject(), parent) elif type == capnp.TYPE_UNKNOWN: raise ValueError("Cannot convert type to Python. Type is unknown by capnproto library") else: @@ -620,20 +620,8 @@ cdef class _DynamicStructBuilder: cdef _get(self, field): cdef C_DynamicValue.Builder value = self.thisptr.get(field) - if value.getType() == capnp.TYPE_OBJECT: - return _DynamicObjectBuilder(field, self) - else: - return to_python_builder(value, self._parent) - - cpdef _get_object(self, field, schema): - cdef _StructSchema s - if hasattr(schema, 'schema'): - s = schema.schema - else: - s = schema - - return _DynamicStructBuilder()._init(self.thisptr.getObject(field, s.thisptr), self._parent) - + return to_python_builder(value, self._parent) + def __getattr__(self, field): return self._get(field) @@ -800,16 +788,24 @@ cdef class _DynamicObjectReader: else: s = schema - return _DynamicStructReader()._init(self.thisptr.as(s.thisptr), self._parent) + return _DynamicStructReader()._init(self.thisptr.getAs(s.thisptr), self._parent) cdef class _DynamicObjectBuilder: - cdef public object _field, _parent_struct - def __init__(self, field, parent_struct): - self._field = field - self._parent_struct = parent_struct + cdef C_DynamicObject.Builder * thisptr + cdef public object _parent + cdef _init(self, C_DynamicObject.Builder other, object parent): + self.thisptr = new C_DynamicObject.Builder(other) + self._parent = parent + return self cpdef as_struct(self, schema): - return self._parent_struct._get_object(self._field, schema) + cdef _StructSchema s + if hasattr(schema, 'schema'): + s = schema.schema + else: + s = schema + + return _DynamicStructBuilder()._init(self.thisptr.getAs(s.thisptr), self._parent) cdef class _Schema: cdef C_Schema thisptr diff --git a/capnp/capnp_cpp.pxd b/capnp/capnp_cpp.pxd index 9f27652..006d748 100644 --- a/capnp/capnp_cpp.pxd +++ b/capnp/capnp_cpp.pxd @@ -138,7 +138,14 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp": void adopt(char *, DynamicOrphan) except +ValueError DynamicOrphan disown(char *) DynamicStruct.Reader asReader() - DynamicStruct.Builder getObject(char *, StructSchema) + +cdef extern from "capnp/object.h" namespace " ::capnp": + cdef cppclass ObjectPointer: + cppclass Reader: + DynamicStruct.Reader getAs"getAs< ::capnp::DynamicStruct>"(StructSchema) + cppclass Builder: + Builder(Builder) + DynamicStruct.Builder getAs"getAs< ::capnp::DynamicStruct>"(StructSchema) cdef extern from "fixMaybe.h": EnumSchema.Enumerant fixMaybe(Maybe[EnumSchema.Enumerant]) except +ValueError @@ -150,13 +157,6 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp": uint16_t getRaw() Maybe[EnumSchema.Enumerant] getEnumerant() - cdef cppclass DynamicObject: - cppclass Reader: - DynamicStruct.Reader as(StructSchema schema) - cppclass Builder: - DynamicObject.Reader asReader() - # DynamicList::Reader as(ListSchema schema) const; - cdef cppclass DynamicList: cppclass Reader: DynamicValueForward.Reader operator[](uint) except +ValueError @@ -201,12 +201,11 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp": char * asText"as< ::capnp::Text>().cStr"() DynamicList.Reader asList"as< ::capnp::DynamicList>"() DynamicStruct.Reader asStruct"as< ::capnp::DynamicStruct>"() - DynamicObject.Reader asObject"as< ::capnp::DynamicObject>"() + ObjectPointer.Reader asObject"as< ::capnp::ObjectPointer>"() DynamicEnum asEnum"as< ::capnp::DynamicEnum>"() Data.Reader asData"as< ::capnp::Data>"() cppclass Builder: - Builder() Type getType() int64_t asInt"as"() uint64_t asUint"as"() @@ -215,6 +214,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp": char * asText"as< ::capnp::Text>().cStr"() DynamicList.Builder asList"as< ::capnp::DynamicList>"() DynamicStruct.Builder asStruct"as< ::capnp::DynamicStruct>"() + ObjectPointer.Builder asObject"as< ::capnp::ObjectPointer>"() DynamicEnum asEnum"as< ::capnp::DynamicEnum>"() Data.Builder asData"as< ::capnp::Data>"()