merge upstream phpxmlrpc
[plcapi.git] / PLC / Methods / system / methodSignature.py
1 from PLC.Parameter import Parameter, Mixed
2 from PLC.Method import Method, xmlrpc_type
3 from functools import reduce
4
5 class methodSignature(Method):
6     """
7     Returns an array of known signatures (an array of arrays) for the
8     method name passed. If no signatures are known, returns a
9     none-array (test for type != array to detect missing signature).
10     """
11
12     roles = []
13     accepts = [Parameter(str, "Method name")]
14     returns = [Parameter([str], "Method signature")]
15
16     def __init__(self, api):
17         Method.__init__(self, api)
18         self.name = "system.methodSignature"
19
20     def possible_signatures(self, signature, arg):
21         """
22         Return a list of the possible new signatures given a current
23         signature and the next argument.
24         """
25
26         if isinstance(arg, Mixed):
27             arg_types = [xmlrpc_type(mixed_arg) for mixed_arg in arg]
28         else:
29             arg_types = [xmlrpc_type(arg)]
30
31         return [signature + [arg_type] for arg_type in arg_types]
32
33     def signatures(self, returns, args):
34         """
35         Returns a list of possible signatures given a return value and
36         a set of arguments.
37         """
38
39         signatures = [[xmlrpc_type(returns)]]
40
41         for arg in args:
42             # Create lists of possible new signatures for each current
43             # signature. Reduce the list of lists back down to a
44             # single list.
45             signatures = reduce(lambda a, b: a + b,
46                                 [self.possible_signatures(signature, arg) \
47                                  for signature in signatures])
48
49         return signatures
50
51     def call(self, method):
52         function = self.api.callable(method)
53         (min_args, max_args, defaults) = function.args()
54
55         signatures = []
56
57         assert len(max_args) >= len(min_args)
58         for num_args in range(len(min_args), len(max_args) + 1):
59             signatures += self.signatures(function.returns, function.accepts[:num_args])
60
61         return signatures