def _reflect_on_method(cls, func): args = func._dbus_args if func._dbus_in_signature: # convert signature into a tuple so length refers to number of # types, not number of characters. the length is checked by # the decorator to make sure it matches the length of args. in_sig = tuple(_dbus_bindings.Signature(func._dbus_in_signature)) else: # magic iterator which returns as many v's as we need in_sig = _VariantSignature() if func._dbus_out_signature: out_sig = _dbus_bindings.Signature(func._dbus_out_signature) else: # its tempting to default to _dbus_bindings.Signature('v'), but # for methods that return nothing, providing incorrect # introspection data is worse than providing none at all out_sig = [] reflection_data = ' <method name="%s">\n' % (func.__name__) for pair in zip(in_sig, args): reflection_data += ' <arg direction="in" type="%s" name="%s" />\n' % pair for type in out_sig: reflection_data += ' <arg direction="out" type="%s" />\n' % type reflection_data += ' </method>\n' return reflection_data
def _reflect_on_signal(cls, func): args = func._dbus_args if func._dbus_signature: # convert signature into a tuple so length refers to number of # types, not number of characters sig = tuple(_dbus_bindings.Signature(func._dbus_signature)) else: # magic iterator which returns as many v's as we need sig = _VariantSignature() reflection_data = ' <signal name="%s">\n' % (func.__name__) for pair in zip(sig, args): reflection_data = reflection_data + ' <arg type="%s" name="%s" />\n' % pair reflection_data = reflection_data + ' </signal>\n' return reflection_data
def decorator(func): args = inspect.getargspec(func)[0] args.pop(0) if async_callbacks: if type(async_callbacks) != tuple: raise TypeError('async_callbacks must be a tuple of (keyword for return callback, keyword for error callback)') if len(async_callbacks) != 2: raise ValueError('async_callbacks must be a tuple of (keyword for return callback, keyword for error callback)') args.remove(async_callbacks[0]) args.remove(async_callbacks[1]) if sender_keyword: args.remove(sender_keyword) if path_keyword: args.remove(path_keyword) if destination_keyword: args.remove(destination_keyword) if message_keyword: args.remove(message_keyword) if connection_keyword: args.remove(connection_keyword) if in_signature: in_sig = tuple(_dbus_bindings.Signature(in_signature)) if len(in_sig) > len(args): raise ValueError, 'input signature is longer than the number of arguments taken' elif len(in_sig) < len(args): raise ValueError, 'input signature is shorter than the number of arguments taken' func._dbus_is_method = True func._dbus_async_callbacks = async_callbacks func._dbus_interface = dbus_interface func._dbus_in_signature = in_signature func._dbus_out_signature = out_signature func._dbus_sender_keyword = sender_keyword func._dbus_path_keyword = path_keyword func._dbus_destination_keyword = destination_keyword func._dbus_message_keyword = message_keyword func._dbus_connection_keyword = connection_keyword func._dbus_args = args func._dbus_get_args_options = {'byte_arrays': byte_arrays, 'utf8_strings': utf8_strings} return func
def decorator(func): member_name = func.__name__ _dbus_bindings.validate_member_name(member_name) def emit_signal(self, *args, **keywords): abs_path = None if path_keyword is not None: if self.SUPPORTS_MULTIPLE_OBJECT_PATHS: raise TypeError('path_keyword cannot be used on the ' 'signals of an object that supports ' 'multiple object paths') abs_path = keywords.pop(path_keyword, None) if (abs_path != self.__dbus_object_path__ and not self.__dbus_object_path__.startswith(abs_path + '/')): raise ValueError('Path %r is not below %r', abs_path, self.__dbus_object_path__) rel_path = None if rel_path_keyword is not None: rel_path = keywords.pop(rel_path_keyword, None) func(self, *args, **keywords) for location in self.locations: if abs_path is None: # non-deprecated case if rel_path is None or rel_path in ('/', ''): object_path = location[1] else: # will be validated by SignalMessage ctor in a moment object_path = location[1] + rel_path else: object_path = abs_path message = _dbus_bindings.SignalMessage(object_path, dbus_interface, member_name) message.append(signature=signature, *args) location[0].send_message(message) # end emit_signal args = inspect.getargspec(func)[0] args.pop(0) for keyword in rel_path_keyword, path_keyword: if keyword is not None: try: args.remove(keyword) except ValueError: raise ValueError('function has no argument "%s"' % keyword) if signature: sig = tuple(_dbus_bindings.Signature(signature)) if len(sig) > len(args): raise ValueError, 'signal signature is longer than the number of arguments provided' elif len(sig) < len(args): raise ValueError, 'signal signature is shorter than the number of arguments provided' emit_signal.__name__ = func.__name__ emit_signal.__doc__ = func.__doc__ emit_signal._dbus_is_signal = True emit_signal._dbus_interface = dbus_interface emit_signal._dbus_signature = signature emit_signal._dbus_args = args return emit_signal
def _message_cb(self, connection, message): try: # lookup candidate method and parent method method_name = message.get_member() interface_name = message.get_interface() (candidate_method, parent_method) = _method_lookup(self, method_name, interface_name) # set up method call parameters args = message.get_args_list( **parent_method._dbus_get_args_options) keywords = {} if parent_method._dbus_out_signature is not None: signature = _dbus_bindings.Signature( parent_method._dbus_out_signature) else: signature = None # set up async callback functions if parent_method._dbus_async_callbacks: (return_callback, error_callback) = parent_method._dbus_async_callbacks keywords[ return_callback] = lambda *retval: _method_reply_return( connection, message, method_name, signature, *retval) keywords[ error_callback] = lambda exception: _method_reply_error( connection, message, exception) # include the sender etc. if desired if parent_method._dbus_sender_keyword: keywords[ parent_method._dbus_sender_keyword] = message.get_sender() if parent_method._dbus_path_keyword: keywords[parent_method._dbus_path_keyword] = message.get_path() if parent_method._dbus_destination_keyword: keywords[ parent_method. _dbus_destination_keyword] = message.get_destination() if parent_method._dbus_message_keyword: keywords[parent_method._dbus_message_keyword] = message if parent_method._dbus_connection_keyword: keywords[parent_method._dbus_connection_keyword] = connection # call method retval = candidate_method(self, *args, **keywords) # we're done - the method has got callback functions to reply with if parent_method._dbus_async_callbacks: return # otherwise we send the return values in a reply. if we have a # signature, use it to turn the return value into a tuple as # appropriate if signature is not None: signature_tuple = tuple(signature) # if we have zero or one return values we want make a tuple # for the _method_reply_return function, otherwise we need # to check we're passing it a sequence if len(signature_tuple) == 0: if retval == None: retval = () else: raise TypeError( '%s has an empty output signature but did not return None' % method_name) elif len(signature_tuple) == 1: retval = (retval, ) else: if operator.isSequenceType(retval): # multi-value signature, multi-value return... proceed unchanged pass else: raise TypeError( '%s has multiple output values in signature %s but did not return a sequence' % (method_name, signature)) # no signature, so just turn the return into a tuple and send it as normal else: if retval is None: retval = () elif (isinstance(retval, tuple) and not isinstance(retval, _dbus_bindings.Struct)): # If the return is a tuple that is not a Struct, we use it # as-is on the assumption that there are multiple return # values - this is the usual Python idiom. (fd.o #10174) pass else: retval = (retval, ) _method_reply_return(connection, message, method_name, signature, *retval) except Exception, exception: # send error reply _method_reply_error(connection, message, exception)