1 """
2 Validators that confirm or convert types.
3
4 """
5
6 __docformat__ = "restructuredtext en"
7
8
9
10
11 from basevalidator import BaseValidator
12 import impl
13 import defs
14 from vocabval import Synonyms
15
16
17
18
19
20
22 """
23 Convert a value to a given type.
24
25 This is largely syntactic sugar: It will actually accept any callable as an
26 argument, but is intended for use with class constructors. You could use
27 raw types and classes, but this throws much nicer error messages. Conversion
28 is done by simply passing a value to the parameter callable.
29
30 """
31
32 - def __init__ (self, to_type, type_name=None):
33 """
34 Class c'tor, accepting a type.
35
36 :Parameters:
37 to_type : callable
38 A class constructor (old or new style), built-in type, or function
39 that can be called to convert a type and will throw if it fails.
40 type_name : string
41 A name for the type produced. If not supplied, it will be extracted
42 from `to_type` if possible.
43
44 For example::
45
46 >>> v = ToType(int, type_name='an integer')
47 >>> v(1)
48 1
49 >>> v(2.3)
50 2
51 >>> v('foo')
52 Traceback (most recent call last):
53 ...
54 ValueError: can't convert 'foo' to an integer
55 >>> v = ToType(float)
56 >>> v('foo')
57 Traceback (most recent call last):
58 ...
59 ValueError: can't convert 'foo' to float
60
61 """
62 self.to_type = to_type
63 if type_name is None:
64
65
66 if hasattr (to_type, '__name__'):
67 type_name = getattr (to_type, '__name__')
68
69 assert (type_name not in [None, '<lambda>']), \
70 "type validator requires type name for lambda"
71 self.type_name = type_name
72
74 """
75 Generate an appropriate error message for type conversion problem.
76 """
77
78 return "can't convert '%s' to %s" % (bad_val, self.type_name)
79
81 return self.to_type (value)
82
83
85 """
86 Convert a value to an integer.
87
88 While you could just use ``int``, this throws a much nicer error message.
89
90 For example::
91
92 >>> v = ToInt()
93 >>> v(1)
94 1
95 >>> v(2.3)
96 2
97 >>> v('foo')
98 Traceback (most recent call last):
99 ...
100 ValueError: can't convert 'foo' to integer
101
102 """
105
106
108 """
109 Convert a value to a float.
110
111 While you could just use ``float``, this throws a much nicer error message.
112
113 For example::
114
115 >>> v = ToFloat()
116 >>> v(1.0)
117 1.0
118 >>> v(2)
119 2.0
120 >>> v('foo')
121 Traceback (most recent call last):
122 ...
123 ValueError: can't convert 'foo' to float
124
125 """
128
129
131 """
132 Convert a value to a string.
133
134 While you could just use ``str``, this throws a much nicer error message.
135
136 For example::
137
138 >>> v = ToStr()
139 >>> v(1.0)
140 '1.0'
141 >>> v('foo')
142 'foo'
143
144 """
147
148
150 """
151 Convert a value to a string.
152
153 Makes sure that the result is a list, even if a list is passed in.
154
155 For example::
156
157 >>> v = ToList()
158 >>> v(1.0)
159 [1.0]
160 >>> v([])
161 []
162 >>> v([1, 2, 3])
163 [1, 2, 3]
164
165 """
168
169
171 """
172 Convert a value to a the best fit numerical representation.
173
174 For example::
175
176 >>> v = ToNumber()
177 >>> v('1')
178 1
179 >>> v('1.111')
180 1.111
181 >>> v(1.0)
182 1
183 >>> v(1.111)
184 1.111
185
186 """
188 float_value = float(value)
189 try:
190 int_value = int(value)
191 except:
192 return float_value
193 if float_value == int_value:
194 return int_value
195 return float_value
196
197
198
200 """
201 Checks that values are instances of a list of classes or their subclasses.
202
203 For example::
204
205 >>> v = IsInstance (basestring)
206 >>> v('foo')
207 'foo'
208 >>> v(1)
209 Traceback (most recent call last):
210 ...
211 ValueError: '1' type is not one of basestring
212
213 """
215 self.allowed_classes = tuple (impl.make_list (allowed_classes))
216
218 return isinstance (value, self.allowed_classes)
219
221
222 return "'%s' type is not one of %s" % (bad_val,
223 ', '.join([t.__name__ for t in self.allowed_classes]))
224
225
227 """
228 Checks that values are instances of a list of classes (not their subclasses).
229
230 For example::
231
232 >>> v = IsType (basestring)
233 >>> v('foo')
234 Traceback (most recent call last):
235 ...
236 ValueError: 'foo' type is not an instance of basestring
237 >>> v = IsType ([basestring, str])
238 >>> v('foo')
239 'foo'
240 >>> v(1)
241 Traceback (most recent call last):
242 ...
243 ValueError: '1' type is not an instance of basestring, str
244
245 """
247 self.allowed_classes = tuple (impl.make_list (allowed_classes))
248
250 for t in self.allowed_classes:
251 if type(value) is t:
252 return True
253 return False
254
255
257
258 return "'%s' type is not an instance of %s" % (bad_val,
259 ', '.join([t.__name__ for t in self.allowed_classes]))
260
261
263 """
264 Converts common abbreviations for true-false to boolean values.
265
266 This converts common abbreviations for true/false to actual Booleans. Case
267 and flanking spaces are ignored. The allowed values are defined in `defs`.
268 For example::
269
270 >>> v = StrToBool()
271 >>> v("True")
272 True
273 >>> v("f")
274 False
275 >>> v(" on ")
276 True
277 >>> v("0")
278 False
279 >>> v("yEs")
280 True
281 >>> v("maybe")
282 Traceback (most recent call last):
283 ...
284 ValueError: can't recognise MAYBE' as true or false
285
286 """
289
292
295
297 return "can't recognise %s' as true or false" % (bad_val)
298
299
300
301
302
303 if __name__ == "__main__":
304 import doctest
305 doctest.testmod()
306
307
308
309
310