From ea1f22e5c6d763886189f8250997b867ea466735 Mon Sep 17 00:00:00 2001 From: Jason Paryani Date: Sun, 25 Aug 2013 16:41:37 -0700 Subject: [PATCH 1/4] Fix new error with DynamicValue.Builder no longer being copyable --- capnp/capnp.pyx | 49 ++++++++++----------------------------------- capnp/capnp_cpp.pxd | 8 ++++---- 2 files changed, 15 insertions(+), 42 deletions(-) diff --git a/capnp/capnp.pyx b/capnp/capnp.pyx index 46b259b..fab0831 100644 --- a/capnp/capnp.pyx +++ b/capnp/capnp.pyx @@ -134,13 +134,15 @@ cdef class _DynamicListBuilder: # self.thisptr._init(size) # return self + cpdef _get(self, index) except +ValueError: + return toPython(self.thisptr[index], self._parent) + def __getitem__(self, index): size = self.thisptr.size() if index >= size: raise IndexError('Out of bounds') index = index % size - temp = self.thisptr[index] - return toPython(temp, self._parent) + return self._get(index) def _setitem(self, index, valid_values value): cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value) @@ -242,39 +244,7 @@ cdef class _DynamicValueReader: else: raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library") - -cdef int getType(C_DynamicValue.Builder & self): - return self.getType() - -cdef toPython(C_DynamicValue.Builder & self, object parent): - cdef int type = getType(self) - if type == capnp.TYPE_BOOL: - return self.asBool() - elif type == capnp.TYPE_INT: - return self.asInt() - elif type == capnp.TYPE_UINT: - return self.asUint() - elif type == capnp.TYPE_FLOAT: - return self.asDouble() - elif type == capnp.TYPE_TEXT: - return self.asText()[:] - elif type == capnp.TYPE_DATA: - temp = self.asData() - return (temp.begin())[:temp.size()] - elif type == capnp.TYPE_LIST: - return list(_DynamicListBuilder()._init(self.asList(), parent)) - elif type == capnp.TYPE_STRUCT: - return _DynamicStructBuilder()._init(self.asStruct(), parent) - elif type == capnp.TYPE_ENUM: - return fixMaybe(self.asEnum().getEnumerant()).getProto().getName().cStr() - elif type == capnp.TYPE_VOID: - return None - elif type == capnp.TYPE_UNKOWN: - raise ValueError("Cannot convert type to Python. Type is unknown by capnproto library") - else: - raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library") - -cdef toPythonByValue(C_DynamicValue.Builder self, object parent): +cdef toPython(C_DynamicValue.Builder self, object parent): cdef int type = self.getType() if type == capnp.TYPE_BOOL: return self.asBool() @@ -330,9 +300,12 @@ cdef class _DynamicStructBuilder: self._parent = parent return self - def __getattr__(self, field): + cpdef _get(self, field) except +ValueError: return toPython(self.thisptr.get(field), self._parent) + def __getattr__(self, field): + return self._get(field) + cdef _setattrInt(self, field, value): cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value) self.thisptr.set(field, temp) @@ -373,9 +346,9 @@ cdef class _DynamicStructBuilder: cpdef init(self, field, size=None) except +ValueError: if size is None: - return toPythonByValue(self.thisptr.init(field), self._parent) + return toPython(self.thisptr.init(field), self._parent) else: - return toPythonByValue(self.thisptr.init(field, size), self._parent) + return toPython(self.thisptr.init(field, size), self._parent) # cpdef which(self): # try: diff --git a/capnp/capnp_cpp.pxd b/capnp/capnp_cpp.pxd index 6ef4d98..4ed5917 100644 --- a/capnp/capnp_cpp.pxd +++ b/capnp/capnp_cpp.pxd @@ -99,7 +99,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp": StructSchema getSchema() Maybe[StructSchema.Field] which() cppclass Builder: - DynamicValueForward.Builder get(char *) except +ValueError + DynamicValueForward.Builder get(char *) bint has(char *) except +ValueError void set(char *, DynamicValueForward.Reader&) except +ValueError DynamicValueForward.Builder init(char *, uint size) @@ -121,10 +121,10 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp": DynamicValueForward.Reader operator[](uint) except +ValueError uint size() cppclass Builder: - DynamicValueForward.Builder operator[](uint) except +ValueError + DynamicValueForward.Builder operator[](uint) uint size() - void set(uint index, DynamicValueForward.Reader& value) - DynamicValueForward.Builder init(uint index, uint size) + void set(uint index, DynamicValueForward.Reader& value) except +ValueError + DynamicValueForward.Builder init(uint index, uint size) except +ValueError cdef cppclass DynamicValue: cppclass Reader: From c6250962e68021eef5f67761c5302ecc4aa05236 Mon Sep 17 00:00:00 2001 From: Jason Paryani Date: Sun, 25 Aug 2013 17:07:08 -0700 Subject: [PATCH 2/4] Add handling of constants in schemas --- capnp/capnp.pyx | 19 ++++++++++++++++--- capnp/capnp_cpp.pxd | 4 ++++ capnp/schema_cpp.pxd | 12 ++++++++++++ examples/addressbook.capnp | 2 ++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/capnp/capnp.pyx b/capnp/capnp.pyx index fab0831..e219fa6 100644 --- a/capnp/capnp.pyx +++ b/capnp/capnp.pyx @@ -87,6 +87,12 @@ cdef class _NodeReader: property nestedNodes: def __get__(self): return _List_NestedNode_Reader()._init(self.thisptr.getNestedNodes()) + property isStruct: + def __get__(self): + return self.thisptr.isStruct() + property isConst: + def __get__(self): + return self.thisptr.isConst() cdef class _NestedNodeReader: cdef C_Node.NestedNode.Reader thisptr @@ -364,6 +370,9 @@ cdef class Schema: self.thisptr = other return self + cpdef asConstValue(self): + return _DynamicValueReader()._init(self.thisptr.asConst(), self).toPython() + cpdef asStruct(self): return StructSchema()._init(self.thisptr.asStruct()) @@ -385,6 +394,9 @@ cdef class ParsedSchema: self.thisptr = other return self + cpdef asConstValue(self): + return _DynamicValueReader()._init(self.thisptr.asConst(), self).toPython() + cpdef asStruct(self): return StructSchema()._init(self.thisptr.asStruct()) @@ -506,10 +518,11 @@ def _load(nodeSchema, module): module.__dict__[node.name] = local_module schema = nodeSchema.getNested(node.name) - try: + proto = schema.getProto() + if proto.isStruct: local_module.Schema = schema.asStruct() - except: - pass + elif proto.isConst: + module.__dict__[node.name] = schema.asConstValue() _load(schema, local_module) diff --git a/capnp/capnp_cpp.pxd b/capnp/capnp_cpp.pxd index 4ed5917..efa3f3a 100644 --- a/capnp/capnp_cpp.pxd +++ b/capnp/capnp_cpp.pxd @@ -29,6 +29,7 @@ cdef extern from "capnp/schema.h" namespace " ::capnp": Node.Reader getProto() except + StructSchema asStruct() except + EnumSchema asEnum() except + + ConstSchema asConst() except + Schema getDependency(uint64_t id) except + #InterfaceSchema asInterface() const; @@ -64,6 +65,9 @@ cdef extern from "capnp/schema.h" namespace " ::capnp": Enumerant getEnumerantByName(char * name) Node.Reader getProto() + cdef cppclass ConstSchema: + pass + cdef extern from "capnp/schema-loader.h" namespace " ::capnp": cdef cppclass SchemaLoader: SchemaLoader() diff --git a/capnp/schema_cpp.pxd b/capnp/schema_cpp.pxd index 41157cf..c779541 100644 --- a/capnp/schema_cpp.pxd +++ b/capnp/schema_cpp.pxd @@ -438,6 +438,12 @@ cdef extern from "capnp/schema.capnp.h" namespace " ::capnp::schema": UInt64 getScopeId() List[Node.Node.NestedNode].Reader getNestedNodes() UInt64 getId() + bint isFile() + bint isStruct() + bint isEnum() + bint isInterface() + bint isConst() + bint isAnnotation() cppclass Builder: Node.Body getBody() @@ -452,6 +458,12 @@ cdef extern from "capnp/schema.capnp.h" namespace " ::capnp::schema": List[Node.Node.NestedNode].Builder initNestedNodes(int) UInt64 getId() void setId(UInt64) + bint isFile() + bint isStruct() + bint isEnum() + bint isInterface() + bint isConst() + bint isAnnotation() cdef cppclass AnnotationNode: diff --git a/examples/addressbook.capnp b/examples/addressbook.capnp index 02e626a..e1cd77c 100644 --- a/examples/addressbook.capnp +++ b/examples/addressbook.capnp @@ -1,5 +1,7 @@ @0x934efea7f017fff0; +const qux :UInt32 = 123; + struct Person { id @0 :UInt32; name @1 :Text; From 2bfc0e0d9a4b5bdeea3ada028dbb6b7b29eebba7 Mon Sep 17 00:00:00 2001 From: Jason Paryani Date: Sun, 25 Aug 2013 17:51:23 -0700 Subject: [PATCH 3/4] update docs for constants --- docs/quickstart.rst | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index cf632d8..a185de3 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -16,7 +16,9 @@ First you need to import the library:: Then you can load the Cap'n Proto schema with:: - capnp.load('addressbook.capnp') + addressbook = capnp.load('addressbook.capnp') + +Note that we assign the loaded module to a variable, named `addressbook`. We'll use this from now on to access the Cap'n Proto schema, ie. when we need to get a Struct's class or accessing const values. You can also provide an absolute path to the Cap'n Proto schema you wish to load. Otherwise, it will only look in the current working directory. @@ -25,6 +27,8 @@ For future reference, here is the Cap'n Proto schema. Also available in the gith # addressbook.capnp 0x934efea7f017fff0; + const qux :UInt32 = 123; + struct Person { id @0 :UInt32; name @1 :Text; @@ -55,6 +59,14 @@ For future reference, here is the Cap'n Proto schema. Also available in the gith people @0 :List(Person); } +Const values +~~~~~~~~~~~~~~ + +Const values show up just as you'd expect under the loaded schema. For example:: + + print addressbook.qux + # 123 + Build a message ------------------ From ca76d66fdd15c8a0b7f3685dcad15c24935f311a Mon Sep 17 00:00:00 2001 From: Jason Paryani Date: Sun, 25 Aug 2013 17:52:44 -0700 Subject: [PATCH 4/4] Bump version for v0.3.5 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 30473ac..6451e72 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ import os MAJOR = 0 MINOR = 3 -MICRO = 4 +MICRO = 5 VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)