Fixed a bug with unions. Also made README better`

This commit is contained in:
Jason Paryani
2013-07-06 18:40:05 -07:00
parent 7b8de8bbfe
commit 259d1a46c1
3 changed files with 69 additions and 33 deletions

View File

@@ -1,2 +1,25 @@
capnpc-python-cpp #capnpc-python-cpp
=================
## Downloading
For now, this code is only on github, although I plan to put it up on PyPi at somepoint.
You can clone the repo like so:
git clone https://github.com/jparyani/capnpc-python-cpp.git
## Requirements
A system-wide installation of the Capnproto C++ library, compiled with the
-fpic flag. All you need to do is follow the official [installation docs](http://kentonv.github.io/capnproto/install.html)].
You also need a working version of the latest [Cython](http://cython.org/) installed. This is easily done with `pip install 'cython >= .19.1'
## Building and installation
`cd` into the repo directory and run `python setup.py install`
## Documentation/Example
At the moment, there is no documenation, but the library is almost a 1:1 clone of the [Capnproto C++ Library](http://kentonv.github.io/capnproto/cxx.html)
The following example should suffice to show off the differences:
TODO

View File

@@ -287,7 +287,7 @@ cdef class _DynamicUnionReader:
return _DynamicValueReader().init(self.thisptr.get()).toPython() return _DynamicValueReader().init(self.thisptr.get()).toPython()
def __getattr__(self, field): def __getattr__(self, field):
return self._get().toPython() return self._get().toPython() # TODO: check that the field is right?
cpdef which(self): cpdef which(self):
return fixMaybe(self.thisptr.which()).getProto().getOrdinal() return fixMaybe(self.thisptr.which()).getProto().getOrdinal()
@@ -299,7 +299,7 @@ cdef class _DynamicUnionBuilder:
return self return self
def __getattr__(self, field): def __getattr__(self, field):
return toPython(self.thisptr.get()) return toPython(self.thisptr.get()) # TODO: check that the field is right?
def _setattr(self, field, valid_values value): def _setattr(self, field, valid_values value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value)
@@ -423,51 +423,64 @@ import re
import schema import schema
import subprocess import subprocess
def _load(m, n, loader, name = None, isUnion = False): def _load(module, node, loader, name = None, isUnion = False):
if name is None: if name is None:
name = n.displayName name = node.displayName
local_m = m
local_module = module
for sub_name in re.split('[:.]', name): for sub_name in re.split('[:.]', name):
new_m = local_m.__dict__.get(sub_name, ModuleType(sub_name)) new_m = local_module.__dict__.get(sub_name, ModuleType(sub_name))
local_m.__dict__[sub_name] = new_m local_module.__dict__[sub_name] = new_m
local_m = new_m local_module = new_m
for nestedNode in n.nestedNodes:
for nestedNode in node.nestedNodes:
s = loader.get(nestedNode.id) s = loader.get(nestedNode.id)
_load(m, s.getProto(), loader, name + ':' + nestedNode.name) _load(module, s.getProto(), loader, name + ':' + nestedNode.name)
body = n.body
body = node.body
which = body.which() which = body.which()
if which == schema.Node.Body.Which.enumNode: if which == schema.Node.Body.Which.enumNode:
enum = body.enumNode enum = body.enumNode
local_m.Which = make_enum(name+':Which', **{upper_and_under(e.name) : e.codeOrder for e in enum.enumerants})
local_module.Which = make_enum(name+':Which', **{upper_and_under(e.name) : e.codeOrder for e in enum.enumerants})
elif which == schema.Node.Body.Which.structNode: elif which == schema.Node.Body.Which.structNode:
struct = body.structNode struct = body.structNode
for member in struct.members: for member in struct.members:
if member.body.which() == schema.StructNode.Member.Body.Which.unionMember: if member.body.which() == schema.StructNode.Member.Body.Which.unionMember:
sub_name = capitalize(member.name) sub_name = capitalize(member.name)
new_m = local_m.__dict__.get(sub_name, ModuleType(sub_name)) new_m = local_module.__dict__.get(sub_name, ModuleType(sub_name))
local_m.__dict__[sub_name] = new_m local_module.__dict__[sub_name] = new_m
new_m.Which = make_enum(sub_name+':Which', **{upper_and_under(e.name) : e.ordinal for e in struct.members})
return local_m new_m.Which = make_enum(sub_name+':Which', **{upper_and_under(e.name) : e.ordinal for e in member.body.unionMember.members})
return local_module
def load(file_name, cat_path='/bin/cat'): def load(file_name, cat_path='/bin/cat'):
p = subprocess.Popen(['capnpc', '-o'+cat_path, file_name], stdout=subprocess.PIPE) p = subprocess.Popen(['capnpc', '-o'+cat_path, file_name], stdout=subprocess.PIPE)
ret = p.wait() retcode = p.wait()
if ret != 0: if retcode != 0:
raise RuntimeError("capnpc failed for some reason") raise RuntimeError("capnpc failed for some reason")
r = schema.StreamFdMessageReader(p.stdout.fileno())
c = r.getRootCodeGeneratorRequest() reader = schema.StreamFdMessageReader(p.stdout.fileno())
m = ModuleType(file_name) request = reader.getRootCodeGeneratorRequest()
l = SchemaLoader() module = ModuleType(file_name)
m._loader = l loader = SchemaLoader()
for node in c.nodes:
s = l.load(node) module._loader = loader
for node in c.nodes:
s = l.load(node) for node in request.nodes:
local_m = _load(m, node, l) loader.load(node)
for node in request.nodes:
s = loader.load(node)
local_module = _load(module, node, loader)
try: try:
s = s.asStruct() s = s.asStruct()
local_m.Schema = s local_module.Schema = s
except: pass except: pass
return m return module

View File

@@ -13,7 +13,7 @@ cdef extern from "kj/common.h" namespace "::kj":
cdef extern from "capnp/schema.h" namespace "::capnp": cdef extern from "capnp/schema.h" namespace "::capnp":
cdef cppclass Schema: cdef cppclass Schema:
Node.Reader getProto() Node.Reader getProto() except +
StructSchema asStruct() except + StructSchema asStruct() except +
EnumSchema asEnum() except + EnumSchema asEnum() except +
Schema getDependency(uint64_t id) except + Schema getDependency(uint64_t id) except +