1
0
Fork 0
mirror of https://github.com/deltachat/deltachat-core.git synced 2025-10-04 18:29:19 +02:00

Add support for the callback in python/cffi

This uses one global event handler function on the C level, as
enforced by CFFI, and caters for registering a per-context event
handeler.  A simple fixture for doing this during tests is also
implemented.
This commit is contained in:
Floris Bruynooghe 2018-07-22 13:46:09 +02:00
parent ee6798ec0e
commit 08689b2a04
4 changed files with 47 additions and 4 deletions

View file

@ -0,0 +1,14 @@
from deltachat import capi
_DC_CALLBACK_MAP = {}
@capi.ffi.def_extern()
def py_dc_callback(ctx, evt, data1, data2):
"""The global event handler.
CFFI only allows us to set one global event handler, so this one
looks up the correct event handler for the given context.
"""
return _DC_CALLBACK_MAP.get(ctx, lambda *a: 0)

View file

@ -28,6 +28,13 @@ def ffibuilder():
output_file=dst_fp.name, output_file=dst_fp.name,
macros=[('PY_CFFI', '1')]) macros=[('PY_CFFI', '1')])
builder.cdef(dst_fp.read()) builder.cdef(dst_fp.read())
builder.cdef("""
extern "Python" uintptr_t py_dc_callback(
dc_context_t* context,
int event,
uintptr_t data1,
uintptr_t data2);
""")
return builder return builder

15
python/tests/conftest.py Normal file
View file

@ -0,0 +1,15 @@
import pytest
import deltachat
@pytest.fixture
def register_dc_callback(monkeypatch):
"""Register a callback for a given context.
This is a function-scoped fixture and the function will be
unregisterd automatically on fixture teardown.
"""
def register_dc_callback(ctx, func):
monkeypatch.setitem(deltachat._DC_CALLBACK_MAP, ctx, func)
return register_dc_callback

View file

@ -1,10 +1,17 @@
import pathlib import deltachat
import pytest
from deltachat import capi from deltachat import capi
def test_empty_context(): def test_empty_context():
ctx = capi.lib.dc_context_new(capi.ffi.NULL, capi.ffi.NULL, capi.ffi.NULL) ctx = capi.lib.dc_context_new(capi.ffi.NULL, capi.ffi.NULL, capi.ffi.NULL)
capi.lib.dc_close(ctx) capi.lib.dc_close(ctx)
def test_cb(register_dc_callback):
def cb(ctx, evt, data1, data2):
return 0
ctx = capi.lib.dc_context_new(capi.lib.py_dc_callback,
capi.ffi.NULL, capi.ffi.NULL)
register_dc_callback(ctx, cb)
capi.lib.dc_close(ctx)
assert deltachat._DC_CALLBACK_MAP[ctx] is cb