dbus-python: Binding names lazily without using follow_name_owner_changes

Neal H. Walfield neal at walfield.org
Sat Nov 26 13:48:21 PST 2011


Hi,

I have a python module.  If I create a dbus.Interface and the server
quits, calling another method on the interface results in a DBus
exception (namely 'org.freedesktop.DBus.Error.ServiceUnknown'), which
is expected as dbus-python strongly binds the server's name to the
object.

I know about 'follow_name_owner_changes', but I want my module to work
even if the program does not use a main loop.

The attached code appears to do what I require.  Have I overlooking
something?

Thanks for your help,

Neal


class DBusIndirectObject(object):
    __slots__ = ('bus', 'args', 'kwargs', 'real_object')
    def __init__(self, bus, *args, **kwargs):
        self.bus = bus
        self.args = args
        self.kwargs = kwargs
        self.bind_object()

    def bind_object(self):
        self.real_object = self.bus.get_object(*self.args, **self.kwargs)

    def __getattr__(self, attr):
        if attr in self.__slots__:
            return super(DBusIndirectObject, self).__getattr__(attr)
        return getattr(self.real_object, attr)

    def __setattr__(self, attr, value):
        if attr in self.__slots__:
            return super(DBusIndirectObject, self).__setattr__(attr, value)
        return setattr(self.real_object, attr, value)

    def get_dbus_method(self, *args, **kwargs):
        def wrap(*m_args, **m_kwargs):
            def invoke():
                m = self.real_object.get_dbus_method(*args, **kwargs)
                return m(*m_args, **m_kwargs)
            try:
                return invoke()
            except dbus.exceptions.DBusException, exception:
                try:
                    dbus_name = str (exception.get_dbus_name ())
                except AttributeError:
                    dbus_name = ""
                if dbus_name == "org.freedesktop.DBus.Error.ServiceUnknown":
                    self.bind_object()
                    return invoke()
                else:
                    raise

        return wrap


More information about the dbus mailing list