1 """Implementation for dbus.Bus. Not to be imported directly."""
3 # Copyright (C) 2003, 2004, 2005, 2006 Red Hat Inc. <http://www.redhat.com/>
4 # Copyright (C) 2003 David Zeuthen
5 # Copyright (C) 2004 Rob Taylor
6 # Copyright (C) 2005, 2006 Collabora Ltd. <http://www.collabora.co.uk/>
8 # Licensed under the Academic Free License version 2.1
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program; if not, write to the Free Software
22 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 from __future__
import generators
26 __all__
= ('Bus', 'SystemBus', 'SessionBus', 'StarterBus')
27 __docformat__
= 'reStructuredText'
32 from traceback
import print_exc
34 from _dbus_bindings
import BUS_DAEMON_NAME
, BUS_DAEMON_PATH
,\
35 BUS_DAEMON_IFACE
, DBusException
, UTF8String
,\
36 validate_member_name
, validate_interface_name
,\
37 validate_bus_name
, validate_object_path
,\
38 BUS_SESSION
, BUS_SYSTEM
, BUS_STARTER
,\
39 DBUS_START_REPLY_SUCCESS
, \
40 DBUS_START_REPLY_ALREADY_RUNNING
, \
42 HANDLER_RESULT_NOT_YET_HANDLED
,\
43 HANDLER_RESULT_HANDLED
44 from dbus
.bus
import BusConnection
49 import dummy_thread
as thread
52 class Bus(BusConnection
):
53 """A connection to one of three possible standard buses, the SESSION,
54 SYSTEM, or STARTER bus. This class manages shared connections to those
57 If you're trying to subclass `Bus`, you may be better off subclassing
58 `BusConnection`, which doesn't have all this magic.
61 _shared_instances
= {}
63 def __new__(cls
, bus_type
=BusConnection
.TYPE_SESSION
, private
=False,
65 """Constructor, returning an existing instance where appropriate.
67 The returned instance is actually always an instance of `SessionBus`,
68 `SystemBus` or `StarterBus`.
71 `bus_type` : cls.TYPE_SESSION, cls.TYPE_SYSTEM or cls.TYPE_STARTER
72 Connect to the appropriate bus
74 If true, never return an existing shared instance, but instead
75 return a private connection
76 `mainloop` : dbus.mainloop.NativeMainLoop
77 The main loop to use. The default is to use the default
78 main loop if one has been set up, or raise an exception
81 - There is currently no way to connect this class to a custom
83 - Some of this functionality should be available on
84 peer-to-peer D-Bus connections too.
85 :Changed: in dbus-python 0.80:
86 converted from a wrapper around a Connection to a Connection
89 if (not private
and bus_type
in cls
._shared
_instances
):
90 return cls
._shared
_instances
[bus_type
]
92 # this is a bit odd, but we create instances of the subtypes
93 # so we can return the shared instances if someone tries to
94 # construct one of them (otherwise we'd eg try and return an
95 # instance of Bus from __new__ in SessionBus). why are there
96 # three ways to construct this class? we just don't know.
97 if bus_type
== BUS_SESSION
:
99 elif bus_type
== BUS_SYSTEM
:
101 elif bus_type
== BUS_STARTER
:
102 subclass
= StarterBus
104 raise ValueError('invalid bus_type %s' % bus_type
)
106 bus
= BusConnection
.__new
__(subclass
, bus_type
, mainloop
=mainloop
)
108 bus
._bus
_type
= bus_type
111 cls
._shared
_instances
[bus_type
] = bus
117 if self
.__class
__._shared
_instances
[t
] is self
:
118 del self
.__class
__._shared
_instances
[t
]
119 super(Bus
, self
).close()
121 def get_connection(self
):
122 """(Deprecated - in new code, just use self)
124 Return self, for backwards compatibility with earlier dbus-python
125 versions where Bus was not a subclass of Connection.
128 _connection
= property(get_connection
, None, None,
129 """self._connection == self, for backwards
130 compatibility with earlier dbus-python versions
131 where Bus was not a subclass of Connection.""")
133 def get_session(private
=False):
134 """Static method that returns a connection to the session bus.
138 If true, do not return a shared connection.
140 return SessionBus(private
=private
)
142 get_session
= staticmethod(get_session
)
144 def get_system(private
=False):
145 """Static method that returns a connection to the system bus.
149 If true, do not return a shared connection.
151 return SystemBus(private
=private
)
153 get_system
= staticmethod(get_system
)
156 def get_starter(private
=False):
157 """Static method that returns a connection to the starter bus.
161 If true, do not return a shared connection.
163 return StarterBus(private
=private
)
165 get_starter
= staticmethod(get_starter
)
168 if self
._bus
_type
== BUS_SESSION
:
170 elif self
._bus
_type
== BUS_SYSTEM
:
172 elif self
._bus
_type
== BUS_STARTER
:
175 raise AssertionError('Unable to represent unknown bus type.')
177 return '<dbus.Bus on %s at %#x>' % (name
, id(self
))
181 # FIXME: Drop the subclasses here? I can't think why we'd ever want
183 class SystemBus(Bus
):
184 """The system-wide message bus."""
185 def __new__(cls
, private
=False, mainloop
=None):
186 """Return a connection to the system bus.
190 If true, never return an existing shared instance, but instead
191 return a private connection.
192 `mainloop` : dbus.mainloop.NativeMainLoop
193 The main loop to use. The default is to use the default
194 main loop if one has been set up, or raise an exception
197 return Bus
.__new
__(cls
, Bus
.TYPE_SYSTEM
, mainloop
=mainloop
,
200 class SessionBus(Bus
):
201 """The session (current login) message bus."""
202 def __new__(cls
, private
=False, mainloop
=None):
203 """Return a connection to the session bus.
207 If true, never return an existing shared instance, but instead
208 return a private connection.
209 `mainloop` : dbus.mainloop.NativeMainLoop
210 The main loop to use. The default is to use the default
211 main loop if one has been set up, or raise an exception
214 return Bus
.__new
__(cls
, Bus
.TYPE_SESSION
, private
=private
,
217 class StarterBus(Bus
):
218 """The bus that activated this process (only valid if
219 this process was launched by DBus activation).
221 def __new__(cls
, private
=False, mainloop
=None):
222 """Return a connection to the bus that activated this process.
226 If true, never return an existing shared instance, but instead
227 return a private connection.
228 `mainloop` : dbus.mainloop.NativeMainLoop
229 The main loop to use. The default is to use the default
230 main loop if one has been set up, or raise an exception
233 return Bus
.__new
__(cls
, Bus
.TYPE_STARTER
, private
=private
,
237 if 'DBUS_PYTHON_NO_DEPRECATED' not in os
.environ
:
239 class _DBusBindingsEmulation
:
240 """A partial emulation of the dbus_bindings module."""
242 return '_DBusBindingsEmulation()'
244 return '_DBusBindingsEmulation()'
245 def __getattr__(self
, attr
):
247 import dbus
.dbus_bindings
as m
249 return getattr(m
, attr
)
251 dbus_bindings
= _DBusBindingsEmulation()
252 """Deprecated, don't use."""