Mark Bus.get_connection() as deprecated; improve Bus.__repr__
[dbus-python-phuang.git] / dbus / _dbus.py
blob8e8bb03261769e749d30e9b946ae0b9ca327651a
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'
29 import os
30 import sys
31 import weakref
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, \
42 SignalMessage,\
43 HANDLER_RESULT_NOT_YET_HANDLED,\
44 HANDLER_RESULT_HANDLED
45 from dbus.bus import BusConnection
47 try:
48 import thread
49 except ImportError:
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
56 buses.
58 If you're trying to subclass `Bus`, you may be better off subclassing
59 `BusConnection`, which doesn't have all this magic.
60 """
62 _shared_instances = {}
64 def __new__(cls, bus_type=BusConnection.TYPE_SESSION, private=False,
65 mainloop=None):
66 """Constructor, returning an existing instance where appropriate.
68 The returned instance is actually always an instance of `SessionBus`,
69 `SystemBus` or `StarterBus`.
71 :Parameters:
72 `bus_type` : cls.TYPE_SESSION, cls.TYPE_SYSTEM or cls.TYPE_STARTER
73 Connect to the appropriate bus
74 `private` : bool
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
80 if none has been.
81 :ToDo:
82 - There is currently no way to connect this class to a custom
83 address.
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
88 subclass.
89 """
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:
99 subclass = SessionBus
100 elif bus_type == BUS_SYSTEM:
101 subclass = SystemBus
102 elif bus_type == BUS_STARTER:
103 subclass = StarterBus
104 else:
105 raise ValueError('invalid bus_type %s' % bus_type)
107 bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
109 bus._bus_type = bus_type
111 if not private:
112 cls._shared_instances[bus_type] = bus
114 return bus
116 def close(self):
117 t = self._bus_type
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 """Return self, for backwards compatibility with earlier dbus-python
124 versions where Bus was not a subclass of Connection.
126 :Deprecated: since 0.80.0
128 return self
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.
137 :Parameters:
138 `private` : bool
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.
148 :Parameters:
149 `private` : bool
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.
160 :Parameters:
161 `private` : bool
162 If true, do not return a shared connection.
164 return StarterBus(private=private)
166 get_starter = staticmethod(get_starter)
168 def __repr__(self):
169 if self._bus_type == BUS_SESSION:
170 name = 'session'
171 elif self._bus_type == BUS_SYSTEM:
172 name = 'system'
173 elif self._bus_type == BUS_STARTER:
174 name = 'starter'
175 else:
176 name = 'unknown bus type'
178 return '<%s.%s (%s) at %#x>' % (self.__class__.__module__,
179 self.__class__.__name__,
180 name, id(self))
181 __str__ = __repr__
184 # FIXME: Drop the subclasses here? I can't think why we'd ever want
185 # polymorphism
186 class SystemBus(Bus):
187 """The system-wide message bus."""
188 def __new__(cls, private=False, mainloop=None):
189 """Return a connection to the system bus.
191 :Parameters:
192 `private` : bool
193 If true, never return an existing shared instance, but instead
194 return a private connection.
195 `mainloop` : dbus.mainloop.NativeMainLoop
196 The main loop to use. The default is to use the default
197 main loop if one has been set up, or raise an exception
198 if none has been.
200 return Bus.__new__(cls, Bus.TYPE_SYSTEM, mainloop=mainloop,
201 private=private)
203 class SessionBus(Bus):
204 """The session (current login) message bus."""
205 def __new__(cls, private=False, mainloop=None):
206 """Return a connection to the session bus.
208 :Parameters:
209 `private` : bool
210 If true, never return an existing shared instance, but instead
211 return a private connection.
212 `mainloop` : dbus.mainloop.NativeMainLoop
213 The main loop to use. The default is to use the default
214 main loop if one has been set up, or raise an exception
215 if none has been.
217 return Bus.__new__(cls, Bus.TYPE_SESSION, private=private,
218 mainloop=mainloop)
220 class StarterBus(Bus):
221 """The bus that activated this process (only valid if
222 this process was launched by DBus activation).
224 def __new__(cls, private=False, mainloop=None):
225 """Return a connection to the bus that activated this process.
227 :Parameters:
228 `private` : bool
229 If true, never return an existing shared instance, but instead
230 return a private connection.
231 `mainloop` : dbus.mainloop.NativeMainLoop
232 The main loop to use. The default is to use the default
233 main loop if one has been set up, or raise an exception
234 if none has been.
236 return Bus.__new__(cls, Bus.TYPE_STARTER, private=private,
237 mainloop=mainloop)
240 if 'DBUS_PYTHON_NO_DEPRECATED' not in os.environ:
242 class _DBusBindingsEmulation:
243 """A partial emulation of the dbus_bindings module."""
244 def __str__(self):
245 return '_DBusBindingsEmulation()'
246 def __repr__(self):
247 return '_DBusBindingsEmulation()'
248 def __getattr__(self, attr):
249 global dbus_bindings
250 import dbus.dbus_bindings as m
251 dbus_bindings = m
252 return getattr(m, attr)
254 dbus_bindings = _DBusBindingsEmulation()
255 """Deprecated, don't use."""