Fixed a bug with unions. Also made README better`
This commit is contained in:
27
README.md
27
README.md
@@ -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
|
||||||
73
capnp.pyx
73
capnp.pyx
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 +
|
||||||
|
|||||||
Reference in New Issue
Block a user