1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 __docformat__ = 'reStructuredText'
20
21 import logging
22
23 from . import Parameter
24
25 _logger = logging.getLogger("pytilities.overloading.compositeparameter")
26
28
29 """
30 `Parameter` that consists of more parameters.
31
32 This parameter matches lists, tuples and dicts, of which all elements match
33 the list of child parameters.
34
35 When this parameter is written to a dict, its child parameters are
36 expanded. E.g. for a composite parameter with childs 'x' and 'y', a read
37 value of (1, 3) and a dict d of {}; after writing to d, d will equal {x:1, y:3},
38 and not {{x:1, y:3}}.
39
40 Methods:
41
42 - all of `Parameter`
43 """
44
45 - def __init__(self, name, params, matcher = (tuple, list, dict), *args, **kwargs):
46 """
47 Construct a `CompositeParameter`.
48
49 Parameters:
50
51 `name` :: string
52 name of the parameter, used for keyword arguments. Must be
53 unique.
54
55 `params` :: (Parameter...)
56 the child parameters of the composite
57
58 `matcher` :: f(value) -> matched::bool
59 :: (type...) = (tuple, list, dict)
60 :: type
61 the parameter will match only if this matcher matches the arg
62 and its child args match the elements of the arg. It is
63 unlikely you'll need a value other than the default.
64
65 `default`
66 default value for the parameter, omit if param has no default
67 """
68 Parameter.__init__(self, name, matcher, *args, **kwargs)
69 self.__params = params
70 self.__arg_matcher = self._matcher
71 self._matcher = self.__match
72
74
75 if not self.__arg_matcher(value):
76 return False
77
78
79 if len(value) != len(self.__params):
80 return False
81
82
83 if isinstance(value, dict):
84 for param in self.__params:
85 if not param.read_kwargs(kwargs):
86 _logger.debug("Overload failed to match, failed at %s" %
87 param)
88 return False
89 else:
90 for arg, param in zip(value, self.__params):
91 if not param.read_arg(arg):
92 _logger.debug("Overload failed to match, failed at %s" %
93 param)
94 return False
95
96 return True
97
99 assert self._matched, \
100 "write() may only be called after a succesful read()"
101
102 for param in self.__params:
103 param.write(kwargs)
104
105
106
107 CompositeParam = CompositeParameter
108