[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