doc/tutorial.txt: Don't claim we have a tutorial for p2p connections yet
[dbus-python-phuang.git] / dbus / _dbus.py
blobd46aa9bb1524256d94421d6c27bd09420c0e4676
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_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, \
41 SignalMessage,\
42 HANDLER_RESULT_NOT_YET_HANDLED,\
43 HANDLER_RESULT_HANDLED
44 from dbus.bus import BusConnection
46 try:
47 import thread
48 except ImportError:
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
55 buses.
57 If you're trying to subclass `Bus`, you may be better off subclassing
58 `BusConnection`, which doesn't have all this magic.
59 """
61 _shared_instances = {}
63 def __new__(cls, bus_type=BusConnection.TYPE_SESSION, private=False,
64 mainloop=None):
65 """Constructor, returning an existing instance where appropriate.
67 The returned instance is actually always an instance of `SessionBus`,
68 `SystemBus` or `StarterBus`.
70 :Parameters:
71 `bus_type` : cls.TYPE_SESSION, cls.TYPE_SYSTEM or cls.TYPE_STARTER
72 Connect to the appropriate bus
73 `private` : bool
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
79 if none has been.
80 :ToDo:
81 - There is currently no way to connect this class to a custom
82 address.
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
87 subclass.
88 """
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:
98 subclass = SessionBus
99 elif bus_type == BUS_SYSTEM:
100 subclass = SystemBus
101 elif bus_type == BUS_STARTER:
102 subclass = StarterBus
103 else:
104 raise ValueError('invalid bus_type %s' % bus_type)
106 bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
108 bus._bus_type = bus_type
110 if not private:
111 cls._shared_instances[bus_type] = bus
113 return bus
115 def close(self):
116 t = self._bus_type
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.
127 return self
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.
136 :Parameters:
137 `private` : bool
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.
147 :Parameters:
148 `private` : bool
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.
159 :Parameters:
160 `private` : bool
161 If true, do not return a shared connection.
163 return StarterBus(private=private)
165 get_starter = staticmethod(get_starter)
167 def __repr__(self):
168 if self._bus_type == BUS_SESSION:
169 name = 'SESSION'
170 elif self._bus_type == BUS_SYSTEM:
171 name = 'SYSTEM'
172 elif self._bus_type == BUS_STARTER:
173 name = 'STARTER'
174 else:
175 raise AssertionError('Unable to represent unknown bus type.')
177 return '<dbus.Bus on %s at %#x>' % (name, id(self))
178 __str__ = __repr__
181 # FIXME: Drop the subclasses here? I can't think why we'd ever want
182 # polymorphism
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.
188 :Parameters:
189 `private` : bool
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
195 if none has been.
197 return Bus.__new__(cls, Bus.TYPE_SYSTEM, mainloop=mainloop,
198 private=private)
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.
205 :Parameters:
206 `private` : bool
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
212 if none has been.
214 return Bus.__new__(cls, Bus.TYPE_SESSION, private=private,
215 mainloop=mainloop)
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.
224 :Parameters:
225 `private` : bool
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
231 if none has been.
233 return Bus.__new__(cls, Bus.TYPE_STARTER, private=private,
234 mainloop=mainloop)
237 if 'DBUS_PYTHON_NO_DEPRECATED' not in os.environ:
239 class _DBusBindingsEmulation:
240 """A partial emulation of the dbus_bindings module."""
241 def __str__(self):
242 return '_DBusBindingsEmulation()'
243 def __repr__(self):
244 return '_DBusBindingsEmulation()'
245 def __getattr__(self, attr):
246 global dbus_bindings
247 import dbus.dbus_bindings as m
248 dbus_bindings = m
249 return getattr(m, attr)
251 dbus_bindings = _DBusBindingsEmulation()
252 """Deprecated, don't use."""