Update preferred method for reading/writing messages from files
This commit is contained in:
@@ -7,9 +7,8 @@ Example Usage::
|
|||||||
addressbook = capnp.load('addressbook.capnp')
|
addressbook = capnp.load('addressbook.capnp')
|
||||||
|
|
||||||
# Building
|
# Building
|
||||||
message = capnp.MallocMessageBuilder()
|
addresses = addressbook.AddressBook.newMessage()
|
||||||
addressBook = message.initRoot(addressbook.AddressBook)
|
people = addresses.init('people', 1)
|
||||||
people = addressBook.init('people', 1)
|
|
||||||
|
|
||||||
alice = people[0]
|
alice = people[0]
|
||||||
alice.id = 123
|
alice.id = 123
|
||||||
@@ -19,16 +18,15 @@ Example Usage::
|
|||||||
alicePhone.type = 'mobile'
|
alicePhone.type = 'mobile'
|
||||||
|
|
||||||
f = open('example.bin', 'w')
|
f = open('example.bin', 'w')
|
||||||
capnp.writePackedMessageToFd(f.fileno(), message)
|
addresses.writeTo(f)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
# Reading
|
# Reading
|
||||||
f = open('example.bin')
|
f = open('example.bin')
|
||||||
message = capnp.PackedFdMessageReader(f.fileno())
|
|
||||||
|
|
||||||
addressBook = message.getRoot(addressbook.AddressBook)
|
addresses = addressbook.AddressBook.readFrom(f)
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ ctypedef double Float64
|
|||||||
from libc.stdlib cimport malloc, free
|
from libc.stdlib cimport malloc, free
|
||||||
from libcpp cimport bool as cbool
|
from libcpp cimport bool as cbool
|
||||||
|
|
||||||
_MAX_INT = 2**63 - 1
|
|
||||||
ctypedef fused _DynamicStructReaderOrBuilder:
|
ctypedef fused _DynamicStructReaderOrBuilder:
|
||||||
_DynamicStructReader
|
_DynamicStructReader
|
||||||
_DynamicStructBuilder
|
_DynamicStructBuilder
|
||||||
@@ -131,7 +130,7 @@ cdef class _DynamicListReader:
|
|||||||
This class thinly wraps the C++ Cap'n Proto DynamicList::Reader class. __getitem__ and __len__ have been defined properly, so you can treat this class mostly like any other iterable class::
|
This class thinly wraps the C++ Cap'n Proto DynamicList::Reader class. __getitem__ and __len__ have been defined properly, so you can treat this class mostly like any other iterable class::
|
||||||
|
|
||||||
...
|
...
|
||||||
person = message.getRoot(addressbook.Person)
|
person = addressbook.Person.readFrom(file)
|
||||||
|
|
||||||
phones = person.phones # This returns a _DynamicListReader
|
phones = person.phones # This returns a _DynamicListReader
|
||||||
|
|
||||||
@@ -170,10 +169,10 @@ cdef class _DynamicResizableListBuilder:
|
|||||||
|
|
||||||
.. warning:: You need to call :meth:`finish` on this object before serializing the Cap'n Proto message. Failure to do so will cause your objects not to be written out as well as leaking orphan structs into your message.
|
.. warning:: You need to call :meth:`finish` on this object before serializing the Cap'n Proto message. Failure to do so will cause your objects not to be written out as well as leaking orphan structs into your message.
|
||||||
|
|
||||||
This class works much like :class:`_DynamicListBuilder`, but it allows growing the list dynamically. It is meant for lists of structs, since for primitive types like int or float, you're much better off using a normal python list and then serializing straight to a Cap'n Proto list. It has __getitem__ and __len__ defined, but not __setitem__.
|
This class works much like :class:`_DynamicListBuilder`, but it allows growing the list dynamically. It is meant for lists of structs, since for primitive types like int or float, you're much better off using a normal python list and then serializing straight to a Cap'n Proto list. It has __getitem__ and __len__ defined, but not __setitem__::
|
||||||
|
|
||||||
...
|
...
|
||||||
person = message.initRoot(addressbook.Person)
|
person = addressbook.Person.newMessage()
|
||||||
|
|
||||||
phones = person.initResizableList('phones') # This returns a _DynamicResizableListBuilder
|
phones = person.initResizableList('phones') # This returns a _DynamicResizableListBuilder
|
||||||
|
|
||||||
@@ -184,7 +183,8 @@ cdef class _DynamicResizableListBuilder:
|
|||||||
|
|
||||||
people.finish()
|
people.finish()
|
||||||
|
|
||||||
capnp.writePackedMessageToFd(fd, message)
|
f = open('example', 'w')
|
||||||
|
person.writeTo(f)
|
||||||
"""
|
"""
|
||||||
cdef public object _parent, _message, _field, _schema
|
cdef public object _parent, _message, _field, _schema
|
||||||
cdef public list _list
|
cdef public list _list
|
||||||
@@ -234,7 +234,7 @@ cdef class _DynamicListBuilder:
|
|||||||
This class thinly wraps the C++ Cap'n Proto DynamicList::Bulder class. __getitem__, __setitem__, and __len__ have been defined properly, so you can treat this class mostly like any other iterable class::
|
This class thinly wraps the C++ Cap'n Proto DynamicList::Bulder class. __getitem__, __setitem__, and __len__ have been defined properly, so you can treat this class mostly like any other iterable class::
|
||||||
|
|
||||||
...
|
...
|
||||||
person = message.initRoot(addressbook.Person)
|
person = addressbook.Person.newMessage()
|
||||||
|
|
||||||
phones = person.init('phones', 2) # This returns a _DynamicListBuilder
|
phones = person.init('phones', 2) # This returns a _DynamicListBuilder
|
||||||
|
|
||||||
@@ -278,21 +278,7 @@ cdef class _DynamicListBuilder:
|
|||||||
cpdef adopt(self, index, _DynamicOrphan orphan):
|
cpdef adopt(self, index, _DynamicOrphan orphan):
|
||||||
"""A method for adopting Cap'n Proto orphans
|
"""A method for adopting 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.
|
||||||
|
|
||||||
message = capnp.MallocMessageBuilder()
|
|
||||||
|
|
||||||
alice = m.newOrphan(addressbook.Person)
|
|
||||||
alice.get().name = 'alice'
|
|
||||||
|
|
||||||
bob = m.newOrphan(addressbook.Person)
|
|
||||||
bob.get().name = 'bob'
|
|
||||||
|
|
||||||
addressBook = message.initRoot(addressbook.AddressBook)
|
|
||||||
people = addressBook.init('people', 2)
|
|
||||||
|
|
||||||
people.adopt(0, alice)
|
|
||||||
people.adopt(1, bob)
|
|
||||||
|
|
||||||
:type index: int
|
:type index: int
|
||||||
:param index: The index of the element in the list to replace with the newly adopted object
|
:param index: The index of the element in the list to replace with the newly adopted object
|
||||||
@@ -439,7 +425,7 @@ cdef class _DynamicStructReader:
|
|||||||
|
|
||||||
This class is almost a 1 for 1 wrapping of the Cap'n Proto C++ DynamicStruct::Reader. The only difference is that instead of a `get` method, __getattr__ is overloaded and the field name is passed onto the C++ equivalent `get`. This means you just use . syntax to access any field. For field names that don't follow valid python naming convention for fields, use the global function :py:func:`getattr`::
|
This class is almost a 1 for 1 wrapping of the Cap'n Proto C++ DynamicStruct::Reader. The only difference is that instead of a `get` method, __getattr__ is overloaded and the field name is passed onto the C++ equivalent `get`. This means you just use . syntax to access any field. For field names that don't follow valid python naming convention for fields, use the global function :py:func:`getattr`::
|
||||||
|
|
||||||
person = message.getRoot(addressbook.Person) # This returns a _DynamicStructReader
|
person = addressbook.Person.readFrom(file) # This returns a _DynamicStructReader
|
||||||
print person.name # using . syntax
|
print person.name # using . syntax
|
||||||
print getattr(person, 'field-with-hyphens') # for names that are invalid for python, use getattr
|
print getattr(person, 'field-with-hyphens') # for names that are invalid for python, use getattr
|
||||||
"""
|
"""
|
||||||
@@ -462,7 +448,7 @@ cdef class _DynamicStructReader:
|
|||||||
|
|
||||||
Enums are just strings in the python Cap'n Proto API, so this function will either return a string equal to the field name of the active field in the union, or throw a ValueError if this isn't a union, or a struct with an unnamed union::
|
Enums are just strings in the python Cap'n Proto API, so this function will either return a string equal to the field name of the active field in the union, or throw a ValueError if this isn't a union, or a struct with an unnamed union::
|
||||||
|
|
||||||
person = message.initRoot(addressbook.Person)
|
person = addressbook.Person.newMessage()
|
||||||
|
|
||||||
person.which()
|
person.which()
|
||||||
# ValueError: member was null
|
# ValueError: member was null
|
||||||
@@ -497,7 +483,7 @@ cdef class _DynamicStructBuilder:
|
|||||||
|
|
||||||
This class is almost a 1 for 1 wrapping of the Cap'n Proto C++ DynamicStruct::Builder. The only difference is that instead of a `get`/`set` method, __getattr__/__setattr__ is overloaded and the field name is passed onto the C++ equivalent function. This means you just use . syntax to access or set any field. For field names that don't follow valid python naming convention for fields, use the global functions :py:func:`getattr`/:py:func:`setattr`::
|
This class is almost a 1 for 1 wrapping of the Cap'n Proto C++ DynamicStruct::Builder. The only difference is that instead of a `get`/`set` method, __getattr__/__setattr__ is overloaded and the field name is passed onto the C++ equivalent function. This means you just use . syntax to access or set any field. For field names that don't follow valid python naming convention for fields, use the global functions :py:func:`getattr`/:py:func:`setattr`::
|
||||||
|
|
||||||
person = message.initRoot(addressbook.Person) # This returns a _DynamicStructBuilder
|
person = addressbook.Person.newMessage() # This returns a _DynamicStructBuilder
|
||||||
|
|
||||||
person.name = 'foo' # using . syntax
|
person.name = 'foo' # using . syntax
|
||||||
print person.name # using . syntax
|
print person.name # using . syntax
|
||||||
@@ -601,7 +587,7 @@ cdef class _DynamicStructBuilder:
|
|||||||
|
|
||||||
Enums are just strings in the python Cap'n Proto API, so this function will either return a string equal to the field name of the active field in the union, or throw a ValueError if this isn't a union, or a struct with an unnamed union::
|
Enums are just strings in the python Cap'n Proto API, so this function will either return a string equal to the field name of the active field in the union, or throw a ValueError if this isn't a union, or a struct with an unnamed union::
|
||||||
|
|
||||||
person = message.initRoot(addressbook.Person)
|
person = addressbook.Person.newMessage()
|
||||||
|
|
||||||
person.which()
|
person.which()
|
||||||
# ValueError: member was null
|
# ValueError: member was null
|
||||||
@@ -620,21 +606,7 @@ cdef class _DynamicStructBuilder:
|
|||||||
cpdef adopt(self, field, _DynamicOrphan orphan):
|
cpdef adopt(self, field, _DynamicOrphan orphan):
|
||||||
"""A method for adopting Cap'n Proto orphans
|
"""A method for adopting 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.
|
||||||
|
|
||||||
message = capnp.MallocMessageBuilder()
|
|
||||||
|
|
||||||
alice = m.newOrphan(addressbook.Person)
|
|
||||||
alice.get().name = 'alice'
|
|
||||||
|
|
||||||
bob = m.newOrphan(addressbook.Person)
|
|
||||||
bob.get().name = 'bob'
|
|
||||||
|
|
||||||
addressBook = message.initRoot(addressbook.AddressBook)
|
|
||||||
people = addressBook.init('people', 2)
|
|
||||||
|
|
||||||
people.adopt(0, alice)
|
|
||||||
people.adopt(1, bob)
|
|
||||||
|
|
||||||
:type field: str
|
:type field: str
|
||||||
:param field: The field name in the struct
|
:param field: The field name in the struct
|
||||||
@@ -814,8 +786,7 @@ cdef class SchemaParser:
|
|||||||
addressbook = parser.load('addressbook.capnp')
|
addressbook = parser.load('addressbook.capnp')
|
||||||
print addressbook.qux # qux is a top level constant
|
print addressbook.qux # qux is a top level constant
|
||||||
# 123
|
# 123
|
||||||
message = capnp.MallocMessageBuilder()
|
person = addressbook.Person.newMessage()
|
||||||
person = message.initRoot(addressbook.Person)
|
|
||||||
|
|
||||||
:type file_name: str
|
:type file_name: str
|
||||||
:param file_name: A relative or absolute path to a Cap'n Proto schema
|
:param file_name: A relative or absolute path to a Cap'n Proto schema
|
||||||
@@ -956,7 +927,7 @@ cdef class MessageBuilder:
|
|||||||
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()
|
||||||
alice = m.newOrphan(addressbook.Person)
|
alice = m.newOrphan(addressbook.Person)
|
||||||
|
|
||||||
:type schema: Schema
|
:type schema: Schema
|
||||||
@@ -1129,8 +1100,7 @@ def load(file_name, display_name=None, imports=[]):
|
|||||||
addressbook = capnp.load('addressbook.capnp')
|
addressbook = capnp.load('addressbook.capnp')
|
||||||
print addressbook.qux # qux is a top level constant in the addressbook.capnp schema
|
print addressbook.qux # qux is a top level constant in the addressbook.capnp schema
|
||||||
# 123
|
# 123
|
||||||
message = capnp.MallocMessageBuilder()
|
person = addressbook.Person.newMessage()
|
||||||
person = message.initRoot(addressbook.Person)
|
|
||||||
|
|
||||||
:type file_name: str
|
:type file_name: str
|
||||||
:param file_name: A relative or absolute path to a Cap'n Proto schema
|
:param file_name: A relative or absolute path to a Cap'n Proto schema
|
||||||
|
|||||||
@@ -10,34 +10,6 @@ API Reference
|
|||||||
Functions
|
Functions
|
||||||
-------------
|
-------------
|
||||||
.. autofunction:: load
|
.. autofunction:: load
|
||||||
.. autofunction:: writeMessageToFd
|
|
||||||
.. autofunction:: writePackedMessageToFd
|
|
||||||
|
|
||||||
Readers
|
|
||||||
-------------
|
|
||||||
|
|
||||||
.. autoclass:: StreamFdMessageReader
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
.. autoclass:: PackedFdMessageReader
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
Builders
|
|
||||||
-------------
|
|
||||||
|
|
||||||
.. autoclass:: MessageBuilder
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
.. autoclass:: MallocMessageBuilder
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
Internal Classes
|
Internal Classes
|
||||||
----------------
|
----------------
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Note that we assign the loaded module to a variable, named `addressbook`. We'll
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
For future reference, here is the Cap'n Proto schema. Also available in the github repository under examples/addressbook.capnp::
|
For future reference, here is the Cap'n Proto schema. Also available in the github repository under `examples/addressbook.capnp <https://github.com/jparyani/pycapnp/tree/master/examples>`_::
|
||||||
|
|
||||||
# addressbook.capnp
|
# addressbook.capnp
|
||||||
0x934efea7f017fff0;
|
0x934efea7f017fff0;
|
||||||
@@ -70,19 +70,12 @@ Const values show up just as you'd expect under the loaded schema. For example::
|
|||||||
Build a message
|
Build a message
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Message Builder
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
First you need to allocate a MessageBuilder for your message to go in. There is only 1 message allocator available at the moment (Malloc), although there may be more varied kinds in the future::
|
|
||||||
|
|
||||||
message = capnp.MallocMessageBuilder()
|
|
||||||
|
|
||||||
Initialize a New Cap'n Proto Object
|
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`::
|
||||||
|
|
||||||
addressBook = message.initRoot(addressbook.AddressBook)
|
addresses = addressbook.AddressBook.newMessage()
|
||||||
|
|
||||||
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`_.
|
||||||
|
|
||||||
@@ -153,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')
|
||||||
capnp.writePackedMessageToFd(f.fileno(), message)
|
addresses.writeTo(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.
|
||||||
|
|
||||||
@@ -166,16 +159,9 @@ 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')
|
||||||
message = capnp.PackedFdMessageReader(f.fileno())
|
addresses = addressbook.AddressBook.readFrom(f
|
||||||
|
|
||||||
Initialize a New Cap'n Proto Object
|
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::
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Just like when building, you have to actually specify which message you want to read out of buffer::
|
|
||||||
|
|
||||||
addressBook = message.getRoot(addressbook.AddressBook)
|
|
||||||
|
|
||||||
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, wrap all your types in an unnamed enum, or you need some out of band method for communicating what type a message is. Unnamed unions are defined in the .capnp file like so::
|
|
||||||
|
|
||||||
struct Message {
|
struct Message {
|
||||||
union {
|
union {
|
||||||
@@ -189,7 +175,7 @@ Reading Fields
|
|||||||
|
|
||||||
Fields are very easy to read. You just use the `.` syntax as before. Lists behave just like normal Python lists::
|
Fields are very easy to read. You just use the `.` syntax as before. Lists behave just like normal Python lists::
|
||||||
|
|
||||||
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)
|
||||||
@@ -224,10 +210,9 @@ Here is a full example reproduced from `examples/example.py <https://github.com/
|
|||||||
this_dir = os.path.dirname(__file__)
|
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(fd):
|
def writeAddressBook(file):
|
||||||
message = capnp.MallocMessageBuilder()
|
addresses = addressbook.AddressBook.newMessage()
|
||||||
addressBook = message.initRoot(addressbook.AddressBook)
|
people = addresses.init('people', 2)
|
||||||
people = addressBook.init('people', 2)
|
|
||||||
|
|
||||||
alice = people[0]
|
alice = people[0]
|
||||||
alice.id = 123
|
alice.id = 123
|
||||||
@@ -249,14 +234,13 @@ 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
|
||||||
|
|
||||||
capnp.writePackedMessageToFd(fd, message)
|
addresses.writeTo(file)
|
||||||
|
|
||||||
|
|
||||||
def printAddressBook(fd):
|
def printAddressBook(file):
|
||||||
message = capnp.PackedFdMessageReader(f.fileno())
|
addresses = addressbook.AddressBook.readFrom(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)
|
||||||
@@ -277,7 +261,7 @@ Here is a full example reproduced from `examples/example.py <https://github.com/
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
f = open('example', 'w')
|
f = open('example', 'w')
|
||||||
writeAddressBook(f.fileno())
|
writeAddressBook(f)
|
||||||
|
|
||||||
f = open('example', 'r')
|
f = open('example', 'r')
|
||||||
printAddressBook(f.fileno())
|
printAddressBook(f)
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import capnp
|
|||||||
this_dir = os.path.dirname(__file__)
|
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(fd):
|
def writeAddressBook(file):
|
||||||
message = capnp.MallocMessageBuilder()
|
addresses = addressbook.AddressBook.newMessage()
|
||||||
addressBook = message.initRoot(addressbook.AddressBook)
|
people = addresses.init('people', 2)
|
||||||
people = addressBook.init('people', 2)
|
|
||||||
|
|
||||||
alice = people[0]
|
alice = people[0]
|
||||||
alice.id = 123
|
alice.id = 123
|
||||||
@@ -30,14 +29,13 @@ def writeAddressBook(fd):
|
|||||||
bobPhones[1].type = 'work'
|
bobPhones[1].type = 'work'
|
||||||
bob.employment.unemployed = None
|
bob.employment.unemployed = None
|
||||||
|
|
||||||
capnp.writePackedMessageToFd(fd, message)
|
addresses.writeTo(file)
|
||||||
|
|
||||||
|
|
||||||
def printAddressBook(fd):
|
def printAddressBook(file):
|
||||||
message = capnp.PackedFdMessageReader(f.fileno())
|
addresses = addressbook.AddressBook.readFrom(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)
|
||||||
@@ -58,7 +56,7 @@ def printAddressBook(fd):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
f = open('example', 'w')
|
f = open('example', 'w')
|
||||||
writeAddressBook(f.fileno())
|
writeAddressBook(f)
|
||||||
|
|
||||||
f = open('example', 'r')
|
f = open('example', 'r')
|
||||||
printAddressBook(f.fileno())
|
printAddressBook(f)
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -61,7 +61,7 @@ setup(
|
|||||||
author_email="pypi-contact@jparyani.com",
|
author_email="pypi-contact@jparyani.com",
|
||||||
url = 'https://github.com/jparyani/pycapnp',
|
url = 'https://github.com/jparyani/pycapnp',
|
||||||
download_url = 'https://github.com/jparyani/pycapnp/archive/v%s.zip' % VERSION,
|
download_url = 'https://github.com/jparyani/pycapnp/archive/v%s.zip' % VERSION,
|
||||||
keywords = ['capnp', 'capnproto'],
|
keywords = ['capnp', 'capnproto', "Cap'n Proto"],
|
||||||
classifiers = [
|
classifiers = [
|
||||||
'Development Status :: 3 - Alpha',
|
'Development Status :: 3 - Alpha',
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ this_dir = os.path.dirname(__file__)
|
|||||||
def addressbook():
|
def addressbook():
|
||||||
return capnp.load(os.path.join(this_dir, 'addressbook.capnp'))
|
return capnp.load(os.path.join(this_dir, 'addressbook.capnp'))
|
||||||
|
|
||||||
def test_addressbook(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.initRoot(addressbook.AddressBook)
|
||||||
@@ -67,6 +67,63 @@ def test_addressbook(addressbook):
|
|||||||
f = open('example', 'r')
|
f = open('example', 'r')
|
||||||
printAddressBook(f.fileno())
|
printAddressBook(f.fileno())
|
||||||
|
|
||||||
|
def test_addressbook(addressbook):
|
||||||
|
def writeAddressBook(file):
|
||||||
|
addresses = addressbook.AddressBook.newMessage()
|
||||||
|
people = addresses.init('people', 2)
|
||||||
|
|
||||||
|
alice = people[0]
|
||||||
|
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[1]
|
||||||
|
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
|
||||||
|
|
||||||
|
addresses.writeTo(file)
|
||||||
|
|
||||||
|
|
||||||
|
def printAddressBook(file):
|
||||||
|
addresses = addressbook.AddressBook.readFrom(file)
|
||||||
|
|
||||||
|
for person in addresses.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()
|
||||||
|
|
||||||
|
|
||||||
|
f = open('example', 'w')
|
||||||
|
writeAddressBook(f)
|
||||||
|
|
||||||
|
f = open('example', 'r')
|
||||||
|
printAddressBook(f)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def all_types():
|
def all_types():
|
||||||
return capnp.load(os.path.join(this_dir, 'all-types.capnp'))
|
return capnp.load(os.path.join(this_dir, 'all-types.capnp'))
|
||||||
|
|||||||
Reference in New Issue
Block a user