Skip to content

Commit

Permalink
support signatures to signal decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
Anders Hellerup Madsen committed Jan 6, 2022
1 parent a7758c3 commit cecfe43
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
13 changes: 6 additions & 7 deletions dbus_next/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,16 @@ def wrapped(*args, **kwargs):


class _Signal:
def __init__(self, fn, name, disabled=False):
def __init__(self, fn, name, disabled=False, signature: Optional[str] = None):
inspection = inspect.signature(fn)

args = []
signature = ''
signature_tree = None

return_annotation = parse_annotation(inspection.return_annotation)
if signature is None:
signature = parse_annotation(inspection.return_annotation)

if return_annotation:
signature = return_annotation
if signature:
signature_tree = SignatureTree._get(signature)
for type_ in signature_tree.types:
args.append(intr.Arg(type_, intr.ArgDirection.OUT))
Expand All @@ -132,7 +131,7 @@ def __init__(self, fn, name, disabled=False):
self.introspection = intr.Signal(self.name, args)


def signal(name: str = None, disabled: bool = False):
def signal(name: str = None, disabled: bool = False, signature: Optional[str] = None):
"""A decorator to mark a class method of a :class:`ServiceInterface` to be a DBus signal.
The signal is broadcast on the bus when the decorated class method is
Expand Down Expand Up @@ -170,7 +169,7 @@ def two_strings_signal(self, val1, val2) -> 'ss':
@no_type_check_decorator
def decorator(fn):
fn_name = name if name else fn.__name__
signal = _Signal(fn, fn_name, disabled)
signal = _Signal(fn, fn_name, disabled, signature)

@wraps(fn)
def wrapped(self, *args, **kwargs):
Expand Down
16 changes: 13 additions & 3 deletions test/service/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def foo_prop(self) -> int:
def foo_prop(self, val: int):
self._foo_prop = val

@signal(signature="as")
def foo_signal(self) -> List[str]:
return ['result']


def test_method_decorator():
interface = ExampleInterface()
Expand Down Expand Up @@ -96,7 +100,7 @@ def test_method_decorator():
assert not method.disabled
assert type(method.introspection) is intr.Method

assert len(signals) == 2
assert len(signals) == 3

signal = signals[0]
assert signal.name == 'renamed_signal'
Expand All @@ -105,6 +109,12 @@ def test_method_decorator():
assert type(signal.introspection) is intr.Signal

signal = signals[1]
assert signal.name == 'foo_signal'
assert signal.signature == 'as'
assert not signal.disabled
assert type(signal.introspection) is intr.Signal

signal = signals[2]
assert signal.name == 'some_signal'
assert signal.signature == 'as'
assert not signal.disabled
Expand Down Expand Up @@ -177,7 +187,7 @@ def test_interface_introspection():
signals = xml.findall('signal')
properties = xml.findall('property')

assert len(xml) == 6
assert len(xml) == 7
assert len(methods) == 2
assert len(signals) == 1
assert len(signals) == 2
assert len(properties) == 3

0 comments on commit cecfe43

Please sign in to comment.