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

John (J5) Palmieri johnp at redhat.com
Wed May 30 12:55:55 PDT 2007


I don't like the name unexport.  remove_from_bus or
remove_from_connection is clearer.

On Wed, 2007-05-30 at 15:22 +0100, Simon McVittie wrote:
> -----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-----
> _______________________________________________
> dbus mailing list
> dbus at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dbus
-- 
John (J5) Palmieri <johnp at redhat.com>



More information about the dbus mailing list