bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1  | 
===================================  | 
2  | 
Validation Schema with validate.py  | 
|
3  | 
===================================  | 
|
4  | 
||
5  | 
--------------------------  | 
|
6  | 
Using the Validator class  | 
|
7  | 
--------------------------  | 
|
8  | 
||
9  | 
||
10  | 
:Authors: `Michael Foord`_, `Nicola Larosa`_, `Mark Andrews`_  | 
|
11  | 
:Version: Validate 0.2.0  | 
|
12  | 
:Date: 2005/08/25  | 
|
13  | 
:Homepage: `Validate Homepage`_  | 
|
14  | 
:License: `BSD License`_  | 
|
15  | 
:Support: `Mailing List`_  | 
|
16  | 
||
17  | 
.. _Mailing List: http://lists.sourceforge.net/lists/listinfo/configobj-develop  | 
|
18  | 
.. _Michael Foord: fuzzyman@voidspace.org.uk  | 
|
19  | 
.. _Nicola Larosa: nico@teknico.net  | 
|
20  | 
.. _Mark Andrews: mark@la-la.com  | 
|
21  | 
.. _This Document:  | 
|
22  | 
.. _Validate Homepage: http://www.voidspace.org.uk/python/validate.html  | 
|
23  | 
.. _BSD License: http://www.voidspace.org.uk/documents/BSD-LICENSE.txt  | 
|
24  | 
||
25  | 
||
26  | 
.. contents:: Validate Manual  | 
|
27  | 
||
28  | 
Introduction  | 
|
29  | 
============  | 
|
30  | 
||
31  | 
Validation is used to check that supplied values conform to a specification.  | 
|
32  | 
||
33  | 
The value can be supplied as a string, e.g. from a config file. In this case  | 
|
34  | 
the check will also *convert* the value to the required type. This allows you  | 
|
35  | 
to add validation as a transparent layer to access data stored as strings. The  | 
|
36  | 
validation checks that the data is correct *and* converts it to the expected  | 
|
37  | 
type.  | 
|
38  | 
||
39  | 
Checks are also strings, and are easy to write. One generic system can be used  | 
|
40  | 
to validate information from different sources, via a single consistent  | 
|
41  | 
mechanism.  | 
|
42  | 
||
43  | 
Checks look like function calls, and map to function calls. They can include  | 
|
44  | 
parameters and keyword arguments. These arguments are passed to the relevant  | 
|
45  | 
function by the ``Validator`` instance, along with the value being checked.  | 
|
46  | 
||
47  | 
The syntax for checks also allows for specifying a default value. This default  | 
|
48  | 
value can be ``None``, no matter what the type of the check. This can be used  | 
|
49  | 
to indicate that a value was missing, and so holds no useful value.  | 
|
50  | 
||
51  | 
Functions either return a new value, or raise an exception. See `Validator  | 
|
52  | 
Exceptions`_ for the low down on the exception classes that ``validate.py``  | 
|
53  | 
defines.  | 
|
54  | 
||
55  | 
Some standard functions are provided, for basic data types; these come built  | 
|
56  | 
into every validator. Additional checks are easy to write: they can be provided  | 
|
57  | 
when the ``Validator`` is instantiated, or added afterwards.  | 
|
58  | 
||
59  | 
Validate was primarily written to support ConfigObj_, but was designed to be  | 
|
60  | 
applicable to many other situations.  | 
|
61  | 
||
62  | 
For support and bug reports please use the ConfigObj `Mailing List`_.  | 
|
63  | 
||
64  | 
.. _ConfigObj: http://www.voidspace.org.uk/python/configobj.html  | 
|
65  | 
||
66  | 
Downloading  | 
|
67  | 
===========  | 
|
68  | 
||
69  | 
The current version is **0.2.0**, dated 25th August 2005.  | 
|
70  | 
||
71  | 
You can get obtain validate in the following ways :  | 
|
72  | 
||
73  | 
Files  | 
|
74  | 
-----  | 
|
75  | 
||
76  | 
* validate.py_ from Voidspace  | 
|
77  | 
||
78  | 
* configobj.zip from Voidspace - See the homepage of ConfigObj_ for the latest  | 
|
79  | 
version and downlaod links.  | 
|
80  | 
||
81  | 
This contains validate.py and `this document`_. (As well as ConfigObj_ and  | 
|
82  | 
the ConfigObj documentation).  | 
|
83  | 
||
84  | 
* The latest development version can be obtained from the `Subversion Repository`_.  | 
|
85  | 
||
86  | 
Documentation  | 
|
87  | 
-------------  | 
|
88  | 
||
89  | 
*configobj.zip* contains `this document`_ and full `API Docs`_, generated  | 
|
90  | 
automatically by EpyDoc_.  | 
|
91  | 
||
92  | 
* You can view `this document`_ online as the `Validate Homepage`_.  | 
|
93  | 
||
94  | 
* You can also browse the `API Docs`_ online.  | 
|
95  | 
||
96  | 
Pythonutils  | 
|
97  | 
-----------  | 
|
98  | 
||
99  | 
Validate_ is also part of the Pythonutils_ set of modules. This contains  | 
|
100  | 
various other useful helper modules, and is required by many of the `Voidspace  | 
|
101  | 
Python Projects`_.  | 
|
102  | 
||
103  | 
.. _configobj.py: http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=configobj.py  | 
|
104  | 
.. _configobj.zip: http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=configobj-4.0.0b4.zip  | 
|
105  | 
.. _validate.py: http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=validate.py  | 
|
106  | 
.. _API Docs: http://www.voidspace.org.uk/python/configobj-api/  | 
|
107  | 
.. _Subversion Repository: http://svn.rest2web.python-hosting.com/branches/configobj4/  | 
|
108  | 
.. _Sourceforge: http://sourceforge.net/projects/configobj  | 
|
109  | 
.. _EpyDoc: http://epydoc.sourceforge.net  | 
|
110  | 
.. _pythonutils: http://www.voidspace.org.uk/python/pythonutils.html  | 
|
111  | 
.. _Voidspace Python Projects: http://www.voidspace.org.uk/python  | 
|
112  | 
.. _validate: http://www.voidspace.org.uk/python/validate.html  | 
|
113  | 
||
114  | 
||
115  | 
The standard functions  | 
|
116  | 
======================  | 
|
117  | 
||
118  | 
The standard functions come built-in to every ``Validator`` instance. They work  | 
|
119  | 
with the following basic data types :  | 
|
120  | 
||
121  | 
* integer  | 
|
122  | 
* float  | 
|
123  | 
* boolean  | 
|
124  | 
* string  | 
|
125  | 
* ip_addr  | 
|
126  | 
||
127  | 
plus lists of these datatypes.  | 
|
128  | 
||
129  | 
Adding additional checks is done through coding simple functions.  | 
|
130  | 
||
131  | 
The full set of standard checks are :  | 
|
132  | 
||
133  | 
:'integer': matches integer values (including negative). Takes optional 'min'  | 
|
134  | 
and 'max' arguments : ::  | 
|
135  | 
||
136  | 
integer()  | 
|
137  | 
integer(3, 9) # any value from 3 to 9  | 
|
138  | 
integer(min=0) # any positive value  | 
|
139  | 
integer(max=9)  | 
|
140  | 
||
141  | 
:'float': matches float values  | 
|
142  | 
Has the same parameters as the integer check.  | 
|
143  | 
||
144  | 
:'bool': matches boolean values: ``True`` or ``False``.  | 
|
145  | 
Acceptable string values for True are : ::  | 
|
146  | 
||
147  | 
true, on, yes, 1  | 
|
148  | 
||
149  | 
Acceptable string values for False are : ::  | 
|
150  | 
||
151  | 
false, off, no, 0  | 
|
152  | 
||
153  | 
Any other value raises an error.  | 
|
154  | 
||
155  | 
:'string': matches any string. Takes optional keyword args 'min' and 'max' to  | 
|
156  | 
specify min and max length of string.  | 
|
157  | 
||
158  | 
:'ip_addr': matches an Internet Protocol address, v.4, represented by a  | 
|
159  | 
dotted-quad string, i.e. '1.2.3.4'.  | 
|
160  | 
||
161  | 
:'list': matches any list. Takes optional keyword args 'min', and 'max' to  | 
|
162  | 
specify min and max sizes of the list.  | 
|
163  | 
||
164  | 
:'int_list': Matches a list of integers. Takes the same arguments as list.  | 
|
165  | 
||
166  | 
:'float_list': Matches a list of floats. Takes the same arguments as list.  | 
|
167  | 
||
168  | 
:'bool_list': Matches a list of boolean values. Takes the same arguments as  | 
|
169  | 
list.  | 
|
170  | 
||
171  | 
:'string_list': Matches a list of strings. Takes the same arguments as list.  | 
|
172  | 
||
173  | 
:'ip_addr_list': Matches a list of IP addresses. Takes the same arguments as  | 
|
174  | 
list.  | 
|
175  | 
||
176  | 
:'mixed_list': Matches a list with different types in specific positions.  | 
|
177  | 
List size must match the number of arguments.  | 
|
178  | 
||
179  | 
Each position can be one of : ::  | 
|
180  | 
||
181  | 
int, str, bool, float, ip_addr  | 
|
182  | 
||
183  | 
So to specify a list with two strings followed by two integers,  | 
|
184  | 
you write the check as : ::  | 
|
185  | 
||
186  | 
mixed_list(str, str, int, int)  | 
|
187  | 
||
188  | 
:'pass': matches everything: it never fails and the value is unchanged. It is  | 
|
189  | 
also the default if no check is specified.  | 
|
190  | 
||
191  | 
:'option': matches any from a list of options.  | 
|
192  | 
You specify this test with : ::  | 
|
193  | 
||
194  | 
               option('option 1', 'option 2', 'option 3')
 | 
