1 """Method-call mixin for use within dbus-python only.
2 See `_MethodCallMixin`.
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
25 from _dbus_bindings
import Connection
, ErrorMessage
, \
26 MethodCallMessage
, MethodReturnMessage
, \
30 # This is special in libdbus - the bus daemon will kick us off if we try to
31 # send any message to it :-/
32 LOCAL_PATH
= '/org/freedesktop/DBus/Local'
35 _logger
= logging
.getLogger('dbus.methods')
38 def _noop(*args
, **kwargs
):
42 class _MethodCallMixin(object):
44 def call_async(self
, bus_name
, object_path
, dbus_interface
, method
,
45 signature
, args
, reply_handler
, error_handler
,
46 timeout
=-1.0, utf8_strings
=False, byte_arrays
=False,
47 require_main_loop
=True):
48 """Call the given method, asynchronously.
50 If the reply_handler is None, successful replies will be ignored.
51 If the error_handler is None, failures will be ignored. If both
52 are None, the implementation may request that no reply is sent.
54 :Returns: The dbus.lowlevel.PendingCall.
56 if object_path
== LOCAL_PATH
:
57 raise DBusException('Methods may not be called on the reserved '
58 'path %s' % LOCAL_PATH
)
59 # no need to validate other args - MethodCallMessage ctor will do
61 get_args_opts
= {'utf8_strings': utf8_strings
,
62 'byte_arrays': byte_arrays
}
64 message
= MethodCallMessage(destination
=bus_name
,
66 interface
=dbus_interface
,
68 # Add the arguments to the function
70 message
.append(signature
=signature
, *args
)
72 _logger
.error('Unable to set arguments %r according to '
73 'signature %r: %s: %s',
74 args
, signature
, e
.__class
__, e
)
77 if reply_handler
is None and error_handler
is None:
78 # we don't care what happens, so just send it
79 self
.send_message(message
)
82 if reply_handler
is None:
84 if error_handler
is None:
87 def msg_reply_handler(message
):
88 if isinstance(message
, MethodReturnMessage
):
89 reply_handler(*message
.get_args_list(**get_args_opts
))
90 elif isinstance(message
, ErrorMessage
):
91 args
= message
.get_args_list()
92 # FIXME: should we do something with the rest?
94 error_handler(DBusException(args
[0]))
96 error_handler(DBusException())
98 error_handler(TypeError('Unexpected type for reply '
99 'message: %r' % message
))
100 return self
.send_message_with_reply(message
, msg_reply_handler
,
102 require_main_loop
=require_main_loop
)
104 def call_blocking(self
, bus_name
, object_path
, dbus_interface
, method
,
105 signature
, args
, timeout
=-1.0, utf8_strings
=False,
107 """Call the given method, synchronously.
109 if object_path
== LOCAL_PATH
:
110 raise DBusException('Methods may not be called on the reserved '
111 'path %s' % LOCAL_PATH
)
112 # no need to validate other args - MethodCallMessage ctor will do
114 get_args_opts
= {'utf8_strings': utf8_strings
,
115 'byte_arrays': byte_arrays
}
117 message
= MethodCallMessage(destination
=bus_name
,
119 interface
=dbus_interface
,
121 # Add the arguments to the function
123 message
.append(signature
=signature
, *args
)
125 _logger
.error('Unable to set arguments %r according to '
126 'signature %r: %s: %s',
127 args
, signature
, e
.__class
__, e
)
130 # make a blocking call
131 reply_message
= self
.send_message_with_reply_and_block(
133 args_list
= reply_message
.get_args_list(**get_args_opts
)
134 if len(args_list
) == 0:
136 elif len(args_list
) == 1:
139 return tuple(args_list
)