Add wrapper for DBusServer.
[dbus-python-phuang.git] / dbus / _dbus.py
blob18747c069cbcdaee794290dee1d6ca0ceb9bd07d
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 # Permission is hereby granted, free of charge, to any person
9 # obtaining a copy of this software and associated documentation
10 # files (the "Software"), to deal in the Software without
11 # restriction, including without limitation the rights to use, copy,
12 # modify, merge, publish, distribute, sublicense, and/or sell copies
13 # of the Software, and to permit persons to whom the Software is
14 # furnished to do so, subject to the following conditions:
16 # The above copyright notice and this permission notice shall be
17 # included in all copies or substantial portions of the Software.
19 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 # DEALINGS IN THE SOFTWARE.
28 from __future__ import generators
30 __all__ = ('Bus', 'SystemBus', 'SessionBus', 'StarterBus')
31 __docformat__ = 'reStructuredText'
33 import os
34 import sys
35 import weakref
36 from traceback import print_exc
38 from dbus.exceptions import DBusException
39 from _dbus_bindings import BUS_DAEMON_NAME, BUS_DAEMON_PATH,\
40 BUS_DAEMON_IFACE, UTF8String,\
41 validate_member_name, validate_interface_name,\
42 validate_bus_name, validate_object_path,\
43 BUS_SESSION, BUS_SYSTEM, BUS_STARTER,\
44 DBUS_START_REPLY_SUCCESS, \
45 DBUS_START_REPLY_ALREADY_RUNNING
46 from dbus.bus import BusConnection
47 from dbus.lowlevel import SignalMessage
49 try:
50 import thread
51 except ImportError:
52 import dummy_thread as thread
55 class Bus(BusConnection):
56 """A connection to one of three possible standard buses, the SESSION,
57 SYSTEM, or STARTER bus. This class manages shared connections to those
58 buses.
60 If you're trying to subclass `Bus`, you may be better off subclassing
61 `BusConnection`, which doesn't have all this magic.
62 """
64 _shared_instances = {}
66 def __new__(cls, bus_type=BusConnection.TYPE_SESSION, private=False,
67 mainloop=None):
68 """Constructor, returning an existing instance where appropriate.
70 The returned instance is actually always an instance of `SessionBus`,
71 `SystemBus` or `StarterBus`.
73 :Parameters:
74 `bus_type` : cls.TYPE_SESSION, cls.TYPE_SYSTEM or cls.TYPE_STARTER
75 Connect to the appropriate bus
76 `private` : bool
77 If true, never return an existing shared instance, but instead
78 return a private connection.
79 :Deprecated: since 0.82.3. Use dbus.bus.BusConnection for
80 private connections.
81 `mainloop` : dbus.mainloop.NativeMainLoop
82 The main loop to use. The default is to use the default
83 main loop if one has been set up, or raise an exception
84 if none has been.
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.get(t) is self:
118 del self.__class__._shared_instances[t]
119 super(Bus, self).close()
121 def get_connection(self):
122 """Return self, for backwards compatibility with earlier dbus-python
123 versions where Bus was not a subclass of Connection.
125 :Deprecated: since 0.80.0
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 name = 'unknown bus type'
177 return '<%s.%s (%s) at %#x>' % (self.__class__.__module__,
178 self.__class__.__name__,
179 name, id(self))
180 __str__ = __repr__
183 # FIXME: Drop the subclasses here? I can't think why we'd ever want
184 # polymorphism
185 class SystemBus(Bus):
186 """The system-wide message bus."""
187 def __new__(cls, private=False, mainloop=None):
188 """Return a connection to the system bus.
190 :Parameters:
191 `private` : bool
192 If true, never return an existing shared instance, but instead
193 return a private connection.
194 `mainloop` : dbus.mainloop.NativeMainLoop
195 The main loop to use. The default is to use the default
196 main loop if one has been set up, or raise an exception
197 if none has been.
199 return Bus.__new__(cls, Bus.TYPE_SYSTEM, mainloop=mainloop,
200 private=private)
202 class SessionBus(Bus):
203 """The session (current login) message bus."""
204 def __new__(cls, private=False, mainloop=None):
205 """Return a connection to the session bus.
207 :Parameters:
208 `private` : bool
209 If true, never return an existing shared instance, but instead
210 return a private connection.
211 `mainloop` : dbus.mainloop.NativeMainLoop
212 The main loop to use. The default is to use the default
213 main loop if one has been set up, or raise an exception
214 if none has been.
216 return Bus.__new__(cls, Bus.TYPE_SESSION, private=private,
217 mainloop=mainloop)
219 class StarterBus(Bus):
220 """The bus that activated this process (only valid if
221 this process was launched by DBus activation).
223 def __new__(cls, private=False, mainloop=None):
224 """Return a connection to the bus that activated this process.
226 :Parameters:
227 `private` : bool
228 If true, never return an existing shared instance, but instead
229 return a private connection.
230 `mainloop` : dbus.mainloop.NativeMainLoop
231 The main loop to use. The default is to use the default
232 main loop if one has been set up, or raise an exception
233 if none has been.
235 return Bus.__new__(cls, Bus.TYPE_STARTER, private=private,
236 mainloop=mainloop)
239 if 'DBUS_PYTHON_NO_DEPRECATED' not in os.environ:
241 class _DBusBindingsEmulation:
242 """A partial emulation of the dbus_bindings module."""
243 def __str__(self):
244 return '_DBusBindingsEmulation()'
245 def __repr__(self):
246 return '_DBusBindingsEmulation()'
247 def __getattr__(self, attr):
248 global dbus_bindings
249 import dbus.dbus_bindings as m
250 dbus_bindings = m
251 return getattr(m, attr)
253 dbus_bindings = _DBusBindingsEmulation()
254 """Deprecated, don't use."""