|
195  | 
||
196  | 
The following code will work without you having to specifically add the  | 
|
197  | 
functions yourself.  | 
|
198  | 
||
199  | 
.. raw:: html  | 
|
200  | 
||
201  | 
    {+coloring}
 | 
|
202  | 
||
203  | 
from validate import Validator  | 
|
204  | 
#  | 
|
205  | 
vtor = Validator()  | 
|
206  | 
newval1 = vtor.check(value1, 'integer')  | 
|
207  | 
newval2 = vtor.check(value2, 'bool')  | 
|
208  | 
# etc ...  | 
|
209  | 
||
210  | 
    {-coloring}
 | 
|
211  | 
||
212  | 
.. note::  | 
|
213  | 
||
214  | 
Of course, if these checks fail they raise exceptions. So you should wrap  | 
|
215  | 
them in ``try...except`` blocks. Better still, use ConfigObj for a higher  | 
|
216  | 
level interface.  | 
|
217  | 
||
218  | 
Using Validator  | 
|
219  | 
===============  | 
|
220  | 
||
221  | 
Using ``Validator`` is very easy. It has one public attribute and one public  | 
|
222  | 
method.  | 
|
223  | 
||
224  | 
Shown below are the different steps in using ``Validator``.  | 
|
225  | 
||
226  | 
The only additional thing you need to know, is about `Writing check  | 
|
227  | 
functions`_.  | 
|
228  | 
||
229  | 
Instantiate  | 
|
230  | 
-----------  | 
|
231  | 
||
232  | 
.. raw:: html  | 
|
233  | 
||
234  | 
    {+coloring}
 | 
