summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Hofstee <jhofstee@victronenergy.com>2022-10-10 14:54:43 +0200
committerSimon McVittie <smcv@collabora.com>2023-08-16 13:09:23 +0100
commite23e06c08e5c3c691cdde616b9f539cba16c60b8 (patch)
treef972745bbc5be391129033755b1d8d57b38ecf9a
parentd8c0e6ae3223085379f18164f9e102f7c3eea58a (diff)
Add support for arg0namespace in add_signal_receiver
Match messages whose first argument is a string and start with the value given to arg0namespace. This is primarily intended for watching name owner changes for a group of related bus names, rather than for a single name or all name changes. Signed-off-by: Jeroen Hofstee <jhofstee@victronenergy.com>
-rw-r--r--dbus/connection.py24
-rw-r--r--dbus/proxies.py5
2 files changed, 27 insertions, 2 deletions
diff --git a/dbus/connection.py b/dbus/connection.py
index 46d74d4..621e54b 100644
--- a/dbus/connection.py
+++ b/dbus/connection.py
@@ -55,7 +55,9 @@ class SignalMatch(object):
'_byte_arrays', '_conn_weakref',
'_destination_keyword', '_interface_keyword',
'_message_keyword', '_member_keyword',
- '_sender_keyword', '_path_keyword', '_int_args_match']
+ '_sender_keyword', '_path_keyword', '_int_args_match',
+ '_arg0namespace'
+ ]
__slots__ = tuple(_slots)
@@ -64,7 +66,7 @@ class SignalMatch(object):
sender_keyword=None, path_keyword=None,
interface_keyword=None, member_keyword=None,
message_keyword=None, destination_keyword=None,
- **kwargs):
+ arg0namespace=None, **kwargs):
if member is not None:
validate_member_name(member)
if dbus_interface is not None:
@@ -80,6 +82,7 @@ class SignalMatch(object):
self._interface = dbus_interface
self._member = member
self._path = object_path
+ self._arg0namespace = arg0namespace
self._handler = handler
# if the connection is actually a bus, it's responsible for changing
@@ -141,6 +144,8 @@ class SignalMatch(object):
rule.append("interface='%s'" % self._interface)
if self._member is not None:
rule.append("member='%s'" % self._member)
+ if self._arg0namespace is not None:
+ rule.append("arg0namespace='%s'" % self._arg0namespace)
if self._int_args_match is not None:
for index, value in self._int_args_match.items():
rule.append("arg%d='%s'" % (index, value))
@@ -187,6 +192,16 @@ class SignalMatch(object):
or not isinstance(args[index], String)
or args[index] != value):
return False
+ if self._arg0namespace is not None:
+ kwargs = dict(byte_arrays=True)
+ args = message.get_args_list(**kwargs)
+ namespace_len = len(self._arg0namespace)
+ if ( len(args) == 0
+ or not isinstance(args[0], String)
+ or not args[0].startswith(self._arg0namespace)
+ or args[0][namespace_len:namespace_len + 1] not in ('', '.')
+ ):
+ return False
# these have likely already been checked by the match tree
if self._member not in (None, message.get_member()):
@@ -382,6 +397,11 @@ class Connection(_Connection):
is the value given for that keyword parameter. As of this
time only string arguments can be matched (in particular,
object paths and signatures can't).
+ `arg0namespace` : str
+ If not None (the default) match only signals where the first
+ argument is a string that either is equal to the
+ keyword parameter, or starts with the keyword parameter
+ followed by a dot (and optionally more text).
`named_service` : str
A deprecated alias for `bus_name`.
"""
diff --git a/dbus/proxies.py b/dbus/proxies.py
index 487976c..a31b5ea 100644
--- a/dbus/proxies.py
+++ b/dbus/proxies.py
@@ -361,6 +361,11 @@ class ProxyObject(object):
is the value given for that keyword parameter. As of this time
only string arguments can be matched (in particular,
object paths and signatures can't).
+ `arg0namespace` : str
+ If not None (the default) match only signals where the first
+ argument is a string that either is equal to the
+ keyword parameter, or starts with the keyword parameter
+ followed by a dot (and optionally more text).
"""
return \
self._bus.add_signal_receiver(handler_function,