summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2007-08-01 19:10:37 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2007-08-01 19:10:37 +0100
commit5e6fa32bf95a0d17fe5ce6a4ecdcae5dd3f967d5 (patch)
tree556ab8211323027ab3bead1a449104f7088d3372
parent65680613473b7ca39f68d25010b6b17eda841f6a (diff)
downloaddbus-python-5e6fa32bf95a0d17fe5ce6a4ecdcae5dd3f967d5.tar.gz
Add rel_path_keyword to @method (fd.o #11623)
-rw-r--r--dbus/decorators.py18
-rw-r--r--dbus/service.py25
-rwxr-xr-xtest/test-client.py23
-rwxr-xr-xtest/test-service.py15
4 files changed, 68 insertions, 13 deletions
diff --git a/dbus/decorators.py b/dbus/decorators.py
index 908d055..00cf20d 100644
--- a/dbus/decorators.py
+++ b/dbus/decorators.py
@@ -35,7 +35,8 @@ def method(dbus_interface, in_signature=None, out_signature=None,
async_callbacks=None,
sender_keyword=None, path_keyword=None, destination_keyword=None,
message_keyword=None, connection_keyword=None,
- utf8_strings=False, byte_arrays=False):
+ utf8_strings=False, byte_arrays=False,
+ rel_path_keyword=None):
"""Factory for decorators used to mark methods of a `dbus.service.Object`
to be exported on the D-Bus.
@@ -86,8 +87,20 @@ def method(dbus_interface, in_signature=None, out_signature=None,
case of "fallback paths" you'll usually want to use the object
path in the method's implementation.
+ For fallback objects, `rel_path_keyword` (new in 0.82.2) is
+ likely to be more useful.
+
:Since: 0.80.0?
+ `rel_path_keyword` : str or None
+ If not None (the default), the decorated method will receive
+ the destination object path, relative to the path at which the
+ object was exported, as a keyword argument with this
+ name. For non-fallback objects the relative path will always be
+ '/'.
+
+ :Since: 0.82.2
+
`destination_keyword` : str or None
If not None (the default), the decorated method will receive
the destination bus name as a keyword argument with this name.
@@ -150,6 +163,8 @@ def method(dbus_interface, in_signature=None, out_signature=None,
if sender_keyword:
args.remove(sender_keyword)
+ if rel_path_keyword:
+ args.remove(rel_path_keyword)
if path_keyword:
args.remove(path_keyword)
if destination_keyword:
@@ -174,6 +189,7 @@ def method(dbus_interface, in_signature=None, out_signature=None,
func._dbus_out_signature = out_signature
func._dbus_sender_keyword = sender_keyword
func._dbus_path_keyword = path_keyword
+ func._dbus_rel_path_keyword = rel_path_keyword
func._dbus_destination_keyword = destination_keyword
func._dbus_message_keyword = message_keyword
func._dbus_connection_keyword = connection_keyword
diff --git a/dbus/service.py b/dbus/service.py
index 8ffec3e..21165c5 100644
--- a/dbus/service.py
+++ b/dbus/service.py
@@ -33,7 +33,7 @@ except ImportError:
import _dbus_bindings
from dbus import SessionBus, Signature, Struct, validate_bus_name, \
- validate_object_path, INTROSPECTABLE_IFACE
+ validate_object_path, INTROSPECTABLE_IFACE, ObjectPath
from dbus.decorators import method, signal
from dbus.exceptions import DBusException, \
NameExistsException, \
@@ -653,6 +653,29 @@ class Object(Interface):
keywords[parent_method._dbus_sender_keyword] = message.get_sender()
if parent_method._dbus_path_keyword:
keywords[parent_method._dbus_path_keyword] = message.get_path()
+ if parent_method._dbus_rel_path_keyword:
+ path = message.get_path()
+ rel_path = path
+ for exp in self._locations:
+ # pathological case: if we're exported in two places,
+ # one of which is a subtree of the other, then pick the
+ # subtree by preference (i.e. minimize the length of
+ # rel_path)
+ if exp[0] is connection:
+ if path == exp[1]:
+ rel_path = '/'
+ break
+ if exp[1] == '/':
+ # we already have rel_path == path at the beginning
+ continue
+ if path.startswith(exp[1] + '/'):
+ # yes we're in this exported subtree
+ suffix = path[len(exp[1]):]
+ if len(suffix) < len(rel_path):
+ rel_path = suffix
+ rel_path = ObjectPath(rel_path)
+ keywords[parent_method._dbus_rel_path_keyword] = rel_path
+
if parent_method._dbus_destination_keyword:
keywords[parent_method._dbus_destination_keyword] = message.get_destination()
if parent_method._dbus_message_keyword:
diff --git a/test/test-client.py b/test/test-client.py
index 050ed46..085c208 100755
--- a/test/test-client.py
+++ b/test/test-client.py
@@ -422,17 +422,32 @@ class TestDBusBindings(unittest.TestCase):
def testFallbackObjectTrivial(self):
obj = self.bus.get_object(NAME, OBJECT + '/Fallback')
iface = dbus.Interface(obj, IFACE)
- path, unique_name = iface.TestPathAndConnKeywords()
+ path, rel, unique_name = iface.TestPathAndConnKeywords()
self.assertEquals(path, OBJECT + '/Fallback')
- #self.assertEquals(rel, '/Badger/Mushroom')
+ self.assertEquals(rel, '/')
+ self.assertEquals(unique_name, obj.bus_name)
+
+ def testFallbackObjectNested(self):
+ obj = self.bus.get_object(NAME, OBJECT + '/Fallback/Nested')
+ iface = dbus.Interface(obj, IFACE)
+ path, rel, unique_name = iface.TestPathAndConnKeywords()
+ self.assertEquals(path, OBJECT + '/Fallback/Nested')
+ self.assertEquals(rel, '/')
+ self.assertEquals(unique_name, obj.bus_name)
+
+ obj = self.bus.get_object(NAME, OBJECT + '/Fallback/Nested/Badger/Mushroom')
+ iface = dbus.Interface(obj, IFACE)
+ path, rel, unique_name = iface.TestPathAndConnKeywords()
+ self.assertEquals(path, OBJECT + '/Fallback/Nested/Badger/Mushroom')
+ self.assertEquals(rel, '/Badger/Mushroom')
self.assertEquals(unique_name, obj.bus_name)
def testFallbackObject(self):
obj = self.bus.get_object(NAME, OBJECT + '/Fallback/Badger/Mushroom')
iface = dbus.Interface(obj, IFACE)
- path, unique_name = iface.TestPathAndConnKeywords()
+ path, rel, unique_name = iface.TestPathAndConnKeywords()
self.assertEquals(path, OBJECT + '/Fallback/Badger/Mushroom')
- #self.assertEquals(rel, '/Badger/Mushroom')
+ self.assertEquals(rel, '/Badger/Mushroom')
self.assertEquals(unique_name, obj.bus_name)
def testTimeoutSync(self):
diff --git a/test/test-service.py b/test/test-service.py
index 4488eb1..10bebc5 100755
--- a/test/test-service.py
+++ b/test/test-service.py
@@ -74,20 +74,21 @@ class TestInterface(dbus.service.Interface):
return False
class Fallback(dbus.service.FallbackObject):
- def __init__(self, bus_name, object_path=OBJECT + '/Fallback'):
- super(Fallback, self).__init__(bus_name, object_path)
+ def __init__(self, conn, object_path=OBJECT + '/Fallback'):
+ super(Fallback, self).__init__(conn, object_path)
+ self.add_to_connection(conn, object_path + '/Nested')
- @dbus.service.method(IFACE, in_signature='', out_signature='os',
- path_keyword='path', # rel_path_keyword='rel',
+ @dbus.service.method(IFACE, in_signature='', out_signature='oos',
+ path_keyword='path', rel_path_keyword='rel',
connection_keyword='conn')
- def TestPathAndConnKeywords(self, path=None, conn=None):
- return path, conn.get_unique_name()
+ def TestPathAndConnKeywords(self, path=None, conn=None, rel=None):
+ return path, rel, conn.get_unique_name()
@dbus.service.signal(IFACE, signature='s', rel_path_keyword='rel_path')
def SignalOneString(self, test, rel_path=None):
logger.info('SignalOneString(%r) @ %r', test, rel_path)
- # Deprecated
+ # Deprecated usage
@dbus.service.signal(IFACE, signature='ss', path_keyword='path')
def SignalTwoStrings(self, test, test2, path=None):
logger.info('SignalTwoStrings(%r, %r) @ %r', test, test2, path)