|
235  | 
||
236  | 
from validate import Validator  | 
|
237  | 
vtor = Validator()  | 
|
238  | 
||
239  | 
    {-coloring}
 | 
|
240  | 
||
241  | 
or even :  | 
|
242  | 
||
243  | 
.. raw:: html  | 
|
244  | 
||
245  | 
    {+coloring}
 | 
|
246  | 
||
247  | 
from validate import Validator  | 
|
248  | 
#  | 
|
249  | 
    fdict = {
 | 
|
250  | 
'check_name1': function1,  | 
|
251  | 
'check_name2': function2,  | 
|
252  | 
'check_name3': function3,  | 
|
253  | 
}  | 
|
254  | 
#  | 
|
255  | 
vtor = Validator(fdict)  | 
|
256  | 
||
257  | 
    {-coloring}
 | 
|
258  | 
||
259  | 
The second method adds a set of your functions as soon as your validator is  | 
|
260  | 
created. They are stored in the ``vtor.functions`` dictionary. The 'key' you  | 
|
261  | 
give them in this dictionary is the name you use in your checks (not the  | 
|
262  | 
original function name).  | 
|
263  | 
||
264  | 
Dictionary keys/functions you pass in can override the built-in ones if you  | 
|
265  | 
want.  | 
|
266  | 
||
267  | 
Adding functions  | 
|
268  | 
----------------  | 
|
269  | 
||
270  | 
The code shown above, for adding functions on instantiation, has exactly the  | 
|
271  | 
same effect as the following code :  | 
|
272  | 
||
273  | 
.. raw:: html  | 
|
274  | 
||
275  | 
    {+coloring}
 | 
