- __path__ was being set to a string
- It's supposed to be a list of strings or None
For pycapnp pydoc isn't super useful at the module level as pydoc will
scan all the files in the directory and just list them.
Here's thread_capnp for example, notice how it doesn't show any
information on the .capnp files.
Help on package thread_capnp:
NAME
thread_capnp
PACKAGE CONTENTS
addressbook
async_calculator_client
async_calculator_server
async_client
async_reconnecting_ssl_client
async_server
async_ssl_client
async_ssl_server
calculator_client
calculator_server
thread_client
thread_server
DATA
Example = <capnp.lib.capnp._InterfaceModule object>
schema = <capnp.lib.capnp._ParsedSchema object>
- poll_forever() doesn't allow for checking socket connection to client
* Need to check for client, if eof received then we can close the
connection and cleanup pycapnp cpu resources (async tasks)
- Updated async examples to fix bugs
* Add checking code for socket connection to the client and gracefully
cleanup resources once the client socket connection closes
* Instanciate a new TwoPartyServer per connection (allows for multiple
connections)
- Should resolve Issue #198
- Adding import path filter to exclude non-directories
Otherwise kj will through exceptions
- Skipped AF_UNIX socket test
- Use default socket configuration when it doesn't matter the type of
socket used
- Open files with utf8 encoding (needed for text validation)
- Explictly call python executable when running external scripts
- Fix path creation to always use os.path.join
- Added timeout to client wait in some tests
- Some broken tests still remain (most likely asyncio related)
- Basic tests are working
- May need some adjustments to get all tests working
- Cleaned up bundling to take Python arch into account when building
with multiple architectures
- Not recommended to be used in new designs
- Just pollutes warning messages during compilation (hiding ones that
should be fixed)
- Updated test code to use bootstrap
- Sped up some of the test code that was just sleeping while waiting for
the server (now polling for the socket)
- Reduces 99% CPU usage to around 1%
- It might be useful to have the sleep/delay tunable for certain
applications depending on the latency requirements
- Needed to include cleanup_global_schema_parser() to handle duplicate
imports of the same .capnp file
* Duplicate IDs are a problem as pytest does not fully cleanup between
tests
- Marked some tests as xfail as I'm not sure the test is supposed to
work anymore with recent versions of capnproto
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude benchmark
Excluding the benchmark directory (due to protobuf generated files)
Also removing some Python2 specific code
Note: I've tried not to break any behaviour of the previously working APIs
Python API Changes / Additions
- capnp/lib/capnp.pyx
* class _RemotePromise
+ [Added] cpdef _wait(self)
= Exception raising code that used to be inside of wait(self)
+ [Modified] def wait(self)
= Same functionality as before
+ [Added] async def a_wait(self)
= Cannot use await as that's a reserved keyword
= Uses pollRemote and asyncio.sleep(0) to make call asynchronous
* class _TwoPartyVatNetwork
+ [Added] cdef _init_pipe(self, _TwoWayPipe pipe, Side side,
schema_cpp.ReaderOptions opts)
= Instanciates a TwoPartyVatNetwork using a TwoWayPipe (instead of
using a file handle or connection as before)
* class TwoPartyClient
+ [Modified] def __init__(self, socket=None, restorer=None,
traversal_limit_in_words=None, nesting_limit=None)
= Changes the socket parameter to be optional
= If socket is not specified, default to using a TwoWayPipe
+ [Added] async def read(self, bufsize)
= awaitable function that blocks until data has been read
= bufsize defines the maximum amount of data to be read back
(e.g. 4096 bytes)
= Reads data from TwoWayPipe
+ [Added] def write(self, data)
= Write data to TwoWayPipe
= Not awaitable as the write interface of the TwoWayPipe doesn't
have poll functionality
* class TwoPartyServer
+ [Modified] def __init__(self, socket=None, restorer=None,
server_socket=None, bootstrap=None, traversal_limit_in_words=None,
nesting_limit=None)
= Changes the socket parameter to be optional
= If socket is not specified, default to using a TwoWayPipe
= Simplified code by removing an else (self._connect)
+ [Added] async def read(self, bufsize)
= awaitable function that blocks until data has been read
= bufsize defines the maximum amount of data to be read back
(e.g. 4096 bytes)
= Reads data from TwoWayPipe
+ [Added] def write(self, data)
= Write data to TwoWayPipe
= Not awaitable as the write interface of the TwoWayPipe doesn't
have poll functionality
+ [Added] async def poll_forever(self)
= asyncio equivalent of run_forever()
* class _TwoWayPipe
+ Wrapper class for TwoWayPipe
Other Additions
- capnp/helpers/asyncHelper.h
* pollWaitScope
+ Pumps the kj event handler
+ Used for the TwoWayServer
* pollRemote
+ Polls a remote promise
+ i.e. a capnp RPC call
- capnp/helpers/asyncIoHelper.h
* AsyncIoStreamReadHelper
+ I wasn't able to figure out Promise[size_t] using Cython so this was
the next best thing I could think of doing
+ Was needed to handle read polling from a read promise
= Polling is used for asyncio as kj waits need a wrapper to be
compatible
- capnp/lib/capnp.pyx
* makeTwoWayPipe
+ Wrapper for kj newTwoWayPipe function
* poll_once
+ Single pump of the kj event handler (used with pollWaitScope)
TwoWayClient Usage - TwoWayPipe
- See examples/async_client.py
TwoWayServer Usage - TwoWayPipe
- See examples/async_server.py
capnp/helpers/asyncIoHelper.h
Misc Changes
- Fixed thread_server.py and thread_client.py to use bootstrap instead
of ez_restore
- async_client.py and async_server.py examples
* Uses the same thread.capnp as thread_client.py and thread_server.py
* They are compatible, so you can mix and match client and server for
compatibility testing
* async_client.py and async_server.py require <address>:<port>
formatting (unlike autodetection from thread_client.py and
thread_server.py)