Skip to content

Commit 2ff9642

Browse files
committed
Support strongly typed signals
In addition to properties and methods, the arguments of a signal have also types which can be defined with `TypedSignal`, a subclass of `signal`.
1 parent 14338be commit 2ff9642

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

pydbus/strong_typing.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Decorators for methods and properties to strongly typed the values."""
22
import inspect
33

4+
from pydbus.generic import signal
45
from pydbus.xml_generator import verify_arguments
56

67

@@ -34,3 +35,10 @@ def decorate(func):
3435
verify_arguments(func)
3536
return func
3637
return decorate
38+
39+
40+
class TypedSignal(signal):
41+
42+
def __init__(self, arguments):
43+
super(TypedSignal, self).__init__()
44+
self.arg_types = arguments

pydbus/xml_generator.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
from xml.etree import ElementTree
66

7+
from pydbus.generic import signal
8+
79

810
PROPERTY_EMITS_SIGNAL = "org.freedesktop.DBus.Property.EmitsChangedSignal"
911

@@ -145,7 +147,7 @@ def valid_member(member):
145147
"""Only select members with the correct type and name."""
146148
if isinstance(member, property):
147149
member = member.fget
148-
elif not ismethod(member):
150+
elif not ismethod(member) and not isinstance(member, signal):
149151
return False
150152
return member.__name__[0].isupper()
151153

@@ -186,6 +188,17 @@ def valid_member(member):
186188
entry, "annotation",
187189
{"name": PROPERTY_EMITS_SIGNAL, "value": "true"})
188190
attributes["access"] = "readwrite"
191+
elif isinstance(value, signal):
192+
if hasattr(value, "arguments"):
193+
arguments = value.arguments
194+
elif require_strong_typing:
195+
raise ValueError(
196+
"No argument definitions for signal "
197+
"'{}'".format(value.__name__))
198+
entry = ElementTree.SubElement(value, "signal")
199+
for arg, arg_type in arguments:
200+
ElementTree.SubElement(
201+
entry, "arg", {"name": arg, "type": arg_type})
189202
elif ismethod(value):
190203
arg_types, ret_type = verify_arguments(value)
191204
entry = ElementTree.SubElement(get_interface(value), "method")

0 commit comments

Comments
 (0)