|
276  | 
||
277  | 
from validate import Validator  | 
|
278  | 
#  | 
|
279  | 
vtor = Validator()  | 
|
280  | 
vtor.functions['check_name1'] = function1  | 
|
281  | 
vtor.functions['check_name2'] = function2  | 
|
282  | 
vtor.functions['check_name3'] = function3  | 
|
283  | 
||
284  | 
    {-coloring}
 | 
|
285  | 
||
286  | 
``vtor.functions``is just a dictionary that maps names to functions, so we  | 
|
287  | 
could also have called ``vtor.functions.update(fdict)``.  | 
|
288  | 
||
289  | 
Writing the check  | 
|
290  | 
-----------------  | 
|
291  | 
||
292  | 
As we've heard, the checks map to the names in the ``functions`` dictionary.  | 
|
293  | 
You've got a full list of `The standard functions`_ and the arguments they  | 
|
294  | 
take.  | 
|
295  | 
||
296  | 
If you're using ``Validator`` from ConfigObj, then your checks will look like  | 
|
297  | 
: ::  | 
|
298  | 
||
299  | 
keyword = int_list(max=6)  | 
|
300  | 
||
301  | 
but the check part will be identical .  | 
|
302  | 
||
303  | 
The check method  | 
|
304  | 
----------------  | 
|
305  | 
||
306  | 
If you're not using ``Validator`` from ConfigObj, then you'll need to call the  | 
|
307  | 
``check`` method yourself.  | 
|
308  | 
||
309  | 
If the check fails then it will raise an exception, so you'll want to trap  | 
|
310  | 
that. Here's the basic example :  | 
|
311  | 
||
312  | 
.. raw:: html  | 
|
313  | 
||
314  | 
    {+coloring}
 | 
|
315  | 
||
316  | 
from validate import Validator, ValidateError  | 
|
317  | 
#  | 
|
318  | 
vtor = Validator()  | 
|
319  | 
check = "integer(0, 9)"  | 
|
320  | 
value = 3  | 
|
321  | 
try:  | 
|
322  | 
newvalue = vtor.check(check, value)  | 
|
323  | 
except ValidateError:  | 
|
324  | 
print 'Check Failed.'  | 
|
325  | 
else:  | 
|
326  | 
print 'Check passed.'  | 
|
327  | 
||
328  | 
    {-coloring}
 | 
|
329  | 
||
330  | 
.. caution::  | 
|
331  | 
||
332  | 
Although the value can be a string, if it represents a list it should  | 
|
333  | 
already have been turned into a list of strings.  | 
|
334  | 
||
335  | 
Default Values  | 
|
336  | 
~~~~~~~~~~~~~~  | 
|
337  | 
||
338  | 
Some values may not be available, and you may want to be able to specify a  | 
|
339  | 
default as part of the check.  | 
|
340  | 
||
341  | 
You do this by passing the keyword ``missing=True`` to the ``check`` method, as  | 
|
342  | 
well as a ``default=value`` in the check. (Constructing these checks is done  | 
|
343  | 
automatically by ConfigObj: you only need to know about the ``default=value``  | 
|
344  | 
part) :  | 
|
345  | 
||
346  | 
.. raw:: html  | 
|
347  | 
||
348  | 
    {+coloring}
 | 
|
349  | 
||
350  | 
check1 = 'integer(default=50)'  | 
|
351  | 
    check2 = 'option("val 1", "val 2", "val 3", default="val 1")'
 | 
|
352  | 
||
353  | 
    assert vtor.check('', check1, missing=True) == 50
 | 
|
354  | 
    assert vtor.check('', check2, missing=True) == "val 1"
 | 
