Extending Unpadded to Python¶
Unpadded API can be extended to Python quite easily, allowing you to communicate with C++ application from a Python script.
Exposing keyrings and dispatchers to Python¶
Unpadded classes can be made available to Python inside a pybind11 module. Two classes can be exposed at the moment:
upd::key
template instances through theupd::py::unpack_keyring()
upd::double_buffered_dispatcher
template instances through theupd::py::declare_dispatcher()
When exposing a keyring to Python, a Python module attribute is defined for each key in the keyring. The name of each attribute is the name of the function associated with the exposed key.
Please refer to the API documentation for further detail on the exposed classes interface.
Lazily compile your Python extension modules¶
Unpadded uses the cppimport API to allow you to import your uncompiled extension modules as if they were Python modules. If you already has some experience of cppimport, the syntax of your Mako headers will be pretty simillar. The only difference is that you will need to replace setup_pybind11(cfg) by setup_unpadded(cfg).
Note
Lazily compile extension modules will also require ccache to be installed on your computer. Theroretically, it is not needed to compile your extension modules. However, Unpadded relies on ccache to check whether the extension module needs to be recompiled. cppimport has a similar mecanism, but has to be provided an explicit list of dependencies that needs to be kept updated, so it has not been retained for Unpadded.
API References¶
unpack_keyring
¶
-
template<typename Keyring>
void upd::py::unpack_keyring(pybind11::module &pymodule, Keyring keyring)¶ Expose every key template instances from a keyring to Python.
For every key in the provided keyring, a Python class with the same name as the callback held by the key will be defined with the following methods :
encode(self, *args) -> bytes
: serialize an argument list into a sequence of bytesdecode(self, payload: bytes)
: deserialize a sequence of bytes and return the corresponding valueindex(self) -> int
: get the index associated with the key
- Template Parameters:
Keyring – Keyring holding the keys to expose
- Parameters:
pymodule – Python module inside of which the classes will be defined
declare_dispatcher
¶
-
template<typename Keyring>
void upd::py::declare_dispatcher(pybind11::module &pymodule, const char *name, Keyring keyring)¶ Expose a double_buffered_dispatcher template instance made from the given keyring.
The class will have the following methods :
read_from(self, getter: Callable[[], int]) -> unpadded.PacketStatus
: read from a byte getter until a packet is dropped on resolvedwrite_to(self, putter: Callable[[int], None]) -> None
: write to a byte putter until the internal output buffer is exhaustedput(self, x: int) -> None
: put a single byte into the input internal buffer and return the status of the current packetget(self) -> int
: get a single byte from the ouput interna bufferis_loaded(self) -> bool
: check whether a packet is loaded in the output bufferreplace(self, key, f: Callable) -> None
: replace the behavior of the action designated bykey
byf
(Python callbacks are supported)
Note
The provided keyring is unpacked.
- Template Parameters:
Keyring – Keyring holding the keys to expose
- Parameters:
name – Name for the Python class bound to the dispatcher
pymodule – Python module inside of which the classes will be defined