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