|
355  | 
||
356  | 
    {-coloring}
 | 
|
357  | 
||
358  | 
If you pass in ``missing=True`` to the check method, then the actual value is  | 
|
359  | 
ignored. If no default is specified in the check, a ``ValidateMissingValue``  | 
|
360  | 
exception is raised. If a default is specified then that is passed to the  | 
|
361  | 
check instead.  | 
|
362  | 
||
363  | 
If the check has ``default=None`` (case sensitive) then ``vtor.check`` will  | 
|
364  | 
*always* return ``None`` (the object). This makes it easy to tell your program  | 
|
365  | 
that this check contains no useful value when missing, i.e. the value is  | 
|
366  | 
optional, and may be omitted without harm.  | 
|
367  | 
||
368  | 
Validator Exceptions  | 
|
369  | 
====================  | 
|
370  | 
||
371  | 
.. note::  | 
|
372  | 
||
373  | 
If you only use Validator through ConfigObj, it traps these Exceptions for  | 
|
374  | 
you. You will still need to know about them for writing your own check  | 
|
375  | 
functions.  | 
|
376  | 
||
377  | 
``vtor.check`` indicates that the check has failed by raising an exception.  | 
|
378  | 
The appropriate error should be raised in the check function.  | 
|
379  | 
||
380  | 
The base error class is ``ValidateError``. All errors (except for ``VdtParamError``)  | 
|
381  | 
raised are sub-classes of this.  | 
|
382  | 
||
383  | 
If an unrecognised check is specified then ``VdtUnknownCheckError`` is  | 
|
384  | 
raised.  | 
|
385  | 
||
386  | 
There are also ``VdtTypeError`` and ``VdtValueError``.  | 
|
387  | 
||
388  | 
If incorrect parameters are passed to a check function then it will (or should)  | 
|
389  | 
raise ``VdtParamError``. As this indicates *programmer* error, rather than an error  | 
|
390  | 
in the value, it is a subclass of ``SyntaxError`` instead of ``ValidateError``.  | 
|
391  | 
||
392  | 
.. note::  | 
|
393  | 
||
394  | 
This means it *won't* be caught by ConfigObj - but propagated instead.  | 
|
395  | 
||
396  | 
If the value supplied is the wrong type, then the check should raise  | 
|
397  | 
``VdtTypeError``. e.g. the check requires the value to be an integer (or  | 
|
398  | 
representation of an integer) and something else was supplied.  | 
|
399  | 
||
400  | 
If the value supplied is the right type, but an unacceptable value, then the  | 
|
401  | 
check should raise ``VdtValueError``. e.g. the check requires the value to  | 
|
402  | 
be an integer (or representation of an integer) less than ten and a higher  | 
|
403  | 
value was supplied.  | 
|
404  | 
||
405  | 
Both ``VdtTypeError`` and ``VdtValueError`` are initialised with the  | 
|
406  | 
incorrect value. In other words you raise them like this :  | 
|
407  | 
||
408  | 
.. raw:: html  | 
|
409  | 
||
410  | 
    {+coloring}
 | 
|
411  | 
||
412  | 
raise VdtTypeError(value)  | 
|
413  | 
#  | 
|
414  | 
raise VdtValueError(value)  | 
|
415  | 
||
416  | 
    {-coloring}
 | 
