[PATCH] dbus.service: Make it possible to unexport objects (fd.o#10457)

Simon McVittie simon.mcvittie at collabora.co.uk
Wed May 30 07:22:08 PDT 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

- ---
 dbus/service.py      |   33 ++++++++++++++++++++++++++++++++-
 test/test-client.py  |   20 ++++++++++++++++++++
 test/test-service.py |   34 +++++++++++++++++++++++++++++++---
 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()
- -- 
1.5.2-rc3.GIT

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: OpenPGP key: http://www.pseudorandom.co.uk/2003/contact/ or pgp.net

iD8DBQFGXYiQWSc8zVUw7HYRAnOuAJ0UCmyu4GuXdue/OIGO7OxYrTu6cwCgpMZh
Bo4jHHuinvm4U468kpZTL04=
=1E2M
-----END PGP SIGNATURE-----


More information about the dbus mailing list