1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """The special auto-generated user function and class objects."""
24
25
26 import lib.arg_check
27 from prompt.uf_docstring import bold_text, build_subtitle, create_table, format_text
28 from prompt.help import relax_class_help
29 from lib.errors import RelaxError
30 from lib.text.string import strip_lead
31 from status import Status; status = Status()
32 from user_functions.data import Uf_info; uf_info = Uf_info()
33 from user_functions.objects import Desc_container
34
35
37 """The container for created the user function class objects."""
38
40 """Set up the container.
41
42 @param name: The name of the user function class.
43 @type name: str
44 @param desc: The description to be presented by the help system.
45 @type desc: str
46 """
47
48
49 self._name = name
50 self._desc = desc
51
52
54 """Replacement function for displaying an instance of this user function class."""
55
56
57 return "<The %s user function class object>" % self._name
58
59
107
108
109
111 """The object for auto-generating the user functions."""
112
113 - def __call__(self, *uf_args, **uf_kargs):
114 """Make the user function executable."""
115
116
117 for name in uf_kargs:
118
119 if name not in self._karg_names:
120 raise RelaxError("User function %s - the keyword argument '%s' is unknown." % (self._name, name))
121
122
123 num_args = len(uf_args)
124 new_args = []
125 if num_args:
126 for i in range(num_args):
127
128 if self._kargs[i]['name'] in uf_kargs:
129 raise RelaxError("User function %s - the argument '%s' and the keyword argument '%s' cannot both be supplied." % (self._name, uf_args[i], self._kargs[i]['name']))
130
131
132 uf_kargs[self._kargs[i]['name']] = uf_args[i]
133
134
135 for i in range(self._karg_num):
136
137 name = self._kargs[i]['name']
138
139
140 if name not in uf_kargs:
141 uf_kargs[name] = self._kargs[i]['default']
142
143
144 if status.uf_intro:
145
146 keys = []
147 values = []
148 for i in range(self._karg_num):
149 keys.append(self._kargs[i]['name'])
150 values.append(uf_kargs[self._kargs[i]['name']])
151
152
153 print(self._intro_text(keys, values))
154
155
156 for i in range(self._karg_num):
157 arg = self._kargs[i]
158 lib.arg_check.validate_arg(uf_kargs[self._kargs[i]['name']], arg['desc_short'], dim=arg['dim'], basic_types=arg['basic_types'], container_types=arg['container_types'], can_be_none=arg['can_be_none'], can_be_empty=arg['can_be_empty'], none_elements=arg['none_elements'])
159
160
161 self._backend(*new_args, **uf_kargs)
162
163
164 - def __init__(self, name, title=None, kargs=None, backend=None, desc=None):
165 """Set up the object.
166
167 @param name: The name of the user function.
168 @type name: str
169 @keyword title: The long title of the user function.
170 @type title: str
171 @keyword kargs: The list of keyword argument details.
172 @type kargs: list of dict
173 @keyword backend: The user function back end. This should be a string version with full module path of the function which executes the back end. For example 'pipe_control.pipes.create'. Note, this should be importable as __import__(backend)!
174 @type backend: executable object
175 @keyword desc: The full, multi-paragraph description.
176 @type desc: str
177 """
178
179
180 self._name = name
181 self._title = title
182 self._kargs = kargs
183 self._backend = backend
184 self._desc = desc
185
186
187 if title == None:
188 raise RelaxError("The title must be given.")
189
190
191 self._karg_num = len(self._kargs)
192 self._karg_names = []
193 for i in range(self._karg_num):
194 self._karg_names.append(self._kargs[i]['name'])
195
196
198 """Replacement function for displaying an instance of this user function class."""
199
200
201 return "<The %s user function>" % self._name
202
203
205 """Create the user function documentation.
206
207 @return: The user function documentation to use in the help system.
208 @rtype: str
209 """
210
211
212 if not isinstance(self._desc, list):
213 raise RelaxError("The user function 'desc' variable must be a list of Desc_container instances.")
214 for i in range(len(self._desc)):
215 if not isinstance(self._desc[i], Desc_container):
216 raise RelaxError("The user function 'desc' list element '%s' must be a list of Desc_container instances." % self._desc[i])
217
218
219 doc = ""
220
221
222 doc += build_subtitle("The %s user function." % self._name, start_nl=False)
223
224
225 doc += build_subtitle("Synopsis")
226 doc += "%s" % self._title
227 doc += "\n\n"
228
229
230 doc += build_subtitle("Defaults")
231 keys = []
232 values = []
233 for i in range(self._karg_num):
234 keys.append(self._kargs[i]['name'])
235 values.append(self._kargs[i]['default'])
236 doc += "%s" % format_text(self._intro_text(keys, values, prompt=False))
237 doc += "\n\n"
238
239
240 if self._kargs != None:
241 doc += build_subtitle("Keyword Arguments")
242 for i in range(len(self._kargs)):
243
244 text = " %s: %s" % (self._kargs[i]['name'], self._kargs[i]['desc'])
245
246
247 text = format_text(text)
248
249
250 length = 7 + len(self._kargs[i]['name'])
251 text = " %s: %s" % (bold_text(self._kargs[i]['name']), text[length:])
252
253
254 doc += "%s\n" % text
255
256
257 if isinstance(self._desc, list) and len(self._desc):
258
259 for i in range(len(self._desc)):
260
261 doc += build_subtitle(self._desc[i].get_title())
262
263
264 for type, element in self._desc[i].element_loop():
265
266 if type == 'paragraph':
267 doc += format_text(element) + '\n'
268
269
270 elif type == 'verbatim':
271 doc += element + '\n\n'
272
273
274 elif type == 'list':
275
276 for j in range(len(element)):
277 doc += format_text(" - %s" % element[j])
278
279
280 doc += '\n'
281
282
283 elif type == 'item list':
284
285 for j in range(len(element)):
286
287 if element[j][0] in [None, '']:
288 doc += format_text(" %s" % element[j][1])
289 else:
290 doc += format_text(" %s: %s" % (element[j][0], element[j][1]))
291
292
293 doc += '\n'
294
295
296 elif type == 'table':
297 doc += create_table(element) + '\n'
298
299
300 elif type == 'prompt':
301
302 for j in range(len(element)):
303 doc += format_text(element[j])
304
305
306 doc += '\n\n'
307
308
309 return doc
310
311
312 - def _intro_text(self, keys, values, prompt=True):
313 """Build and return the user function intro text.
314
315 @param keys: The user function keys.
316 @type keys: list of str
317 @param values: The values corresponding to the keys.
318 @type values: list
319 @keyword prompt: A flag which if True will cause the prompt text to be included.
320 @type prompt: bool
321 @return: The user function intro text.
322 @rtype: str
323 """
324
325
326 text = ""
327
328
329 if prompt:
330 text += status.ps3
331
332
333 text += "%s(" % self._name
334
335
336 for i in range(len(keys)):
337
338 if i >= 1:
339 text += ", "
340
341
342 text += "%s=%s" % (keys[i], repr(values[i]))
343
344
345 text += ")"
346
347
348 return text
349