|
417  | 
||
418  | 
``VdtValueError`` has the following subclasses, which should be raised if  | 
|
419  | 
they are more appropriate.  | 
|
420  | 
||
421  | 
* ``VdtValueTooSmallError``  | 
|
422  | 
* ``VdtValueTooBigError``  | 
|
423  | 
* ``VdtValueTooShortError``  | 
|
424  | 
* ``VdtValueTooLongError``  | 
|
425  | 
||
426  | 
Writing check functions  | 
|
427  | 
=======================  | 
|
428  | 
||
429  | 
Writing check functions is easy.  | 
|
430  | 
||
431  | 
The check function will receive the value as its first argument, followed by  | 
|
432  | 
any other parameters and keyword arguments.  | 
|
433  | 
||
434  | 
If the check fails, it should raise a ``VdtTypeError`` or a  | 
|
435  | 
``VdtValueError`` (or an appropriate subclass).  | 
|
436  | 
||
437  | 
All parameters and keyword arguments are *always* passed as strings. (Parsed  | 
|
438  | 
from the check string).  | 
|
439  | 
||
440  | 
The value might be a string (or list of strings) and need  | 
|
441  | 
converting to the right type - alternatively it might already be a list of  | 
|
442  | 
integers. Our function needs to be able to handle either.  | 
|
443  | 
||
444  | 
If the check passes then it should return the value (possibly converted to the  | 
|
445  | 
right type).  | 
|
446  | 
||
447  | 
And that's it !  | 
|
448  | 
||
449  | 
Example  | 
|
450  | 
-------  | 
|
451  | 
||
452  | 
Here is an example function that requires a list of integers. Each integer  | 
|
453  | 
must be between 0 and 99.  | 
|
454  | 
||
455  | 
It takes a single argument specifying the length of the list. (Which allows us  | 
|
456  | 
to use the same check in more than one place). If the length can't be converted  | 
|
457  | 
to an integer then we need to raise ``VdtParamError``.  | 
|
458  | 
||
459  | 
Next we check that the value is a list. Anything else should raise a  | 
|
460  | 
``VdtTypeError``. The list should also have 'length' entries. If the list  | 
|
461  | 
has more or less entries then we will need to raise a  | 
|
462  | 
``VdtValueTooShortError`` or a ``VdtValueTooLongError``.  | 
|
463  | 
||
464  | 
Then we need to check every entry in the list. Each entry should be an integer  | 
|
465  | 
between 0 and 99, or a string representation of an integer between 0 and 99.  | 
|
466  | 
Any other type is a ``VdtTypeError``, any other value is a  | 
|
467  | 
``VdtValueError`` (either too big, or too small).  | 
|
468  | 
||
469  | 
.. raw:: html  | 
|
470  | 
||
471  | 
    {+coloring}
 | 
|
472  | 
||
473  | 
def special_list(value, length):  | 
|
474  | 
"""  | 
|
475  | 
Check that the supplied value is a list of integers,  | 
|
476  | 
with 'length' entries, and each entry between 0 and 99.  | 
|
477  | 
"""  | 
|
478  | 
# length is supplied as a string  | 
|
479  | 
# we need to convert it to an integer  | 
|
480  | 
try:  | 
|
481  | 
length = int(length)  | 
|
482  | 
except ValueError:  | 
|
483  | 
            raise VdtParamError('length', length)
 | 
|
484  | 
#  | 
|
485  | 
# Check the supplied value is a list  | 
|
486  | 
if not isinstance(value, list):  | 
|
487  | 
raise VdtTypeError(value)  | 
|
488  | 
#  | 
|
489  | 
# check the length of the list is correct  | 
|
490  | 
if len(value) > length:  | 
|
491  | 
raise VdtValueTooLongError(value)  | 
|
492  | 
elif len(value) < length:  | 
|
493  | 
raise VdtValueTooShortError(value)  | 
|
494  | 
#  | 
|
495  | 
# Next, check every member in the list  | 
|
496  | 
# converting strings as necessary  | 
|
497  | 
out = []  | 
|
498  | 
for entry in value:  | 
|
499  | 
if not isinstance(entry, (str, unicode, int)):  | 
|
500  | 
# a value in the list  | 
|
501  | 
# is neither an integer nor a string  | 
|
502  | 
raise VdtTypeError(value)  | 
|
503  | 
elif isinstance(entry, (str, unicode)):  | 
|
504  | 
if not entry.isdigit():  | 
|
505  | 
raise VdtTypeError(value)  | 
|
506  | 
else:  | 
|
507  | 
entry = int(entry)  | 
|
508  | 
if entry < 0:  | 
|
509  | 
raise VdtValueTooSmallError(value)  | 
|
510  | 
elif entry > 99:  | 
|
511  | 
raise VdtValueTooBigError(value)  | 
|
512  | 
out.append(entry)  | 
|
513  | 
#  | 
|
514  | 
# if we got this far, all is well  | 
|
515  | 
# return the new list  | 
|
516  | 
return out  | 
|
517  | 
||
518  | 
    {-coloring}
 | 
