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 .matchers import matches_everything, matches_type
24
25 _logger = logging.getLogger("pytilities.overloading.parameter")
28
29 """
30 A parameter of an operation.
31
32 It can match arguments and provide default values for them.
33
34 Note that an argument matches a parameter, if its matcher returns True on
35 the argument value or the parameter has a default.
36
37 Methods:
38
39 - `read_arg`: Read/process the given arg.
40 - `read_kwargs`: Look in a dict for a matching arg and process its value
41 - `write`: Adds the last read argument value to a dictionary.
42 """
43
44
46 """
47 Construct a `Parameter`.
48
49 Parameters:
50
51 `name` :: string
52 name of parameter as specified in keyword arguments
53
54 `matcher` ::
55 Either of:
56
57 - type of the parameter
58 - iterable of possible types of param
59 - a matcher function :: f(value) -> matched::bool
60
61 `default`
62 default value for the parameter. Omit if param has no default
63
64 Preconditions:
65 1. `default` must match the specified matcher
66 """
67
68 assert name, "Name param musn't be empty or None"
69 assert isinstance(name, basestring), "Name must be a string"
70 assert len(args) <= 1, \
71 "Unexpected trailing args: %s" % args
72 assert not (args and "default" in kwargs), (
73 "Default specified twice: by *args(%s) and **kwargs(%s)" %
74 (args[0], kwargs["default"]))
75
76 self.__name = name
77
78 if hasattr(matcher, "__iter__"):
79
80 self._matcher = matches_type(*matcher)
81 elif isinstance(matcher, type):
82
83 self._matcher = matches_type(matcher)
84 else:
85
86 self._matcher = matcher
87
88 self.__has_default = True
89 if args:
90 self.__default = args[0]
91 elif "default" in kwargs:
92 self.__default = kwargs["default"]
93 else:
94 self.__has_default = False
95
96 assert not self.__has_default or \
97 self._matcher(self.__default), (
98 "Default must match the given matcher as well. (Precondition 1) Default: %s" %
99 (self.__default))
100
101
102 self.__matched = False
103
104
105
106
107
108
110 """
111 Read/process the given arg.
112
113 Parameters:
114
115 `arg`
116 the argument value to read
117
118 Returns True if parameter matches `arg` :: bool
119 """
120 self.__value = arg
121 self.__matched = self._matcher(self.__value)
122 return self.__matched
123
125 """
126 Look in a dict for a matching arg and process its value.
127
128 Parameters:
129
130 `kwargs` :: {name::string : value}
131 dictionary of arguments
132
133 Returns True if a matching argument was found in `kwargs` :: bool
134 """
135
136 if self.__name in kwargs:
137 return self.read_arg(kwargs[self.__name])
138 elif self.__has_default:
139 self.__matched = True
140 self.__value = self.__default
141 else:
142 self.__matched = False
143
144 return self.__matched
145
146 - def write(self, kwargs):
147 """
148 Adds the last read argument value to a dictionary.
149
150 Parameters:
151
152 `kwargs` :: {name::string : value}
153 the dictionary to add the last value and the parameter name to
154
155 Preconditions:
156
157 1. the parameter matched on the last read
158 """
159
160 assert self.__matched, \
161 "write() may only be called after a succesful read()"
162
163 kwargs[self.__name] = self.__value
164
165 @property
167 return self.__matched
168
169
170
171 Param = Parameter
172
173
174
175
176
177