summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dbus/service.py33
-rwxr-xr-xtest/test-client.py20
-rwxr-xr-xtest/test-service.py34
3 files changed, 83 insertions, 4 deletions
diff --git a/dbus/service.py b/dbus/service.py
index be30b9b..65af3ff 100644
--- a/dbus/service.py
+++ b/dbus/service.py
@@ -380,7 +380,7 @@ class Object(Interface):
is also required.
:Parameters:
- `conn` : dbus.Connection
+ `conn` : dbus.connection.Connection
The connection on which to export this object.
If None, use the Bus associated with the given ``bus_name``,
@@ -426,6 +426,37 @@ class Object(Interface):
__dbus_object_path__ = property(lambda self: self._object_path, None, None,
"The D-Bus object path of this object")
+ def unexport(self, connection=None, path=None):
+ """Unexport this object. It will no longer be accessible via D-Bus.
+
+ It's not currently possible to export an object on more than one
+ connection or with more than one object-path, but this will be
+ supported in future.
+
+ :Parameters:
+ `connection` : dbus.connection.Connection or None
+ Only unexport the object from this Connection. If None,
+ unexport from all Connections.
+ `path` : dbus.ObjectPath or other str, or None
+ Only unexport the object from this object path. If None,
+ unexport from all object paths.
+ :Raises LookupError:
+ if the object was not exported on the requested connection
+ or path, or (if both are None) was not exported at all.
+ """
+ if self._object_path is None or self._connection is None:
+ raise LookupError('%r is not exported' % self)
+ if path is not None and self._object_path != path:
+ raise LookupError('%r is not exported at path %r' % (self, path))
+ if connection is not None and self._connection != connection:
+ raise LookupError('%r is not exported on %r' % (self, connection))
+
+ try:
+ self._connection._unregister_object_path(self._object_path)
+ finally:
+ self._connection = None
+ self._object_path = None
+
def _unregister_cb(self, connection):
_logger.info('Unregistering exported object %r', self)
diff --git a/test/test-client.py b/test/test-client.py
index 2de34fb..fbf0555 100755
--- a/test/test-client.py
+++ b/test/test-client.py
@@ -388,6 +388,26 @@ class TestDBusBindings(unittest.TestCase):
def testListExportedChildObjects(self):
self.assert_(self.iface.TestListExportedChildObjects())
+ def testUnexport(self):
+ # https://bugs.freedesktop.org/show_bug.cgi?id=10457
+ self.assert_(not self.iface.HasRemovableObject())
+ self.assert_(self.iface.AddRemovableObject())
+ self.assert_(self.iface.HasRemovableObject())
+
+ removable = self.bus.get_object(NAME, OBJECT + '/RemovableObject')
+ iface = dbus.Interface(removable, IFACE)
+ self.assert_(iface.IsThere())
+ self.assert_(iface.RemoveSelf())
+
+ self.assert_(not self.iface.HasRemovableObject())
+
+ # and again...
+ self.assert_(self.iface.AddRemovableObject())
+ self.assert_(self.iface.HasRemovableObject())
+ self.assert_(iface.IsThere())
+ self.assert_(iface.RemoveSelf())
+ self.assert_(not self.iface.HasRemovableObject())
+
""" Remove this for now
class TestDBusPythonToGLibBindings(unittest.TestCase):
def setUp(self):
diff --git a/test/test-service.py b/test/test-service.py
index c27c55f..8f588c8 100755
--- a/test/test-service.py
+++ b/test/test-service.py
@@ -48,6 +48,20 @@ NAME = "org.freedesktop.DBus.TestSuitePythonService"
IFACE = "org.freedesktop.DBus.TestSuiteInterface"
OBJECT = "/org/freedesktop/DBus/TestSuitePythonObject"
+class RemovableObject(dbus.service.Object):
+ # Part of test for https://bugs.freedesktop.org/show_bug.cgi?id=10457
+ def __init__(self, bus_name, object_path=OBJECT + '/RemovableObject'):
+ super(RemovableObject, self).__init__(bus_name, object_path)
+
+ @dbus.service.method(IFACE, in_signature='', out_signature='b')
+ def IsThere(self):
+ return True
+
+ @dbus.service.method(IFACE, in_signature='', out_signature='b')
+ def RemoveSelf(self):
+ self.unexport()
+ return True
+
class TestGObject(ExportedGObject):
def __init__(self, bus_name, object_path=OBJECT + '/GObject'):
super(TestGObject, self).__init__(bus_name, object_path)
@@ -64,6 +78,7 @@ class TestInterface(dbus.service.Interface):
class TestObject(dbus.service.Object, TestInterface):
def __init__(self, bus_name, object_path=OBJECT):
dbus.service.Object.__init__(self, bus_name, object_path)
+ self._removables = []
""" Echo whatever is sent
"""
@@ -210,14 +225,27 @@ class TestObject(dbus.service.Object, TestInterface):
def WhoAmI(self, sender):
return sender
+ @dbus.service.method(IFACE, in_signature='', out_signature='b')
+ def AddRemovableObject(self):
+ # Part of test for https://bugs.freedesktop.org/show_bug.cgi?id=10457
+ # Keep the removable object reffed, since that's the use case for this
+ self._removables.append(RemovableObject(global_name))
+ return True
+
+ @dbus.service.method(IFACE, in_signature='', out_signature='b')
+ def HasRemovableObject(self):
+ # Part of test for https://bugs.freedesktop.org/show_bug.cgi?id=10457
+ objs = session_bus.list_exported_child_objects(OBJECT)
+ return ('RemovableObject' in objs)
+
@dbus.service.method(IFACE)
def MultipleReturnWithoutSignature(self):
# https://bugs.freedesktop.org/show_bug.cgi?id=10174
return dbus.String('abc'), dbus.Int32(123)
session_bus = dbus.SessionBus()
-name = dbus.service.BusName(NAME, bus=session_bus)
-object = TestObject(name)
-g_object = TestGObject(name)
+global_name = dbus.service.BusName(NAME, bus=session_bus)
+object = TestObject(global_name)
+g_object = TestGObject(global_name)
loop = gobject.MainLoop()
loop.run()