[PATCH 11/17] Convert _BusDaemonMixin and _MethodCallMixin into base classes BusConnection and Connection.

Simon McVittie simon.mcvittie at collabora.co.uk
Mon Apr 30 03:56:42 PDT 2007


Also add method activate_name_owner() for proxies to use (so they don't need
to be aware of whether the connection is a bus daemon or not), and stop using
deprecated get_connection method.

diff --git a/dbus/_dbus.py b/dbus/_dbus.py
index fc070ae..48c623b 100644
--- a/dbus/_dbus.py
+++ b/dbus/_dbus.py
@@ -37,14 +37,12 @@ from _dbus_bindings import BUS_DAEMON_NAME, BUS_DAEMON_PATH,\
                            validate_member_name, validate_interface_name,\
                            validate_bus_name, validate_object_path,\
                            BUS_SESSION, BUS_SYSTEM, BUS_STARTER,\
-                           Connection as _Connection,\
                            DBUS_START_REPLY_SUCCESS, \
                            DBUS_START_REPLY_ALREADY_RUNNING, \
                            SignalMessage,\
                            HANDLER_RESULT_NOT_YET_HANDLED,\
                            HANDLER_RESULT_HANDLED
-from dbus.bus import _BusDaemonMixin
-from dbus.connection import _MethodCallMixin
+from dbus.bus import BusConnection
 from dbus.proxies import ProxyObject
 
 try:
@@ -228,7 +226,7 @@ class SignalMatch(object):
                                         **self._args_match)
 
 
-class Bus(_Connection, _MethodCallMixin, _BusDaemonMixin):
+class Bus(BusConnection):
     """A connection to a DBus daemon.
 
     One of three possible standard buses, the SESSION, SYSTEM,
@@ -324,7 +322,7 @@ class Bus(_Connection, _MethodCallMixin, _BusDaemonMixin):
         t = self._bus_type
         if self.__class__._shared_instances[t] is self:
             del self.__class__._shared_instances[t]
-        _Connection.close(self)
+        super(BusConnection, self).close()
 
     def get_connection(self):
         """(Deprecated - in new code, just use self)
diff --git a/dbus/bus.py b/dbus/bus.py
index 6899b12..e5356d2 100644
--- a/dbus/bus.py
+++ b/dbus/bus.py
@@ -1,5 +1,3 @@
-"""Bus mixin, for use within dbus-python only. See `_BusMixin`."""
-
 # Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
 #
 # Licensed under the Academic Free License version 2.1
@@ -21,15 +19,33 @@
 from _dbus_bindings import validate_interface_name, validate_member_name,\
                            validate_bus_name, validate_object_path,\
                            validate_error_name,\
+                           DBusException, \
                            BUS_DAEMON_NAME, BUS_DAEMON_PATH, BUS_DAEMON_IFACE
+from dbus.connection import Connection
 
 
-class _BusDaemonMixin(object):
+class BusConnection(Connection):
     """This mixin provides simple blocking wrappers for various methods on
     the org.freedesktop.DBus bus-daemon object, to reduce the amount of C
     code we need.
     """
 
+    def activate_name_owner(self, bus_name):
+        if (bus_name is not None and bus_name[:1] != ':'
+            and bus_name != BUS_DAEMON_NAME):
+            try:
+                return self.get_name_owner(bus_name)
+            except DBusException, e:
+                # FIXME: detect whether it's NameHasNoOwner, but properly
+                #if not str(e).startswith('org.freedesktop.DBus.Error.NameHasNoOwner:'):
+                #    raise
+                # it might not exist: try to start it
+                self.start_service_by_name(bus_name)
+                return self.get_name_owner(bus_name)
+        else:
+            # already unique
+            return bus_name
+
     def get_unix_user(self, bus_name):
         """Get the numeric uid of the process owning the given bus name.
 
diff --git a/dbus/connection.py b/dbus/connection.py
index 36a9a7b..b78e221 100644
--- a/dbus/connection.py
+++ b/dbus/connection.py
@@ -1,7 +1,3 @@
-"""Method-call mixin for use within dbus-python only.
-See `_MethodCallMixin`.
-"""
-
 # Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
 #
 # Licensed under the Academic Free License version 2.1
@@ -22,7 +18,7 @@ See `_MethodCallMixin`.
 
 import logging
 
-from _dbus_bindings import Connection, ErrorMessage, \
+from _dbus_bindings import Connection as _Connection, ErrorMessage, \
                            MethodCallMessage, MethodReturnMessage, \
                            DBusException, LOCAL_PATH, LOCAL_IFACE
 
@@ -34,7 +30,22 @@ def _noop(*args, **kwargs):
     pass
 
 
-class _MethodCallMixin(object):
+class Connection(_Connection):
+
+    def activate_name_owner(self, bus_name):
+        """Return the unique name for the given bus name, activating it
+        if necessary and possible.
+
+        If the name is already unique or this connection is not to a
+        bus daemon, just return it.
+
+        :Returns: a bus name. If the given `bus_name` exists, the returned
+            name identifies its current owner; otherwise the returned name
+            does not exist.
+        :Raises DBusException: if the implementation has failed
+            to activate the given bus name.
+        """
+        return bus_name
 
     def call_async(self, bus_name, object_path, dbus_interface, method,
                    signature, args, reply_handler, error_handler,
diff --git a/dbus/proxies.py b/dbus/proxies.py
index e2a1aed..5934b56 100644
--- a/dbus/proxies.py
+++ b/dbus/proxies.py
@@ -202,23 +202,8 @@ class ProxyObject(object):
         _dbus_bindings.validate_object_path(object_path)
         self.__dbus_object_path__ = object_path
 
-        # XXX: assumes it's a bus daemon
-        if (named_service is not None and named_service[:1] != ':'
-            and named_service != BUS_DAEMON_NAME
-            and not follow_name_owner_changes):
-            bus_object = bus.get_object(BUS_DAEMON_NAME, BUS_DAEMON_PATH)
-            try:
-                self._named_service = bus_object.GetNameOwner(named_service,
-                        dbus_interface=BUS_DAEMON_IFACE)
-            except DBusException, e:
-                # FIXME: detect whether it's NameHasNoOwner, but properly
-                #if not str(e).startswith('org.freedesktop.DBus.Error.NameHasNoOwner:'):
-                #    raise
-                # it might not exist: try to start it
-                bus_object.StartServiceByName(named_service,
-                                              _dbus_bindings.UInt32(0))
-                self._named_service = bus_object.GetNameOwner(named_service,
-                        dbus_interface=BUS_DAEMON_IFACE)
+        if not follow_name_owner_changes:
+            self._named_service = bus.activate_name_owner(named_service)
 
         #PendingCall object for Introspect call
         self._pending_introspect = None
@@ -433,7 +418,7 @@ class ProxyObject(object):
         this won't be a problem.
         """
 
-        ret = self.ProxyMethodClass(self, self._bus.get_connection(),
+        ret = self.ProxyMethodClass(self, self._bus,
                                     self._named_service,
                                     self.__dbus_object_path__, member,
                                     dbus_interface)


More information about the dbus mailing list