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

Source Code for Module prompt.uf_objects

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