feat: allow varargs callback for signals (#22)
This commit is contained in:
parent
f4d173e042
commit
a3379c74ad
@ -118,8 +118,10 @@ class BaseProxyInterface:
|
|||||||
def _add_signal(self, intr_signal, interface):
|
def _add_signal(self, intr_signal, interface):
|
||||||
def on_signal_fn(fn):
|
def on_signal_fn(fn):
|
||||||
fn_signature = inspect.signature(fn)
|
fn_signature = inspect.signature(fn)
|
||||||
if not callable(fn) or len(fn_signature.parameters) != len(
|
if len(fn_signature.parameters) != len(intr_signal.args) and (
|
||||||
intr_signal.args
|
inspect.Parameter.VAR_POSITIONAL
|
||||||
|
not in [par.kind for par in fn_signature.parameters.values()]
|
||||||
|
or len(fn_signature.parameters) - 1 > len(intr_signal.args)
|
||||||
):
|
):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
f"reply_notify must be a function with {len(intr_signal.args)} parameters"
|
f"reply_notify must be a function with {len(intr_signal.args)} parameters"
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import pytest
|
|||||||
|
|
||||||
from dbus_fast import Message
|
from dbus_fast import Message
|
||||||
from dbus_fast.aio import MessageBus
|
from dbus_fast.aio import MessageBus
|
||||||
|
from dbus_fast.aio.proxy_object import ProxyInterface
|
||||||
from dbus_fast.constants import RequestNameReply
|
from dbus_fast.constants import RequestNameReply
|
||||||
from dbus_fast.introspection import Node
|
from dbus_fast.introspection import Node
|
||||||
from dbus_fast.service import ServiceInterface, signal
|
from dbus_fast.service import ServiceInterface, signal
|
||||||
@ -158,6 +159,100 @@ async def test_signals():
|
|||||||
bus3.disconnect()
|
bus3.disconnect()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_varargs_callback():
|
||||||
|
"""Test varargs callback for signal."""
|
||||||
|
bus1 = await MessageBus().connect()
|
||||||
|
bus2 = await MessageBus().connect()
|
||||||
|
|
||||||
|
await bus1.request_name("test.signals.name")
|
||||||
|
service_interface = ExampleInterface()
|
||||||
|
bus1.export("/test/path", service_interface)
|
||||||
|
|
||||||
|
obj = bus2.get_proxy_object(
|
||||||
|
"test.signals.name", "/test/path", bus1._introspect_export_path("/test/path")
|
||||||
|
)
|
||||||
|
interface = obj.get_interface(service_interface.name)
|
||||||
|
|
||||||
|
async def ping():
|
||||||
|
await bus2.call(
|
||||||
|
Message(
|
||||||
|
destination=bus1.unique_name,
|
||||||
|
interface="org.freedesktop.DBus.Peer",
|
||||||
|
path="/test/path",
|
||||||
|
member="Ping",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
varargs_handler_counter = 0
|
||||||
|
varargs_handler_err = None
|
||||||
|
varargs_plus_handler_counter = 0
|
||||||
|
varargs_plus_handler_err = None
|
||||||
|
|
||||||
|
def varargs_handler(*args):
|
||||||
|
nonlocal varargs_handler_counter
|
||||||
|
nonlocal varargs_handler_err
|
||||||
|
try:
|
||||||
|
assert args[0] == "hello"
|
||||||
|
varargs_handler_counter += 1
|
||||||
|
except AssertionError as ex:
|
||||||
|
varargs_handler_err = ex
|
||||||
|
|
||||||
|
def varargs_plus_handler(value, *_):
|
||||||
|
nonlocal varargs_plus_handler_counter
|
||||||
|
nonlocal varargs_plus_handler_err
|
||||||
|
try:
|
||||||
|
assert value == "hello"
|
||||||
|
varargs_plus_handler_counter += 1
|
||||||
|
except AssertionError as ex:
|
||||||
|
varargs_plus_handler_err = ex
|
||||||
|
|
||||||
|
interface.on_some_signal(varargs_handler)
|
||||||
|
interface.on_some_signal(varargs_plus_handler)
|
||||||
|
await ping()
|
||||||
|
|
||||||
|
service_interface.SomeSignal()
|
||||||
|
await ping()
|
||||||
|
assert varargs_handler_err is None
|
||||||
|
assert varargs_handler_counter == 1
|
||||||
|
assert varargs_plus_handler_err is None
|
||||||
|
assert varargs_plus_handler_counter == 1
|
||||||
|
|
||||||
|
bus1.disconnect()
|
||||||
|
bus2.disconnect()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_on_signal_type_error():
|
||||||
|
"""Test on callback raises type errors for invalid callbacks."""
|
||||||
|
bus1 = await MessageBus().connect()
|
||||||
|
bus2 = await MessageBus().connect()
|
||||||
|
|
||||||
|
await bus1.request_name("test.signals.name")
|
||||||
|
service_interface = ExampleInterface()
|
||||||
|
bus1.export("/test/path", service_interface)
|
||||||
|
|
||||||
|
obj = bus2.get_proxy_object(
|
||||||
|
"test.signals.name", "/test/path", bus1._introspect_export_path("/test/path")
|
||||||
|
)
|
||||||
|
interface = obj.get_interface(service_interface.name)
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
interface.on_some_signal("not_a_callable")
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
interface.on_some_signal(lambda a, b: "Too many parameters")
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
interface.on_some_signal(lambda: "Too few parameters")
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
interface.on_some_signal(lambda a, b, *args: "Too many before varargs")
|
||||||
|
|
||||||
|
bus1.disconnect()
|
||||||
|
bus2.disconnect()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_signals_with_changing_owners():
|
async def test_signals_with_changing_owners():
|
||||||
well_known_name = "test.signals.changing.name"
|
well_known_name = "test.signals.changing.name"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user