Change naming for functions to conform to PEP 8. Also deprecate old

read/write api.
This commit is contained in:
Jason Paryani
2013-09-01 20:10:57 -07:00
parent 6fcdf841e4
commit 1317527893
9 changed files with 270 additions and 257 deletions

View File

@@ -42,19 +42,22 @@ There is some basic documentation [here](http://jparyani.github.io/pycapnp/).
The examples directory has one example that shows off the capabilities quite nicely. Here it is, reproduced: The examples directory has one example that shows off the capabilities quite nicely. Here it is, reproduced:
```python ```python
from __future__ import print_function
import os
import capnp import capnp
addressbook = capnp.load('addressbook.capnp')
def writeAddressBook(fd): this_dir = os.path.dirname(__file__)
message = capnp.MallocMessageBuilder() addressbook = capnp.load(os.path.join(this_dir, 'addressbook.capnp'))
addressBook = message.initRoot(addressbook.AddressBook)
people = addressBook.initPeople(2) def writeAddressBook(file):
addresses = addressbook.AddressBook.new_message()
people = addresses.init('people', 2)
alice = people[0] alice = people[0]
alice.id = 123 alice.id = 123
alice.name = 'Alice' alice.name = 'Alice'
alice.email = 'alice@example.com' alice.email = 'alice@example.com'
alicePhones = alice.initPhones(1) alicePhones = alice.init('phones', 1)
alicePhones[0].number = "555-1212" alicePhones[0].number = "555-1212"
alicePhones[0].type = 'mobile' alicePhones[0].type = 'mobile'
alice.employment.school = "MIT" alice.employment.school = "MIT"
@@ -63,29 +66,26 @@ def writeAddressBook(fd):
bob.id = 456 bob.id = 456
bob.name = 'Bob' bob.name = 'Bob'
bob.email = 'bob@example.com' bob.email = 'bob@example.com'
bobPhones = bob.initPhones(2) bobPhones = bob.init('phones', 2)
bobPhones[0].number = "555-4567" bobPhones[0].number = "555-4567"
bobPhones[0].type = 'home' bobPhones[0].type = 'home'
bobPhones[1].number = "555-7654" bobPhones[1].number = "555-7654"
bobPhones[1].type = 'work' bobPhones[1].type = 'work'
bob.employment.unemployed = None bob.employment.unemployed = None
capnp.writePackedMessageToFd(fd, message) addresses.write(file)
f = open('example', 'w')
writeAddressBook(f.fileno())
def printAddressBook(fd): def printAddressBook(file):
message = capnp.PackedFdMessageReader(f.fileno()) addresses = addressbook.AddressBook.read(file)
addressBook = message.getRoot(addressbook.AddressBook)
for person in addressBook.people: for person in addresses.people:
print person.name, ':', person.email print(person.name, ':', person.email)
for phone in person.phones: for phone in person.phones:
print phone.type, ':', phone.number print(phone.type, ':', phone.number)
which = person.employment.which() which = person.employment.which()
print which print(which)
if which == 'unemployed': if which == 'unemployed':
print('unemployed') print('unemployed')
@@ -95,10 +95,15 @@ def printAddressBook(fd):
print('student at:', person.employment.school) print('student at:', person.employment.school)
elif which == 'selfEmployed': elif which == 'selfEmployed':
print('self employed') print('self employed')
print print()
f = open('example', 'r')
printAddressBook(f.fileno()) if __name__ == '__main__':
f = open('example', 'w')
writeAddressBook(f)
f = open('example', 'r')
printAddressBook(f)
``` ```
## Common Problems ## Common Problems

View File

@@ -33,5 +33,5 @@ Example Usage::
""" """
from .version import version as __version__ from .version import version as __version__
from .capnp import * from .capnp import *
from .capnp import _DynamicStructReader, _DynamicStructBuilder, _DynamicResizableListBuilder, _DynamicListReader, _DynamicListBuilder, _DynamicOrphan, _DynamicResizableListBuilder from .capnp import _DynamicStructReader, _DynamicStructBuilder, _DynamicResizableListBuilder, _DynamicListReader, _DynamicListBuilder, _DynamicOrphan, _DynamicResizableListBuilder, _MallocMessageBuilder, _PackedFdMessageReader, _StreamFdMessageReader, _write_message_to_fd, _write_packed_message_to_fd
del capnp del capnp

View File

@@ -152,7 +152,7 @@ cdef class _DynamicListReader:
if index >= size: if index >= size:
raise IndexError('Out of bounds') raise IndexError('Out of bounds')
index = index % size index = index % size
return toPythonReader(self.thisptr[index], self._parent) return to_python_reader(self.thisptr[index], self._parent)
def __len__(self): def __len__(self):
return self.thisptr.size() return self.thisptr.size()
@@ -174,7 +174,7 @@ cdef class _DynamicResizableListBuilder:
... ...
person = addressbook.Person.newMessage() person = addressbook.Person.newMessage()
phones = person.initResizableList('phones') # This returns a _DynamicResizableListBuilder phones = person.init_resizable_list('phones') # This returns a _DynamicResizableListBuilder
phone = phones.add() phone = phones.add()
phone.number = 'foo' phone.number = 'foo'
@@ -184,7 +184,7 @@ cdef class _DynamicResizableListBuilder:
people.finish() people.finish()
f = open('example', 'w') f = open('example', 'w')
person.writeTo(f) person.write(f)
""" """
cdef public object _parent, _message, _field, _schema cdef public object _parent, _message, _field, _schema
cdef public list _list cdef public list _list
@@ -203,7 +203,7 @@ cdef class _DynamicResizableListBuilder:
:rtype: :class:`_DynamicStructBuilder` :rtype: :class:`_DynamicStructBuilder`
""" """
orphan = self._message.newOrphan(self._schema) orphan = self._message.new_orphan(self._schema)
orphan_val = orphan.get() orphan_val = orphan.get()
self._list.append((orphan, orphan_val)) self._list.append((orphan, orphan_val))
return orphan_val return orphan_val
@@ -254,7 +254,7 @@ cdef class _DynamicListBuilder:
return self return self
cdef _get(self, index) except +ValueError: cdef _get(self, index) except +ValueError:
return toPython(self.thisptr[index], self._parent) return to_python_builder(self.thisptr[index], self._parent)
def __getitem__(self, index): def __getitem__(self, index):
size = self.thisptr.size() size = self.thisptr.size()
@@ -325,7 +325,7 @@ cdef class _List_NestedNode_Reader:
def __len__(self): def __len__(self):
return self.thisptr.size() return self.thisptr.size()
cdef toPythonReader(C_DynamicValue.Reader self, object parent): cdef to_python_reader(C_DynamicValue.Reader self, object parent):
cdef int type = self.getType() cdef int type = self.getType()
if type == capnp.TYPE_BOOL: if type == capnp.TYPE_BOOL:
return self.asBool() return self.asBool()
@@ -353,7 +353,7 @@ cdef toPythonReader(C_DynamicValue.Reader self, object parent):
else: else:
raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library") raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library")
cdef toPython(C_DynamicValue.Builder self, object parent): cdef to_python_builder(C_DynamicValue.Builder self, object parent):
cdef int type = self.getType() cdef int type = self.getType()
if type == capnp.TYPE_BOOL: if type == capnp.TYPE_BOOL:
return self.asBool() return self.asBool()
@@ -381,10 +381,10 @@ cdef toPython(C_DynamicValue.Builder self, object parent):
else: else:
raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library") raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library")
cdef C_DynamicValue.Reader _extractDynamicStructBuilder(_DynamicStructBuilder value): cdef C_DynamicValue.Reader _extract_dynamic_struct_builder(_DynamicStructBuilder value):
return C_DynamicValue.Reader(value.thisptr.asReader()) return C_DynamicValue.Reader(value.thisptr.asReader())
cdef C_DynamicValue.Reader _extractDynamicStructReader(_DynamicStructReader value): cdef C_DynamicValue.Reader _extract_dynamic_struct_reader(_DynamicStructReader value):
return C_DynamicValue.Reader(value.thisptr) return C_DynamicValue.Reader(value.thisptr)
cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent): cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent):
@@ -407,16 +407,16 @@ cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent):
temp = C_DynamicValue.Reader(<char*>value) temp = C_DynamicValue.Reader(<char*>value)
thisptr.set(field, temp) thisptr.set(field, temp)
elif value_type is list: elif value_type is list:
builder = toPython(thisptr.init(field, len(value)), parent) builder = to_python_builder(thisptr.init(field, len(value)), parent)
for (i, v) in enumerate(value): for (i, v) in enumerate(value):
builder[i] = v builder[i] = v
elif value is None: elif value is None:
temp = C_DynamicValue.Reader(VOID) temp = C_DynamicValue.Reader(VOID)
thisptr.set(field, temp) thisptr.set(field, temp)
elif value_type is _DynamicStructBuilder: elif value_type is _DynamicStructBuilder:
thisptr.set(field, _extractDynamicStructBuilder(value)) thisptr.set(field, _extract_dynamic_struct_builder(value))
elif value_type is _DynamicStructReader: elif value_type is _DynamicStructReader:
thisptr.set(field, _extractDynamicStructReader(value)) thisptr.set(field, _extract_dynamic_struct_reader(value))
else: else:
raise ValueError("Non primitive type") raise ValueError("Non primitive type")
@@ -438,7 +438,7 @@ cdef class _DynamicStructReader:
return self return self
def __getattr__(self, field): def __getattr__(self, field):
return toPythonReader(self.thisptr.get(field), self._parent) return to_python_reader(self.thisptr.get(field), self._parent)
def _has(self, field): def _has(self, field):
return self.thisptr.has(field) return self.thisptr.has(field)
@@ -500,10 +500,10 @@ cdef class _DynamicStructBuilder:
self._isRoot = isRoot self._isRoot = isRoot
return self return self
def writeTo(self, file): def write(self, file):
"""Writes the struct's containing message to the given file object in unpacked binary format. """Writes the struct's containing message to the given file object in unpacked binary format.
This is a shortcut for calling capnp.writeMessageToFd(). This can only be called on the This is a shortcut for calling capnp._write_message_to_fd(). This can only be called on the
message's root struct. message's root struct.
:type file: file :type file: file
@@ -514,13 +514,13 @@ cdef class _DynamicStructBuilder:
:Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct. :Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct.
""" """
if not self._isRoot: if not self._isRoot:
raise ValueError("You can only call writeTo() on the message's root struct.") raise ValueError("You can only call write() on the message's root struct.")
writeMessageToFd(file.fileno(), self._parent) _write_message_to_fd(file.fileno(), self._parent)
def writePackedTo(self, file): def write_packed(self, file):
"""Writes the struct's containing message to the given file object in packed binary format. """Writes the struct's containing message to the given file object in packed binary format.
This is a shortcut for calling capnp.writePackedMessageToFd(). This can only be called on This is a shortcut for calling capnp._write_packed_message_to_fd(). This can only be called on
the message's root struct. the message's root struct.
:type file: file :type file: file
@@ -531,11 +531,11 @@ cdef class _DynamicStructBuilder:
:Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct. :Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct.
""" """
if not self._isRoot: if not self._isRoot:
raise ValueError("You can only call writeTo() on the message's root struct.") raise ValueError("You can only call write() on the message's root struct.")
writePackedMessageToFd(file.fileno(), self._parent) _write_packed_message_to_fd(file.fileno(), self._parent)
cdef _get(self, field) except +ValueError: cdef _get(self, field) except +ValueError:
return toPython(self.thisptr.get(field), self._parent) return to_python_builder(self.thisptr.get(field), self._parent)
def __getattr__(self, field): def __getattr__(self, field):
return self._get(field) return self._get(field)
@@ -562,11 +562,11 @@ cdef class _DynamicStructBuilder:
:Raises: :exc:`exceptions.AttributeError` if the field isn't in this struct :Raises: :exc:`exceptions.AttributeError` if the field isn't in this struct
""" """
if size is None: if size is None:
return toPython(self.thisptr.init(field), self._parent) return to_python_builder(self.thisptr.init(field), self._parent)
else: else:
return toPython(self.thisptr.init(field, size), self._parent) return to_python_builder(self.thisptr.init(field, size), self._parent)
cpdef initResizableList(self, field): cpdef init_resizable_list(self, field):
"""Method for initializing fields that are of type list (of structs) """Method for initializing fields that are of type list (of structs)
This version of init returns a :class:`_DynamicResizableListBuilder` that allows you to add members one at a time (ie. if you don't know the size for sure). This is only meant for lists of Cap'n Proto objects, since for primitive types you can just define a normal python list and fill it yourself. This version of init returns a :class:`_DynamicResizableListBuilder` that allows you to add members one at a time (ie. if you don't know the size for sure). This is only meant for lists of Cap'n Proto objects, since for primitive types you can just define a normal python list and fill it yourself.
@@ -630,7 +630,7 @@ cdef class _DynamicStructBuilder:
""" """
return _DynamicOrphan()._init(self.thisptr.disown(field), self._parent) return _DynamicOrphan()._init(self.thisptr.disown(field), self._parent)
cpdef asReader(self): cpdef as_reader(self):
"""A method for casting this Builder to a Reader """A method for casting this Builder to a Reader
Don't use this method unless you know what you're doing. Don't use this method unless you know what you're doing.
@@ -673,7 +673,7 @@ cdef class _DynamicOrphan:
Use this DynamicValue to set fields inside the orphan Use this DynamicValue to set fields inside the orphan
""" """
return toPython(self.thisptr.get(), self._parent) return to_python_builder(self.thisptr.get(), self._parent)
def __str__(self): def __str__(self):
return str(self.get()) return str(self.get())
@@ -687,16 +687,16 @@ cdef class _Schema:
self.thisptr = other self.thisptr = other
return self return self
cpdef asConstValue(self): cpdef as_const_value(self):
return toPythonReader(<C_DynamicValue.Reader>self.thisptr.asConst(), self) return to_python_reader(<C_DynamicValue.Reader>self.thisptr.asConst(), self)
cpdef asStruct(self): cpdef as_struct(self):
return _StructSchema()._init(self.thisptr.asStruct()) return _StructSchema()._init(self.thisptr.asStruct())
cpdef getDependency(self, id): cpdef get_dependency(self, id):
return _Schema()._init(self.thisptr.getDependency(id)) return _Schema()._init(self.thisptr.getDependency(id))
cpdef getProto(self): cpdef get_proto(self):
return _NodeReader().init(self.thisptr.getProto()) return _NodeReader().init(self.thisptr.getProto())
cdef class _StructSchema: cdef class _StructSchema:
@@ -732,16 +732,16 @@ cdef class _ParsedSchema:
self.thisptr = other self.thisptr = other
return self return self
cpdef asConstValue(self): cpdef as_const_value(self):
return toPythonReader(<C_DynamicValue.Reader>self.thisptr.asConst(), self) return to_python_reader(<C_DynamicValue.Reader>self.thisptr.asConst(), self)
cpdef asStruct(self): cpdef as_struct(self):
return _StructSchema()._init(self.thisptr.asStruct()) return _StructSchema()._init(self.thisptr.asStruct())
cpdef getDependency(self, id): cpdef get_dependency(self, id):
return _Schema()._init(self.thisptr.getDependency(id)) return _Schema()._init(self.thisptr.getDependency(id))
cpdef getProto(self): cpdef get_proto(self):
return _NodeReader().init(self.thisptr.getProto()) return _NodeReader().init(self.thisptr.getProto())
cpdef getNested(self, name): cpdef getNested(self, name):
@@ -759,7 +759,7 @@ cdef class SchemaParser:
def __dealloc__(self): def __dealloc__(self):
del self.thisptr del self.thisptr
def _parseDiskFile(self, displayName, diskPath, imports): def _parse_disk_file(self, displayName, diskPath, imports):
cdef StringPtr * importArray = <StringPtr *>malloc(sizeof(StringPtr) * len(imports)) cdef StringPtr * importArray = <StringPtr *>malloc(sizeof(StringPtr) * len(imports))
for i in range(len(imports)): for i in range(len(imports)):
@@ -807,7 +807,7 @@ cdef class SchemaParser:
""" """
def _load(nodeSchema, module): def _load(nodeSchema, module):
module._nodeSchema = nodeSchema module._nodeSchema = nodeSchema
nodeProto = nodeSchema.getProto() nodeProto = nodeSchema.get_proto()
module._nodeProto = nodeProto module._nodeProto = nodeProto
for node in nodeProto.nestedNodes: for node in nodeProto.nestedNodes:
@@ -815,23 +815,23 @@ cdef class SchemaParser:
module.__dict__[node.name] = local_module module.__dict__[node.name] = local_module
schema = nodeSchema.getNested(node.name) schema = nodeSchema.getNested(node.name)
proto = schema.getProto() proto = schema.get_proto()
if proto.isStruct: if proto.isStruct:
local_module.schema = schema.asStruct() local_module.schema = schema.as_struct()
def readFrom(file): def read(file):
reader = StreamFdMessageReader(file.fileno()) reader = _StreamFdMessageReader(file.fileno())
return reader.getRoot(local_module) return reader.get_root(local_module)
def readPackedFrom(file): def read_packed(file):
reader = PackedFdMessageReader(file.fileno()) reader = _PackedFdMessageReader(file.fileno())
return reader.getRoot(local_module) return reader.get_root(local_module)
def newMessage(): def new_message():
builder = MallocMessageBuilder() builder = _MallocMessageBuilder()
return builder.initRoot(local_module) return builder.init_root(local_module)
local_module.readFrom = readFrom local_module.read = read
local_module.readPackedFrom = readPackedFrom local_module.read_packed = read_packed
local_module.newMessage = newMessage local_module.new_message = new_message
elif proto.isConst: elif proto.isConst:
module.__dict__[node.name] = schema.asConstValue() module.__dict__[node.name] = schema.as_const_value()
_load(schema, local_module) _load(schema, local_module)
@@ -843,12 +843,12 @@ cdef class SchemaParser:
module._parser = parser module._parser = parser
fileSchema = parser._parseDiskFile(display_name, file_name, imports) fileSchema = parser._parse_disk_file(display_name, file_name, imports)
_load(fileSchema, module) _load(fileSchema, module)
return module return module
cdef class MessageBuilder: cdef class _MessageBuilder:
"""An abstract base class for building Cap'n Proto messages """An abstract base class for building Cap'n Proto messages
.. warning:: Don't ever instantiate this class directly. It is only used for inheritance. .. warning:: Don't ever instantiate this class directly. It is only used for inheritance.
@@ -860,7 +860,7 @@ cdef class MessageBuilder:
def __init__(self): def __init__(self):
raise NotImplementedError("This is an abstract base class. You should use MallocMessageBuilder instead") raise NotImplementedError("This is an abstract base class. You should use MallocMessageBuilder instead")
cpdef initRoot(self, schema): cpdef init_root(self, schema):
"""A method for instantiating Cap'n Proto structs """A method for instantiating Cap'n Proto structs
You will need to pass in a schema to specify which struct to You will need to pass in a schema to specify which struct to
@@ -868,7 +868,7 @@ cdef class MessageBuilder:
addressbook = capnp.load('addressbook.capnp') addressbook = capnp.load('addressbook.capnp')
... ...
person = message.initRoot(addressbook.Person) person = message.init_root(addressbook.Person)
:type schema: Schema :type schema: Schema
:param schema: A Cap'n proto schema specifying which struct to instantiate :param schema: A Cap'n proto schema specifying which struct to instantiate
@@ -883,17 +883,17 @@ cdef class MessageBuilder:
s = schema s = schema
return _DynamicStructBuilder()._init(self.thisptr.initRootDynamicStruct(s.thisptr), self, True) return _DynamicStructBuilder()._init(self.thisptr.initRootDynamicStruct(s.thisptr), self, True)
cpdef getRoot(self, schema): cpdef get_root(self, schema):
"""A method for instantiating Cap'n Proto structs, from an already pre-written buffer """A method for instantiating Cap'n Proto structs, from an already pre-written buffer
Don't use this method unless you know what you're doing. You probably Don't use this method unless you know what you're doing. You probably
want to use initRoot instead:: want to use init_root instead::
addressbook = capnp.load('addressbook.capnp') addressbook = capnp.load('addressbook.capnp')
... ...
person = message.initRoot(addressbook.Person) person = message.init_root(addressbook.Person)
... ...
person = message.getRoot(addressbook.Person) person = message.get_root(addressbook.Person)
:type schema: Schema :type schema: Schema
:param schema: A Cap'n proto schema specifying which struct to instantiate :param schema: A Cap'n proto schema specifying which struct to instantiate
@@ -908,7 +908,7 @@ cdef class MessageBuilder:
s = schema s = schema
return _DynamicStructBuilder()._init(self.thisptr.getRootDynamicStruct(s.thisptr), self, True) return _DynamicStructBuilder()._init(self.thisptr.getRootDynamicStruct(s.thisptr), self, True)
cpdef setRoot(self, value): cpdef set_root(self, value):
"""A method for instantiating Cap'n Proto structs by copying from an existing struct """A method for instantiating Cap'n Proto structs by copying from an existing struct
:type value: :class:`_DynamicStructReader` :type value: :class:`_DynamicStructReader`
@@ -918,17 +918,17 @@ cdef class MessageBuilder:
""" """
if type(value) is _DynamicStructBuilder: if type(value) is _DynamicStructBuilder:
value = value.asReader(); value = value.as_reader();
self.thisptr.setRootDynamicStruct((<_DynamicStructReader>value).thisptr) self.thisptr.setRootDynamicStruct((<_DynamicStructReader>value).thisptr)
cpdef newOrphan(self, schema): cpdef new_orphan(self, schema):
"""A method for instantiating Cap'n Proto orphans """A method for instantiating Cap'n Proto orphans
Don't use this method unless you know what you're doing. Orphans are useful for dynamically allocating objects for an unkown sized list, ie:: Don't use this method unless you know what you're doing. Orphans are useful for dynamically allocating objects for an unkown sized list, ie::
addressbook = capnp.load('addressbook.capnp') addressbook = capnp.load('addressbook.capnp')
m = capnp.MallocMessageBuilder() m = capnp._MallocMessageBuilder()
alice = m.newOrphan(addressbook.Person) alice = m.new_orphan(addressbook.Person)
:type schema: Schema :type schema: Schema
:param schema: A Cap'n proto schema specifying which struct to instantiate :param schema: A Cap'n proto schema specifying which struct to instantiate
@@ -944,7 +944,7 @@ cdef class MessageBuilder:
return _DynamicOrphan()._init(self.thisptr.newOrphan(s.thisptr), self) return _DynamicOrphan()._init(self.thisptr.newOrphan(s.thisptr), self)
cdef class MallocMessageBuilder(MessageBuilder): cdef class _MallocMessageBuilder(_MessageBuilder):
"""The main class for building Cap'n Proto messages """The main class for building Cap'n Proto messages
You will use this class to handle arena allocation of the Cap'n Proto You will use this class to handle arena allocation of the Cap'n Proto
@@ -952,12 +952,12 @@ cdef class MallocMessageBuilder(MessageBuilder):
Proto objects, and wish to serialize them:: Proto objects, and wish to serialize them::
addressbook = capnp.load('addressbook.capnp') addressbook = capnp.load('addressbook.capnp')
message = capnp.MallocMessageBuilder() message = capnp._MallocMessageBuilder()
person = message.initRoot(addressbook.Person) person = message.init_root(addressbook.Person)
person.name = 'alice' person.name = 'alice'
... ...
f = open('out.txt', 'w') f = open('out.txt', 'w')
writeMessageToFd(f.fileno(), message) _write_message_to_fd(f.fileno(), message)
""" """
def __cinit__(self): def __cinit__(self):
self.thisptr = new schema_cpp.MallocMessageBuilder() self.thisptr = new schema_cpp.MallocMessageBuilder()
@@ -976,10 +976,10 @@ cdef class _MessageReader:
def __init__(self): def __init__(self):
raise NotImplementedError("This is an abstract base class") raise NotImplementedError("This is an abstract base class")
cpdef _getRootNode(self): cpdef _get_root_node(self):
return _NodeReader().init(self.thisptr.getRootNode()) return _NodeReader().init(self.thisptr.getRootNode())
cpdef getRoot(self, schema): cpdef get_root(self, schema):
"""A method for instantiating Cap'n Proto structs """A method for instantiating Cap'n Proto structs
You will need to pass in a schema to specify which struct to You will need to pass in a schema to specify which struct to
@@ -987,7 +987,7 @@ cdef class _MessageReader:
addressbook = capnp.load('addressbook.capnp') addressbook = capnp.load('addressbook.capnp')
... ...
person = message.getRoot(addressbook.Person) person = message.get_root(addressbook.Person)
:type schema: Schema :type schema: Schema
:param schema: A Cap'n proto schema specifying which struct to instantiate :param schema: A Cap'n proto schema specifying which struct to instantiate
@@ -1003,14 +1003,14 @@ cdef class _MessageReader:
s = schema s = schema
return _DynamicStructReader()._init(self.thisptr.getRootDynamicStruct(s.thisptr), self) return _DynamicStructReader()._init(self.thisptr.getRootDynamicStruct(s.thisptr), self)
cdef class StreamFdMessageReader(_MessageReader): cdef class _StreamFdMessageReader(_MessageReader):
"""Read a Cap'n Proto message from a file descriptor """Read a Cap'n Proto message from a file descriptor
You use this class to for reading message(s) from a file. It's analagous to the inverse of :func:`writeMessageToFd` and :class:`MessageBuilder`, but in one class:: You use this class to for reading message(s) from a file. It's analagous to the inverse of :func:`_write_message_to_fd` and :class:`_MessageBuilder`, but in one class::
f = open('out.txt') f = open('out.txt')
message = StreamFdMessageReader(f.fileno()) message = _StreamFdMessageReader(f.fileno())
person = message.getRoot(addressbook.Person) person = message.get_root(addressbook.Person)
print person.name print person.name
:Parameters: - fd (`int`) - A file descriptor :Parameters: - fd (`int`) - A file descriptor
@@ -1018,14 +1018,14 @@ cdef class StreamFdMessageReader(_MessageReader):
def __init__(self, int fd): def __init__(self, int fd):
self.thisptr = new schema_cpp.StreamFdMessageReader(fd) self.thisptr = new schema_cpp.StreamFdMessageReader(fd)
cdef class PackedFdMessageReader(_MessageReader): cdef class _PackedFdMessageReader(_MessageReader):
"""Read a Cap'n Proto message from a file descriptor in a packed manner """Read a Cap'n Proto message from a file descriptor in a packed manner
You use this class to for reading message(s) from a file. It's analagous to the inverse of :func:`writePackedMessageToFd` and :class:`MessageBuilder`, but in one class.:: You use this class to for reading message(s) from a file. It's analagous to the inverse of :func:`_write_packed_message_to_fd` and :class:`_MessageBuilder`, but in one class.::
f = open('out.txt') f = open('out.txt')
message = StreamFdMessageReader(f.fileno()) message = _PackedFdMessageReader(f.fileno())
person = message.getRoot(addressbook.Person) person = message.get_root(addressbook.Person)
print person.name print person.name
:Parameters: - fd (`int`) - A file descriptor :Parameters: - fd (`int`) - A file descriptor
@@ -1033,51 +1033,51 @@ cdef class PackedFdMessageReader(_MessageReader):
def __init__(self, int fd): def __init__(self, int fd):
self.thisptr = new schema_cpp.PackedFdMessageReader(fd) self.thisptr = new schema_cpp.PackedFdMessageReader(fd)
def writeMessageToFd(int fd, MessageBuilder message): def _write_message_to_fd(int fd, _MessageBuilder message):
"""Serialize a Cap'n Proto message to a file descriptor """Serialize a Cap'n Proto message to a file descriptor
You use this method to serialize your message to a file. Please note that You use this method to serialize your message to a file. Please note that
you must pass a file descriptor (ie. an int), not a file object. Make sure you must pass a file descriptor (ie. an int), not a file object. Make sure
you use the proper reader to match this (ie. don't use PackedFdMessageReader):: you use the proper reader to match this (ie. don't use _PackedFdMessageReader)::
message = capnp.MallocMessageBuilder() message = capnp._MallocMessageBuilder()
... ...
f = open('out.txt', 'w') f = open('out.txt', 'w')
writeMessageToFd(f.fileno(), message) _write_message_to_fd(f.fileno(), message)
... ...
f = open('out.txt') f = open('out.txt')
StreamFdMessageReader(f.fileno()) _StreamFdMessageReader(f.fileno())
:type fd: int :type fd: int
:param fd: A file descriptor :param fd: A file descriptor
:type message: :class:`MessageBuilder` :type message: :class:`_MessageBuilder`
:param message: The Cap'n Proto message to serialize :param message: The Cap'n Proto message to serialize
:rtype: void :rtype: void
""" """
schema_cpp.writeMessageToFd(fd, deref(message.thisptr)) schema_cpp.writeMessageToFd(fd, deref(message.thisptr))
def writePackedMessageToFd(int fd, MessageBuilder message): def _write_packed_message_to_fd(int fd, _MessageBuilder message):
"""Serialize a Cap'n Proto message to a file descriptor in a packed manner """Serialize a Cap'n Proto message to a file descriptor in a packed manner
You use this method to serialize your message to a file. Please note that You use this method to serialize your message to a file. Please note that
you must pass a file descriptor (ie. an int), not a file object. Also, note you must pass a file descriptor (ie. an int), not a file object. Also, note
the difference in names with writeMessageToFd. This method uses a different the difference in names with _write_message_to_fd. This method uses a different
serialization specification, and your reader will need to match.:: serialization specification, and your reader will need to match.::
message = capnp.MallocMessageBuilder() message = capnp._MallocMessageBuilder()
... ...
f = open('out.txt', 'w') f = open('out.txt', 'w')
writePackedMessageToFd(f.fileno(), message) _write_packed_message_to_fd(f.fileno(), message)
... ...
f = open('out.txt') f = open('out.txt')
PackedFdMessageReader(f.fileno()) _PackedFdMessageReader(f.fileno())
:type fd: int :type fd: int
:param fd: A file descriptor :param fd: A file descriptor
:type message: :class:`MessageBuilder` :type message: :class:`_MessageBuilder`
:param message: The Cap'n Proto message to serialize :param message: The Cap'n Proto message to serialize
:rtype: void :rtype: void

View File

@@ -20,9 +20,13 @@ Pip
Using pip is by far the easiest way to install the library. After you've installed the C++ library, all you need to run is:: Using pip is by far the easiest way to install the library. After you've installed the C++ library, all you need to run is::
pip install -U cython [sudo] pip install -U cython
pip install -U setuptools [sudo] pip install -U setuptools
pip install pycapnp [sudo] pip install pycapnp
On some systems you will have to install Python's headers before doing any of this. For Debian/Ubuntu, this is::
sudo apt-get install python-dev
You can control the compiler version with the environment variable CC, ie. `CC=gcc-4.8 pip install pycapnp`. You only need to run the setuptools line if you have a setuptools older than v0.8.0, and the cython line if you have a version older than v0.19.1. You can control the compiler version with the environment variable CC, ie. `CC=gcc-4.8 pip install pycapnp`. You only need to run the setuptools line if you have a setuptools older than v0.8.0, and the cython line if you have a version older than v0.19.1.

View File

@@ -75,7 +75,7 @@ Initialize a New Cap'n Proto Object
Now that you have a message buffer, you need to allocate an actual object that is from your schema. In this case, we will allocate an `AddressBook`:: Now that you have a message buffer, you need to allocate an actual object that is from your schema. In this case, we will allocate an `AddressBook`::
addresses = addressbook.AddressBook.newMessage() addresses = addressbook.AddressBook.new_message()
Notice that we used `addressbook` from the previous section: `Load a Cap'n Proto Schema`_. Notice that we used `addressbook` from the previous section: `Load a Cap'n Proto Schema`_.
@@ -146,7 +146,7 @@ Writing to a File
For now, the only way to serialize a message is to write it directly to a file descriptor (expect serializing to strings at some point soon):: For now, the only way to serialize a message is to write it directly to a file descriptor (expect serializing to strings at some point soon)::
f = open('example.bin', 'w') f = open('example.bin', 'w')
addresses.writeTo(f) addresses.write(f)
Note the call to fileno(), since it expects a raw file descriptor. There is also `writeMessageToFd` instead of `writePackedMessageToFd`. Make sure your reader uses the same packing type. Note the call to fileno(), since it expects a raw file descriptor. There is also `writeMessageToFd` instead of `writePackedMessageToFd`. Make sure your reader uses the same packing type.
@@ -159,7 +159,7 @@ Reading from a file
Much like before, you will have to de-serialize the message from a file descriptor:: Much like before, you will have to de-serialize the message from a file descriptor::
f = open('example.bin') f = open('example.bin')
addresses = addressbook.AddressBook.readFrom(f addresses = addressbook.AddressBook.read(f)
Note that this very much needs to match the type you wrote out. In general, you will always be sending the same message types out over a given channel or you should wrap all your types in an unnamed union. Unnamed unions are defined in the .capnp file like so:: Note that this very much needs to match the type you wrote out. In general, you will always be sending the same message types out over a given channel or you should wrap all your types in an unnamed union. Unnamed unions are defined in the .capnp file like so::
@@ -211,7 +211,7 @@ Here is a full example reproduced from `examples/example.py <https://github.com/
addressbook = capnp.load(os.path.join(this_dir, 'addressbook.capnp')) addressbook = capnp.load(os.path.join(this_dir, 'addressbook.capnp'))
def writeAddressBook(file): def writeAddressBook(file):
addresses = addressbook.AddressBook.newMessage() addresses = addressbook.AddressBook.new_message()
people = addresses.init('people', 2) people = addresses.init('people', 2)
alice = people[0] alice = people[0]
@@ -234,11 +234,11 @@ Here is a full example reproduced from `examples/example.py <https://github.com/
bobPhones[1].type = 'work' bobPhones[1].type = 'work'
bob.employment.unemployed = None bob.employment.unemployed = None
addresses.writeTo(file) addresses.write(file)
def printAddressBook(file): def printAddressBook(file):
addresses = addressbook.AddressBook.readFrom(file) addresses = addressbook.AddressBook.read(file)
for person in addresses.people: for person in addresses.people:
print(person.name, ':', person.email) print(person.name, ':', person.email)
@@ -265,3 +265,4 @@ Here is a full example reproduced from `examples/example.py <https://github.com/
f = open('example', 'r') f = open('example', 'r')
printAddressBook(f) printAddressBook(f)

View File

@@ -6,7 +6,7 @@ this_dir = os.path.dirname(__file__)
addressbook = capnp.load(os.path.join(this_dir, 'addressbook.capnp')) addressbook = capnp.load(os.path.join(this_dir, 'addressbook.capnp'))
def writeAddressBook(file): def writeAddressBook(file):
addresses = addressbook.AddressBook.newMessage() addresses = addressbook.AddressBook.new_message()
people = addresses.init('people', 2) people = addresses.init('people', 2)
alice = people[0] alice = people[0]
@@ -29,11 +29,11 @@ def writeAddressBook(file):
bobPhones[1].type = 'work' bobPhones[1].type = 'work'
bob.employment.unemployed = None bob.employment.unemployed = None
addresses.writeTo(file) addresses.write(file)
def printAddressBook(file): def printAddressBook(file):
addresses = addressbook.AddressBook.readFrom(file) addresses = addressbook.AddressBook.read(file)
for person in addresses.people: for person in addresses.people:
print(person.name, ':', person.email) print(person.name, ':', person.email)

View File

@@ -1,66 +0,0 @@
from __future__ import print_function
import os
import capnp
this_dir = os.path.dirname(__file__)
addressbook = capnp.load(os.path.join(this_dir, 'addressbook.capnp'))
def writeAddressBook(fd):
message = capnp.MallocMessageBuilder()
addressBook = message.initRoot(addressbook.AddressBook)
people = addressBook.initResizableList('people')
alice = people.add()
alice.id = 123
alice.name = 'Alice'
alice.email = 'alice@example.com'
alicePhones = alice.init('phones', 1)
alicePhones[0].number = "555-1212"
alicePhones[0].type = 'mobile'
alice.employment.school = "MIT"
bob = people.add()
bob.id = 456
bob.name = 'Bob'
bob.email = 'bob@example.com'
bobPhones = bob.init('phones', 2)
bobPhones[0].number = "555-4567"
bobPhones[0].type = 'home'
bobPhones[1].number = "555-7654"
bobPhones[1].type = 'work'
bob.employment.unemployed = None
people.finish()
capnp.writePackedMessageToFd(fd, message)
def printAddressBook(fd):
message = capnp.PackedFdMessageReader(f.fileno())
addressBook = message.getRoot(addressbook.AddressBook)
for person in addressBook.people:
print(person.name, ':', person.email)
for phone in person.phones:
print(phone.type, ':', phone.number)
which = person.employment.which()
print(which)
if which == 'unemployed':
print('unemployed')
elif which == 'employer':
print('employer:', person.employment.employer)
elif which == 'school':
print('student at:', person.employment.school)
elif which == 'selfEmployed':
print('self employed')
print()
if __name__ == '__main__':
f = open('example', 'w')
writeAddressBook(f.fileno())
f = open('example', 'r')
printAddressBook(f.fileno())

View File

@@ -27,10 +27,10 @@ def test_classes(addressbook):
assert addressbook.Person assert addressbook.Person
def test_import(foo, bar): def test_import(foo, bar):
m = capnp.MallocMessageBuilder() m = capnp._MallocMessageBuilder()
foo = m.initRoot(foo.Foo) foo = m.init_root(foo.Foo)
m2 = capnp.MallocMessageBuilder() m2 = capnp._MallocMessageBuilder()
bar = m2.initRoot(bar.Bar) bar = m2.init_root(bar.Bar)
foo.name = 'foo' foo.name = 'foo'
bar.foo = foo bar.foo = foo
@@ -44,10 +44,10 @@ def test_failed_import():
foo = s.load(os.path.join(this_dir, 'foo.capnp')) foo = s.load(os.path.join(this_dir, 'foo.capnp'))
bar = s2.load(os.path.join(this_dir, 'bar.capnp')) bar = s2.load(os.path.join(this_dir, 'bar.capnp'))
m = capnp.MallocMessageBuilder() m = capnp._MallocMessageBuilder()
foo = m.initRoot(foo.Foo) foo = m.init_root(foo.Foo)
m2 = capnp.MallocMessageBuilder() m2 = capnp._MallocMessageBuilder()
bar = m2.initRoot(bar.Bar) bar = m2.init_root(bar.Bar)
foo.name = 'foo' foo.name = 'foo'

View File

@@ -11,8 +11,8 @@ def addressbook():
def test_addressbook_message_classes(addressbook): def test_addressbook_message_classes(addressbook):
def writeAddressBook(fd): def writeAddressBook(fd):
message = capnp.MallocMessageBuilder() message = capnp._MallocMessageBuilder()
addressBook = message.initRoot(addressbook.AddressBook) addressBook = message.init_root(addressbook.AddressBook)
people = addressBook.init('people', 2) people = addressBook.init('people', 2)
alice = people[0] alice = people[0]
@@ -35,31 +35,34 @@ def test_addressbook_message_classes(addressbook):
bobPhones[1].type = 'work' bobPhones[1].type = 'work'
bob.employment.unemployed = None bob.employment.unemployed = None
capnp.writePackedMessageToFd(fd, message) capnp._write_packed_message_to_fd(fd, message)
def printAddressBook(fd): def printAddressBook(fd):
message = capnp.PackedFdMessageReader(f.fileno()) message = capnp._PackedFdMessageReader(f.fileno())
addressBook = message.getRoot(addressbook.AddressBook) addressBook = message.get_root(addressbook.AddressBook)
for person in addressBook.people: people = addressBook.people
print(person.name, ':', person.email)
for phone in person.phones:
print(phone.type, ':', phone.number)
which = person.employment.which() alice = people[0]
print(which) assert alice.id == 123
assert alice.name == 'Alice'
if which == 'unemployed': assert alice.email == 'alice@example.com'
print('unemployed') alicePhones = alice.phones
elif which == 'employer': assert alicePhones[0].number == "555-1212"
print('employer:', person.employment.employer) assert alicePhones[0].type == 'mobile'
elif which == 'school': assert alice.employment.school == "MIT"
print('student at:', person.employment.school)
elif which == 'selfEmployed':
print('self employed')
print()
bob = people[1]
assert bob.id == 456
assert bob.name == 'Bob'
assert bob.email == 'bob@example.com'
bobPhones = bob.phones
assert bobPhones[0].number == "555-4567"
assert bobPhones[0].type == 'home'
assert bobPhones[1].number == "555-7654"
assert bobPhones[1].type == 'work'
assert bob.employment.unemployed == None
f = open('example', 'w') f = open('example', 'w')
writeAddressBook(f.fileno()) writeAddressBook(f.fileno())
@@ -69,7 +72,7 @@ def test_addressbook_message_classes(addressbook):
def test_addressbook(addressbook): def test_addressbook(addressbook):
def writeAddressBook(file): def writeAddressBook(file):
addresses = addressbook.AddressBook.newMessage() addresses = addressbook.AddressBook.new_message()
people = addresses.init('people', 2) people = addresses.init('people', 2)
alice = people[0] alice = people[0]
@@ -92,29 +95,95 @@ def test_addressbook(addressbook):
bobPhones[1].type = 'work' bobPhones[1].type = 'work'
bob.employment.unemployed = None bob.employment.unemployed = None
addresses.writeTo(file) addresses.write(file)
def printAddressBook(file): def printAddressBook(file):
addresses = addressbook.AddressBook.readFrom(file) addresses = addressbook.AddressBook.read(file)
for person in addresses.people: people = addresses.people
print(person.name, ':', person.email)
for phone in person.phones:
print(phone.type, ':', phone.number)
which = person.employment.which() alice = people[0]
print(which) assert alice.id == 123
assert alice.name == 'Alice'
assert alice.email == 'alice@example.com'
alicePhones = alice.phones
assert alicePhones[0].number == "555-1212"
assert alicePhones[0].type == 'mobile'
assert alice.employment.school == "MIT"
if which == 'unemployed': bob = people[1]
print('unemployed') assert bob.id == 456
elif which == 'employer': assert bob.name == 'Bob'
print('employer:', person.employment.employer) assert bob.email == 'bob@example.com'
elif which == 'school': bobPhones = bob.phones
print('student at:', person.employment.school) assert bobPhones[0].number == "555-4567"
elif which == 'selfEmployed': assert bobPhones[0].type == 'home'
print('self employed') assert bobPhones[1].number == "555-7654"
print() assert bobPhones[1].type == 'work'
assert bob.employment.unemployed == None
f = open('example', 'w')
writeAddressBook(f)
f = open('example', 'r')
printAddressBook(f)
def test_addressbook_resizable(addressbook):
def writeAddressBook(file):
addresses = addressbook.AddressBook.new_message()
people = addresses.init_resizable_list('people')
alice = people.add()
alice.id = 123
alice.name = 'Alice'
alice.email = 'alice@example.com'
alicePhones = alice.init('phones', 1)
alicePhones[0].number = "555-1212"
alicePhones[0].type = 'mobile'
alice.employment.school = "MIT"
bob = people.add()
bob.id = 456
bob.name = 'Bob'
bob.email = 'bob@example.com'
bobPhones = bob.init('phones', 2)
bobPhones[0].number = "555-4567"
bobPhones[0].type = 'home'
bobPhones[1].number = "555-7654"
bobPhones[1].type = 'work'
bob.employment.unemployed = None
people.finish()
addresses.write(file)
def printAddressBook(file):
addresses = addressbook.AddressBook.read(file)
people = addresses.people
alice = people[0]
assert alice.id == 123
assert alice.name == 'Alice'
assert alice.email == 'alice@example.com'
alicePhones = alice.phones
assert alicePhones[0].number == "555-1212"
assert alicePhones[0].type == 'mobile'
assert alice.employment.school == "MIT"
bob = people[1]
assert bob.id == 456
assert bob.name == 'Bob'
assert bob.email == 'bob@example.com'
bobPhones = bob.phones
assert bobPhones[0].number == "555-4567"
assert bobPhones[0].type == 'home'
assert bobPhones[1].number == "555-7654"
assert bobPhones[1].type == 'work'
assert bob.employment.unemployed == None
f = open('example', 'w') f = open('example', 'w')
@@ -323,46 +392,46 @@ def check_all_types(reader):
check_list(reader.enumList, ["foo", "garply"]) check_list(reader.enumList, ["foo", "garply"])
def test_build(all_types): def test_build(all_types):
root = all_types.TestAllTypes.newMessage() root = all_types.TestAllTypes.new_message()
init_all_types(root) init_all_types(root)
expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read() expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read()
assert str(root) + '\n' == expectedText assert str(root) + '\n' == expectedText
def test_binary_read(all_types): def test_binary_read(all_types):
f = open(os.path.join(this_dir, 'all-types.binary'), 'r') f = open(os.path.join(this_dir, 'all-types.binary'), 'r')
root = all_types.TestAllTypes.readFrom(f) root = all_types.TestAllTypes.read(f)
check_all_types(root) check_all_types(root)
expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read() expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read()
assert str(root) + '\n' == expectedText assert str(root) + '\n' == expectedText
# Test setRoot(). # Test set_root().
builder = capnp.MallocMessageBuilder() builder = capnp._MallocMessageBuilder()
builder.setRoot(root) builder.set_root(root)
check_all_types(builder.getRoot(all_types.TestAllTypes)) check_all_types(builder.get_root(all_types.TestAllTypes))
builder2 = capnp.MallocMessageBuilder() builder2 = capnp._MallocMessageBuilder()
builder2.setRoot(builder.getRoot(all_types.TestAllTypes)) builder2.set_root(builder.get_root(all_types.TestAllTypes))
check_all_types(builder2.getRoot(all_types.TestAllTypes)) check_all_types(builder2.get_root(all_types.TestAllTypes))
def test_packed_read(all_types): def test_packed_read(all_types):
f = open(os.path.join(this_dir, 'all-types.packed'), 'r') f = open(os.path.join(this_dir, 'all-types.packed'), 'r')
root = all_types.TestAllTypes.readPackedFrom(f) root = all_types.TestAllTypes.read_packed(f)
check_all_types(root) check_all_types(root)
expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read() expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read()
assert str(root) + '\n' == expectedText assert str(root) + '\n' == expectedText
def test_binary_write(all_types): def test_binary_write(all_types):
root = all_types.TestAllTypes.newMessage() root = all_types.TestAllTypes.new_message()
init_all_types(root) init_all_types(root)
root.writeTo(open('example', 'w')) root.write(open('example', 'w'))
check_all_types(all_types.TestAllTypes.readFrom(open('example', 'r'))) check_all_types(all_types.TestAllTypes.read(open('example', 'r')))
def test_packed_write(all_types): def test_packed_write(all_types):
root = all_types.TestAllTypes.newMessage() root = all_types.TestAllTypes.new_message()
init_all_types(root) init_all_types(root)
root.writePackedTo(open('example', 'w')) root.write_packed(open('example', 'w'))
check_all_types(all_types.TestAllTypes.readPackedFrom(open('example', 'r'))) check_all_types(all_types.TestAllTypes.read_packed(open('example', 'r')))