1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import types
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
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 """
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
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
141 """ Check for an argument, sends a TypeError Exception
142 if arguments doesn't accomplish constraint """
143 if fmt is None:
144 return
145
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):
170
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