Package SPyRO :: Module args
[hide private]
[frames] | no frames]

Source Code for Module SPyRO.args

  1  #coding: utf-8; 
  2  ############################################################################ 
  3  #                                                                          # 
  4  #    This file 'args.py'                                                   # 
  5  #    is part of 'SPyRO: Simple Python Remote Objects'                      # 
  6  #    Copyright (C) 2004-2005 by Eric Sadit Tellez Avila                    # 
  7  #    Copyright (C) 2005-2006 by Eric Sadit Tellez Avila                    # 
  8  #    sadit@lsc.fie.umich.mx or donsadit@gmail.com                          # 
  9  #                                                                          # 
 10  #    This program is free software; you can redistribute it and#or modify  # 
 11  #    it under the terms of the GNU General Public License as published by  # 
 12  #    the Free Software Foundation; either version 2 of the License, or     # 
 13  #    (at your option) any later version.                                   # 
 14  #                                                                          # 
 15  #    This program is distributed in the hope that it will be useful,       # 
 16  #    but WITHOUT ANY WARRANTY; without even the implied warranty of        # 
 17  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         # 
 18  #    GNU General Public License for more details.                          # 
 19  #                                                                          # 
 20  #    You should have received a copy of the GNU General Public License     # 
 21  #    along with this program; if not, write to the                         # 
 22  #    Free Software Foundation, Inc.,                                       # 
 23  #    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             # 
 24  ############################################################################ 
 25   
 26  import types 
27 -def _set_booleans():
28 BooleanType = types.IntType 29 __builtins__['True'] = 1 30 __builtins__['False'] = 0
31 32 try: 33 BooleanType = types.BooleanType 34 True 35 except: 36 warn.warn("An old version of python or jython was detected") 37 _set_booleans() 38 39 __doc__ = """ 40 41 This module is an attempt to increment the security of SPyRO, giving 42 tools to check the type of the arguments passed to functions. 43 44 Note: Remote arguments passed by reference are not checked properly, and must 45 be checked in the returned values. 46 47 48 The form to specify the argument's costraints are given by a format string, a type or class, or None 49 50 If the format is an string, you can specify an OR operation, the followoing values can be used: 51 52 i => int 53 f => float 54 c => complex 55 o => an instance 56 s => string 57 u => an unicode string 58 b => boolean data 59 n => None, the argument can be None 60 l => list 61 t => tuple 62 d => dictionary 63 64 If the format is a type, class or a tuple of clases, it will be used as 65 second argument of the 'isinstace' statement. 66 67 If the format is None, then it will not be checked 68 69 The format to check arguments must be given in two elements: 70 positional arguments and named arguments. 71 72 73 """ 74 75 import types 76
77 -class Arguments:
78 """ 79 Check if the arguments are valid against |fmt_args|. 80 If any constraint is not valid, the function 81 will return raise a TypeError and will set the appropiate string in the 82 raised Exception. 83 84 If the number of the given arguments are lesser that supposed 85 it will raise TypeError too 86 87 A proper check of arguments inside functions can be performed using 88 the function 'local()' to retrieve local variables. And get the 89 retrieve arguments 90 91 |fmt_args| is a collection of tuples (argument_name, argument_value) 92 93 Example 94 ( ('arg1',fmt_arg1), 95 ('arg2',fmt_arg2), 96 ('arg3',fmt_arg3), 97 ... 98 ) 99 100 The arguments will be create two checking instances a list and a 101 dictionary. The list checks positional arguments |args|, then when 102 positional arguments are 103 exhausted, named arguments |kwargs| will be checked with the dictionary 104 validator. 105 """
106 - def __init__(self, fmt_args):
107 """ Compile an argument list to positional and keyword argument 108 formats """ 109 self.named = named = {} 110 self.positional = pos = [] 111 for name, format in fmt_args: 112 expformat = self._expand(format) 113 pos.append(expformat) 114 named[name] = expformat
115 116 Types = {'i': types.IntType, 117 'f': types.FloatType, 118 'c': types.ComplexType, 119 'o': types.InstanceType, 120 's': types.StringType, 121 'u': types.UnicodeType, 122 'b': types.BooleanType, 123 'n': types.NoneType, 124 'l': types.ListType, 125 'd': types.DictionaryType, 126 } 127
128 - def _expand(self, fmt):
129 """ Expands a format to an entity usable by isinstance or None""" 130 exp = [] 131 if exp is None: 132 return None 133 elif isinstance(fmt, types.StringTypes): 134 for x in fmt: 135 exp.append(Arguments.Types[x]) 136 return tuple(exp) 137 else: 138 return fmt
139
140 - def _checkarg(self, fmt, arg, nameorpos):
141 """ Check for an argument, sends a TypeError Exception 142 if arguments doesn't accomplish constraint """ 143 if fmt is None: 144 return 145 #print fmt 146 if not isinstance(arg, fmt): 147 raise TypeError, "Argument '%s' has not a valid type '%s', valid types are: %s"%(nameorpos, type(arg), fmt)
148 149
150 - def check(self, args=(), kwargs={}):
151 """ Check arguments """ 152 ipos = iter(self.positional) 153 pos = 1 154 for arg in args: 155 try: 156 self._checkarg(ipos.next(), arg, pos) 157 pos = pos + 1 158 except StopIteration: 159 raise TypeError, "Argument '%s' does not exists in the format of arguments"%pos 160 for name, arg in kwargs.items(): 161 try: 162 self._checkarg(self.named[name], arg, name) 163 except KeyError: 164 raise TypeError, "Argument '%s' does not exists in the format of arguments"%name 165 return True
166
167 -def check(fmt, args, kwargs):
168 argcheck = Arguments( fmt ) 169 argcheck.check(args, kwargs)
170
171 -def testfun1(arg1, arg2, arg3):
172 print type(arg1), type(arg2), type(arg3)
173 174 if __name__ == '__main__': 175 176 fmt = ( ("arg1","if"), 177 ("arg2","sn"), 178 ("argx","snf") ) 179 180 argcheck = Arguments( ( ("arg1","if"), 181 ("arg2","sn"), 182 ("argx","snf") ) ) 183 for args, kwargs in ( ( (1, None, 'sadit'), {'Fumofu':1} ), 184 ( (1, 1.1, 'sadit'), {}), 185 ( (1, 2, 'sadit'), {}), 186 ( (1, 'eric', 'sadit'), {})): 187 try: 188 print argcheck.check( args, kwargs ) 189 print "0-BUENO:", args 190 except Exception, err: 191 print "0-ERROR:", args, " -> ", err 192 193 194 try: 195 print check( fmt, args, kwargs ) 196 print "1-BUENO:", args 197 except Exception, err: 198 print "1-ERROR:", args, " -> ", err 199