summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2023-08-16 12:25:41 +0000
committerSimon McVittie <smcv@collabora.com>2023-08-16 12:25:41 +0000
commitaf204e52ddae8084516a98bbf2f75f58ee1de353 (patch)
tree6af106bb7a09476702c041b2b3be237e431cd4dc
parentd8c0e6ae3223085379f18164f9e102f7c3eea58a (diff)
parentd159c6115f53b83b934e5537ba94268ce4bffa49 (diff)
Merge branch 'arg0namespace' into 'master'
Add support for arg0namespace in add_signal_receiver See merge request dbus/dbus-python!27
-rw-r--r--dbus/connection.py24
-rw-r--r--dbus/proxies.py5
-rwxr-xr-xtest/test-standalone.py36
3 files changed, 63 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,
diff --git a/test/test-standalone.py b/test/test-standalone.py
index c091228..7cca6a0 100755
--- a/test/test-standalone.py
+++ b/test/test-standalone.py
@@ -581,6 +581,42 @@ class TestMatching(unittest.TestCase):
self._message.append('/', signature='o')
self.assertFalse(self._match.maybe_handle_message(self._message))
+class TestArg0Namespace(unittest.TestCase):
+ def setUp(self):
+ self._match = dbus.connection.SignalMatch(object, None, '/', None, None,
+ None, arg0namespace='org.freedesktop.dbus-python')
+
+ def test_invalid_arg1namespace(self):
+ try:
+ dbus.connection.SignalMatch(object, None, '/', None, None,
+ None, arg1namespace='org.freedesktop.dbus-python')
+ except TypeError:
+ pass
+ else:
+ raise AssertionError('arg1namespace is not a valid keyword argument')
+
+ def test_namespace_match(self):
+ message = _dbus_bindings.SignalMessage('/', 'a.b', 'c')
+ message.append('org.freedesktop.dbus-python', signature='s')
+ self.assertTrue(self._match.maybe_handle_message(message))
+
+ def test_namespace_match2(self):
+ message = _dbus_bindings.SignalMessage('/', 'a.b', 'c')
+ message.append('org.freedesktop.dbus-python.test', signature='s')
+ self.assertTrue(self._match.maybe_handle_message(message))
+
+ def test_namespace_mismatch(self):
+ message = _dbus_bindings.SignalMessage('/', 'a.b', 'c')
+ message.append('org.freedesktop.dbus-python-test', signature='s')
+ self.assertFalse(self._match.maybe_handle_message(message))
+
+ def test_namespace_type_mismatch(self):
+ match = dbus.connection.SignalMatch(object, None, '/', None, None,
+ None, arg0namespace='1')
+ message = _dbus_bindings.SignalMessage('/', 'a.b', 'c')
+ message.append(1, signature='i')
+ self.assertFalse(match.maybe_handle_message(message))
+
class TestVersion(unittest.TestCase):
if sys.version_info[:2] < (2, 7):
def assertGreater(self, first, second):