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
.exceptions
import DBusException
35 from _dbus_bindings
import BUS_DAEMON_NAME
, BUS_DAEMON_PATH
,\
36 BUS_DAEMON_IFACE
, UTF8String
,\
37 validate_member_name
, validate_interface_name
,\
38 validate_bus_name
, validate_object_path
,\
39 BUS_SESSION
, BUS_SYSTEM
, BUS_STARTER
,\
40 DBUS_START_REPLY_SUCCESS
, \
41 DBUS_START_REPLY_ALREADY_RUNNING
, \
43 HANDLER_RESULT_NOT_YET_HANDLED
,\
44 HANDLER_RESULT_HANDLED
45 from dbus
.bus
import BusConnection
50 import dummy_thread
as thread
53 class Bus(BusConnection
):
54 """A connection to one of three possible standard buses, the SESSION,
55 SYSTEM, or STARTER bus. This class manages shared connections to those
58 If you're trying to subclass `Bus`, you may be better off subclassing
59 `BusConnection`, which doesn't have all this magic.
62 _shared_instances
= {}
64 def __new__(cls
, bus_type
=BusConnection
.TYPE_SESSION
, private
=False,
66 """Constructor, returning an existing instance where appropriate.
68 The returned instance is actually always an instance of `SessionBus`,
69 `SystemBus` or `StarterBus`.
72 `bus_type` : cls.TYPE_SESSION, cls.TYPE_SYSTEM or cls.TYPE_STARTER
73 Connect to the appropriate bus
75 If true, never return an existing shared instance, but instead
76 return a private connection
77 `mainloop` : dbus.mainloop.NativeMainLoop
78 The main loop to use. The default is to use the default
79 main loop if one has been set up, or raise an exception
82 - There is currently no way to connect this class to a custom
84 - Some of this functionality should be available on
85 peer-to-peer D-Bus connections too.
86 :Changed: in dbus-python 0.80:
87 converted from a wrapper around a Connection to a Connection
90 if (not private
and bus_type
in cls
._shared
_instances
):
91 return cls
._shared
_instances
[bus_type
]
93 # this is a bit odd, but we create instances of the subtypes
94 # so we can return the shared instances if someone tries to
95 # construct one of them (otherwise we'd eg try and return an
96 # instance of Bus from __new__ in SessionBus). why are there
97 # three ways to construct this class? we just don't know.
98 if bus_type
== BUS_SESSION
:
100 elif bus_type
== BUS_SYSTEM
:
102 elif bus_type
== BUS_STARTER
:
103 subclass
= StarterBus
105 raise ValueError('invalid bus_type %s' % bus_type
)
107 bus
= BusConnection
.__new
__(subclass
, bus_type
, mainloop
=mainloop
)
109 bus
._bus
_type
= bus_type
112 cls
._shared
_instances
[bus_type
] = bus
118 if self
.__class
__._shared
_instances
[t
] is self
:
119 del self
.__class
__._shared
_instances
[t
]
120 super(Bus
, self
).close()
122 def get_connection(self
):
123 """(Deprecated - in new code, just use self)
125 Return self, for backwards compatibility with earlier dbus-python
126 versions where Bus was not a subclass of Connection.
129 _connection
= property(get_connection
, None, None,
130 """self._connection == self, for backwards
131 compatibility with earlier dbus-python versions
132 where Bus was not a subclass of Connection.""")
134 def get_session(private
=False):
135 """Static method that returns a connection to the session bus.
139 If true, do not return a shared connection.
141 return SessionBus(private
=private
)
143 get_session
= staticmethod(get_session
)
145 def get_system(private
=False):
146 """Static method that returns a connection to the system bus.
150 If true, do not return a shared connection.
152 return SystemBus(private
=private
)
154 get_system
= staticmethod(get_system
)
157 def get_starter(private
=False):
158 """Static method that returns a connection to the starter bus.
162 If true, do not return a shared connection.
164 return StarterBus(private
=private
)
166 get_starter
= staticmethod(get_starter
)
169 if self
._bus
_type
== BUS_SESSION
:
171 elif self
._bus
_type
== BUS_SYSTEM
:
173 elif self
._bus
_type
== BUS_STARTER
:
176 raise AssertionError('Unable to represent unknown bus type.')
178 return '<dbus.Bus on %s at %#x>' % (name
, id(self
))
182 # FIXME: Drop the subclasses here? I can't think why we'd ever want
184 class SystemBus(Bus
):
185 """The system-wide message bus."""
186 def __new__(cls
, private
=False, mainloop
=None):
187 """Return a connection to the system bus.
191 If true, never return an existing shared instance, but instead
192 return a private connection.
193 `mainloop` : dbus.mainloop.NativeMainLoop
194 The main loop to use. The default is to use the default
195 main loop if one has been set up, or raise an exception
198 return Bus
.__new
__(cls
, Bus
.TYPE_SYSTEM
, mainloop
=mainloop
,
201 class SessionBus(Bus
):
202 """The session (current login) message bus."""
203 def __new__(cls
, private
=False, mainloop
=None):
204 """Return a connection to the session bus.
208 If true, never return an existing shared instance, but instead
209 return a private connection.
210 `mainloop` : dbus.mainloop.NativeMainLoop
211 The main loop to use. The default is to use the default
212 main loop if one has been set up, or raise an exception
215 return Bus
.__new
__(cls
, Bus
.TYPE_SESSION
, private
=private
,
218 class StarterBus(Bus
):
219 """The bus that activated this process (only valid if
220 this process was launched by DBus activation).
222 def __new__(cls
, private
=False, mainloop
=None):
223 """Return a connection to the bus that activated this process.
227 If true, never return an existing shared instance, but instead
228 return a private connection.
229 `mainloop` : dbus.mainloop.NativeMainLoop
230 The main loop to use. The default is to use the default
231 main loop if one has been set up, or raise an exception
234 return Bus
.__new
__(cls
, Bus
.TYPE_STARTER
, private
=private
,
238 if 'DBUS_PYTHON_NO_DEPRECATED' not in os
.environ
:
240 class _DBusBindingsEmulation
:
241 """A partial emulation of the dbus_bindings module."""
243 return '_DBusBindingsEmulation()'
245 return '_DBusBindingsEmulation()'
246 def __getattr__(self
, attr
):
248 import dbus
.dbus_bindings
as m
250 return getattr(m
, attr
)
252 dbus_bindings
= _DBusBindingsEmulation()
253 """Deprecated, don't use."""