Package prompt :: Module uf_objects
[hide private]
[frames] | no frames]

Source Code for Module prompt.uf_objects

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2012-2013 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """The special auto-generated user function and class objects.""" 
 24   
 25  # relax module imports. 
 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   
36 -class Class_container(object):
37 """The container for created the user function class objects.""" 38
39 - def __init__(self, name, desc):
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 # Store the args. 49 self._name = name 50 self._desc = desc
51 52
53 - def __repr__(self):
54 """Replacement function for displaying an instance of this user function class.""" 55 56 # Return a description. 57 return "<The %s user function class object>" % self._name
58 59
60 - def _build_doc(self):
61 """Create the user function class documentation. 62 63 @return: The user function class documentation to use in the help system. 64 @rtype: str 65 """ 66 67 # Initialise. 68 doc = "" 69 70 # The title. 71 doc += build_subtitle("The %s user function class." % self._name, start_nl=False) 72 73 # The synopsis. 74 doc += build_subtitle("Synopsis") 75 doc += self._desc 76 doc += "\n\n" 77 78 # Usage help string. 79 doc += build_subtitle("Usage") 80 doc += format_text(relax_class_help) 81 doc += "\n" 82 83 # Add a description to the help string. 84 if hasattr(self, '__description__'): 85 doc += build_subtitle("Description") 86 doc += "\n\n%s\n" % strip_lead(self.__description__) 87 88 # The member user functions. 89 doc += build_subtitle("Contents") 90 doc += "This class contains the following user functions:\n\n" 91 for uf_name, uf in uf_info.uf_loop(self._name): 92 # The unformatted text. 93 text = " %s: %s" % (uf_name, uf.title) 94 95 # Format. 96 text = format_text(text) 97 98 # Replace the arg text with bold text. 99 length = 7 + len(uf_name) 100 text = " %s: %s" % (bold_text(uf_name), text[length:]) 101 102 # Add to the docstring. 103 doc += "%s\n" % text 104 105 # Return the documentation. 106 return doc
107 108 109
110 -class Uf_object(object):
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 # Check the keyword args. 117 keys = uf_kargs.keys() 118 for name in keys: 119 # Unknown keyword. 120 if name not in self._karg_names: 121 raise RelaxError("User function %s - the keyword argument '%s' is unknown." % (self._name, name)) 122 123 # Convert the args to keyword args if needed. 124 num_args = len(uf_args) 125 new_args = [] 126 if num_args: 127 for i in range(num_args): 128 # Check if the keyword is already assigned. 129 if self._kargs[i]['name'] in keys: 130 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'])) 131 132 # Add the arg as a keyword arg. 133 uf_kargs[self._kargs[i]['name']] = uf_args[i] 134 135 # Set the argument defaults. 136 for i in range(self._karg_num): 137 # The keyword. 138 name = self._kargs[i]['name'] 139 140 # Set the default if the user has not supplied a value. 141 if name not in uf_kargs.keys(): 142 uf_kargs[name] = self._kargs[i]['default'] 143 144 # Function intro text. 145 if status.uf_intro: 146 # Convert the keys and values. 147 keys = [] 148 values = [] 149 for i in range(self._karg_num): 150 keys.append(self._kargs[i]['name']) 151 values.append(uf_kargs[self._kargs[i]['name']]) 152 153 # The printout. 154 print(self._intro_text(keys, values)) 155 156 # Check the argument values. 157 for i in range(self._karg_num): 158 # Aliases. 159 value = uf_kargs[self._kargs[i]['name']] 160 arg = self._kargs[i] 161 py_type = arg['py_type'] 162 desc_short = arg['desc_short'] 163 dim = arg['dim'] 164 can_be_none = arg['can_be_none'] 165 can_be_empty = arg['can_be_empty'] 166 none_elements = arg['none_elements'] 167 168 # Check if the correct Python object type has been supplied. 169 if py_type == 'bool': 170 lib.arg_check.is_bool(value, desc_short) 171 elif py_type == 'float': 172 lib.arg_check.is_float(value, desc_short, can_be_none=can_be_none) 173 elif py_type == 'float_array': 174 lib.arg_check.is_float_array(value, desc_short, size=dim, can_be_none=can_be_none) 175 elif py_type == 'float_matrix': 176 lib.arg_check.is_float_matrix(value, desc_short, dim=dim, can_be_none=can_be_none) 177 elif py_type == 'float_object': 178 lib.arg_check.is_float_object(value, desc_short, dim=dim, can_be_none=can_be_none) 179 elif py_type == 'func': 180 lib.arg_check.is_func(value, desc_short, can_be_none=can_be_none) 181 elif py_type == 'int': 182 lib.arg_check.is_int(value, desc_short, can_be_none=can_be_none) 183 elif py_type == 'int_list': 184 lib.arg_check.is_int_list(value, desc_short, size=dim, can_be_none=can_be_none) 185 elif py_type == 'int_or_int_list': 186 lib.arg_check.is_int_or_int_list(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty, none_elements=none_elements) 187 elif py_type == 'list': 188 lib.arg_check.is_list(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 189 elif py_type == 'list_val_or_list_of_list_val': 190 lib.arg_check.is_list_val_or_list_of_list_val(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty, list_of_lists=True) 191 elif py_type == 'none': 192 lib.arg_check.is_none(value, desc_short) 193 elif py_type == 'num': 194 lib.arg_check.is_num(value, desc_short, can_be_none=can_be_none) 195 elif py_type == 'num_list': 196 lib.arg_check.is_num_list(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 197 elif py_type == 'num_or_num_tuple': 198 lib.arg_check.is_num_or_num_tuple(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 199 elif py_type == 'num_tuple': 200 lib.arg_check.is_num_tuple(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 201 elif py_type == 'str': 202 lib.arg_check.is_str(value, desc_short, can_be_none=can_be_none) 203 elif py_type == 'str_list': 204 lib.arg_check.is_str_list(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 205 elif py_type == 'str_list_of_lists': 206 lib.arg_check.is_str_list(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty, list_of_lists=True) 207 elif py_type == 'str_or_inst': 208 lib.arg_check.is_str_or_inst(value, desc_short, can_be_none=can_be_none) 209 elif py_type == 'str_or_num_or_str_num_list': 210 lib.arg_check.is_str_or_num_or_str_num_list(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 211 elif py_type == 'str_or_num_list': 212 lib.arg_check.is_str_or_num_list(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 213 elif py_type == 'str_or_str_list': 214 lib.arg_check.is_str_or_str_list(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 215 elif py_type == 'tuple': 216 lib.arg_check.is_tuple(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 217 elif py_type == 'val_or_list': 218 lib.arg_check.is_val_or_list(value, desc_short, size=dim, can_be_none=can_be_none, can_be_empty=can_be_empty) 219 else: 220 raise RelaxError("User function %s - the Python object type '%s' is unknown." % (self._name, py_type)) 221 222 # Execute the functional code. 223 self._backend(*new_args, **uf_kargs)
224 225
226 - def __init__(self, name, title=None, kargs=None, backend=None, desc=None):
227 """Set up the object. 228 229 @param name: The name of the user function. 230 @type name: str 231 @keyword title: The long title of the user function. 232 @type title: str 233 @keyword kargs: The list of keyword argument details. 234 @type kargs: list of dict 235 @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)! 236 @type backend: executable object 237 @keyword desc: The full, multi-paragraph description. 238 @type desc: str 239 """ 240 241 # Store the args. 242 self._name = name 243 self._title = title 244 self._kargs = kargs 245 self._backend = backend 246 self._desc = desc 247 248 # Check the args. 249 if title == None: 250 raise RelaxError("The title must be given.") 251 252 # Generate fixed keyword argument data structures (for faster execution). 253 self._karg_num = len(self._kargs) 254 self._karg_names = [] 255 for i in range(self._karg_num): 256 self._karg_names.append(self._kargs[i]['name'])
257 258
259 - def __repr__(self):
260 """Replacement function for displaying an instance of this user function class.""" 261 262 # Return a description. 263 return "<The %s user function>" % self._name
264 265
266 - def _build_doc(self):
267 """Create the user function documentation. 268 269 @return: The user function documentation to use in the help system. 270 @rtype: str 271 """ 272 273 # Checks. 274 if not isinstance(self._desc, list): 275 raise RelaxError("The user function 'desc' variable must be a list of Desc_container instances.") 276 for i in range(len(self._desc)): 277 if not isinstance(self._desc[i], Desc_container): 278 raise RelaxError("The user function 'desc' list element '%s' must be a list of Desc_container instances." % self._desc[i]) 279 280 # Initialise. 281 doc = "" 282 283 # The title. 284 doc += build_subtitle("The %s user function." % self._name, start_nl=False) 285 286 # The synopsis. 287 doc += build_subtitle("Synopsis") 288 doc += "%s" % self._title 289 doc += "\n\n" 290 291 # The defaults. 292 doc += build_subtitle("Defaults") 293 keys = [] 294 values = [] 295 for i in range(self._karg_num): 296 keys.append(self._kargs[i]['name']) 297 values.append(self._kargs[i]['default']) 298 doc += "%s" % format_text(self._intro_text(keys, values, prompt=False)) 299 doc += "\n\n" 300 301 # Add the keyword args. 302 if self._kargs != None: 303 doc += build_subtitle("Keyword Arguments") 304 for i in range(len(self._kargs)): 305 # The unformatted text. 306 text = " %s: %s" % (self._kargs[i]['name'], self._kargs[i]['desc']) 307 308 # Format. 309 text = format_text(text) 310 311 # Replace the arg text with bold text. 312 length = 7 + len(self._kargs[i]['name']) 313 text = " %s: %s" % (bold_text(self._kargs[i]['name']), text[length:]) 314 315 # Add to the docstring. 316 doc += "%s\n" % text 317 318 # Add the description sections. 319 if isinstance(self._desc, list) and len(self._desc): 320 # Loop over the sections. 321 for i in range(len(self._desc)): 322 # The title. 323 doc += build_subtitle(self._desc[i].get_title()) 324 325 # Loop over the elements. 326 for type, element in self._desc[i].element_loop(): 327 # A paragraph or verbatim text. 328 if type == 'paragraph': 329 doc += format_text(element) + '\n' 330 331 # Verbatim text. 332 elif type == 'verbatim': 333 doc += element + '\n\n' 334 335 # A list. 336 elif type == 'list': 337 # Loop over the list elements. 338 for j in range(len(element)): 339 doc += format_text(" - %s" % element[j]) 340 341 # Final newline. 342 doc += '\n' 343 344 # An itemised list. 345 elif type == 'item list': 346 # Loop over the list elements. 347 for j in range(len(element)): 348 # No item. 349 if element[j][0] in [None, '']: 350 doc += format_text(" %s" % element[j][1]) 351 else: 352 doc += format_text(" %s: %s" % (element[j][0], element[j][1])) 353 354 # Final newline. 355 doc += '\n' 356 357 # A table. 358 elif type == 'table': 359 doc += create_table(element) + '\n' 360 361 # A prompt example. 362 elif type == 'prompt': 363 # Loop over the prompt examples. 364 for j in range(len(element)): 365 doc += format_text(element[j]) 366 367 # Final double newline. 368 doc += '\n\n' 369 370 # Return the documentation. 371 return doc
372 373
374 - def _intro_text(self, keys, values, prompt=True):
375 """Build and return the user function intro text. 376 377 @param keys: The user function keys. 378 @type keys: list of str 379 @param values: The values corresponding to the keys. 380 @type values: list 381 @keyword prompt: A flag which if True will cause the prompt text to be included. 382 @type prompt: bool 383 @return: The user function intro text. 384 @rtype: str 385 """ 386 387 # Initialise. 388 text = "" 389 390 # The prompt. 391 if prompt: 392 text += status.ps3 393 394 # The user function name. 395 text += "%s(" % self._name 396 397 # The keyword args. 398 for i in range(len(keys)): 399 # Comma separation. 400 if i >= 1: 401 text += ", " 402 403 # Add the arg. 404 text += "%s=%s" % (keys[i], repr(values[i])) 405 406 # The end. 407 text += ")" 408 409 # Return the text. 410 return text
411