dbus/connection.py: Import constants from _dbus_bindings; check for reserved local...
[dbus-python-phuang.git] / dbus / connection.py
blob36a9a7bcaf4bcd2e6ed6f27e54b48c55e78605aa
1 """Method-call mixin for use within dbus-python only.
2 See `_MethodCallMixin`.
3 """
5 # Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
7 # Licensed under the Academic Free License version 2.1
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU Lesser General Public License as published
11 # by the Free Software Foundation; either version 2.1 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 import logging
25 from _dbus_bindings import Connection, ErrorMessage, \
26 MethodCallMessage, MethodReturnMessage, \
27 DBusException, LOCAL_PATH, LOCAL_IFACE
30 _logger = logging.getLogger('dbus.methods')
33 def _noop(*args, **kwargs):
34 pass
37 class _MethodCallMixin(object):
39 def call_async(self, bus_name, object_path, dbus_interface, method,
40 signature, args, reply_handler, error_handler,
41 timeout=-1.0, utf8_strings=False, byte_arrays=False,
42 require_main_loop=True):
43 """Call the given method, asynchronously.
45 If the reply_handler is None, successful replies will be ignored.
46 If the error_handler is None, failures will be ignored. If both
47 are None, the implementation may request that no reply is sent.
49 :Returns: The dbus.lowlevel.PendingCall.
50 """
51 if object_path == LOCAL_PATH:
52 raise DBusException('Methods may not be called on the reserved '
53 'path %s' % LOCAL_PATH)
54 if dbus_interface == LOCAL_IFACE:
55 raise DBusException('Methods may not be called on the reserved '
56 'interface %s' % LOCAL_IFACE)
57 # no need to validate other args - MethodCallMessage ctor will do
59 get_args_opts = {'utf8_strings': utf8_strings,
60 'byte_arrays': byte_arrays}
62 message = MethodCallMessage(destination=bus_name,
63 path=object_path,
64 interface=dbus_interface,
65 method=method)
66 # Add the arguments to the function
67 try:
68 message.append(signature=signature, *args)
69 except Exception, e:
70 _logger.error('Unable to set arguments %r according to '
71 'signature %r: %s: %s',
72 args, signature, e.__class__, e)
73 raise
75 if reply_handler is None and error_handler is None:
76 # we don't care what happens, so just send it
77 self.send_message(message)
78 return
80 if reply_handler is None:
81 reply_handler = _noop
82 if error_handler is None:
83 error_handler = _noop
85 def msg_reply_handler(message):
86 if isinstance(message, MethodReturnMessage):
87 reply_handler(*message.get_args_list(**get_args_opts))
88 elif isinstance(message, ErrorMessage):
89 args = message.get_args_list()
90 # FIXME: should we do something with the rest?
91 if len(args) > 0:
92 error_handler(DBusException(args[0]))
93 else:
94 error_handler(DBusException())
95 else:
96 error_handler(TypeError('Unexpected type for reply '
97 'message: %r' % message))
98 return self.send_message_with_reply(message, msg_reply_handler,
99 timeout/1000.0,
100 require_main_loop=require_main_loop)
102 def call_blocking(self, bus_name, object_path, dbus_interface, method,
103 signature, args, timeout=-1.0, utf8_strings=False,
104 byte_arrays=False):
105 """Call the given method, synchronously.
107 if object_path == LOCAL_PATH:
108 raise DBusException('Methods may not be called on the reserved '
109 'path %s' % LOCAL_PATH)
110 if dbus_interface == LOCAL_IFACE:
111 raise DBusException('Methods may not be called on the reserved '
112 'interface %s' % LOCAL_IFACE)
113 # no need to validate other args - MethodCallMessage ctor will do
115 get_args_opts = {'utf8_strings': utf8_strings,
116 'byte_arrays': byte_arrays}
118 message = MethodCallMessage(destination=bus_name,
119 path=object_path,
120 interface=dbus_interface,
121 method=method)
122 # Add the arguments to the function
123 try:
124 message.append(signature=signature, *args)
125 except Exception, e:
126 _logger.error('Unable to set arguments %r according to '
127 'signature %r: %s: %s',
128 args, signature, e.__class__, e)
129 raise
131 # make a blocking call
132 reply_message = self.send_message_with_reply_and_block(
133 message, timeout)
134 args_list = reply_message.get_args_list(**get_args_opts)
135 if len(args_list) == 0:
136 return None
137 elif len(args_list) == 1:
138 return args_list[0]
139 else:
140 return tuple(args_list)