|
519  | 
||
520  | 
If you are only using validate from ConfigObj then the error type (*TooBig*,  | 
|
521  | 
*TooSmall*, etc) is lost - so you may only want to raise ``VdtValueError``.  | 
|
522  | 
||
523  | 
.. caution::  | 
|
524  | 
||
525  | 
If your function raises an exception that isn't a subclass of  | 
|
526  | 
``ValidateError``, then ConfigObj won't trap it. This means validation will  | 
|
527  | 
fail.  | 
|
528  | 
||
529  | 
This is why our function starts by checking the type of the value. If we  | 
|
530  | 
are passed the wrong type (e.g. an integer rather than a list) we get a  | 
|
531  | 
``VdtTypeError`` rather than bombing out when we try to iterate over  | 
|
532  | 
the value.  | 
|
533  | 
||
534  | 
If you are using validate in another circumstance you may want to create your  | 
|
535  | 
own subclasses of ``ValidateError``, that convey more specific information.  | 
|
536  | 
||
537  | 
TODO  | 
|
538  | 
====  | 
|
539  | 
||
540  | 
* A regex check function ?  | 
|
541  | 
* A timestamp check function ? (Using the ``parse`` function from ``DateUtil``).  | 
|
542  | 
* Allow triple quotes ? (getting a bit heavy for a single regex)  | 
|
543  | 
||
544  | 
ISSUES  | 
|
545  | 
======  | 
|
546  | 
||
547  | 
.. note::  | 
|
548  | 
||
549  | 
Please file any bug reports to `Michael Foord`_ or the ConfigObj  | 
|
550  | 
`Mailing List`_.  | 
|
551  | 
||
552  | 
Lists passed as function arguments need additional quotes. Ugly, could do  | 
|
553  | 
with fixing this.  | 
|
554  | 
||
555  | 
If we could pull tuples out of arguments, it would be easier  | 
|
556  | 
to specify arguments for 'mixed_lists'.  | 
|
557  | 
||
558  | 
CHANGELOG  | 
|
559  | 
=========  | 
|
560  | 
||
561  | 
||
562  | 
2005/08/18 Version 0.2.0  | 
|
563  | 
-----------------------------  | 
|
564  | 
||
565  | 
Updated by `Michael Foord`_ and `Nicola Larosa`_  | 
|
566  | 
||
567  | 
Does type conversion as well.  | 
|
568  | 
||
569  | 
2005/02/01 Version 0.1.0  | 
|
570  | 
-----------------------------  | 
|
571  | 
||
572  | 
Initial version developed by `Michael Foord`_  | 
|
573  | 
and `Mark Andrews`_  | 
|
574  | 
||
575  | 
.. note::  | 
|
576  | 
||
577  | 
Rendering this document with docutils also needs the  | 
|
578  | 
textmacros module and the PySrc CSS stuff. See  | 
|
579  | 
http://www.voidspace.org.uk/python/firedrop2/textmacros.shtml  | 
|
580  | 
||
581  | 
.. raw:: html  | 
|
582  | 
||
583  | 
<div align="center">  | 
|
584  | 
<a href="http://www.python.org">  | 
|
585  | 
<img src="images/powered_by_python.jpg" width="602" height="186" border="0" />  | 
|
586  | 
</a>  | 
|
587  | 
<a href="http://www.opensource.org">  | 
|
588  | 
<img src="images/osi-certified-120x100.gif" width="120" height="100" border="0" />  | 
|
589  | 
<br /><strong>Certified Open Source</strong>  | 
|
590  | 
</a>  | 
|
591  | 
<br /><br />  | 
|
592  | 
<script type="text/javascript" language="JavaScript">var site="s16atlantibots"</script>  | 
|
593  | 
<script type="text/javascript" language="JavaScript1.2" src="http://s16.sitemeter.com/js/counter.js?site=s16atlantibots"></script>  | 
|
594  | 
<noscript>  | 
|
595  | 
<a href="http://s16.sitemeter.com/stats.asp?site=s16atlantibots">  | 
|
596  | 
<img src="http://s16.sitemeter.com/meter.asp?site=s16atlantibots" alt="Site Meter" border=0 />  | 
|
597  | 
</a>  | 
|
598  | 
</noscript>  | 
|
599  | 
</div>  |