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`_ |
|
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
11 |
:Version: Validate 0.2.1 |
12 |
:Date: 2005/12/16 |
|
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
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 |
|
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
23 |
.. _BSD License: http://www.voidspace.org.uk/python/license.shtml |
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
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 |
||
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
59 |
Validate was primarily written to support ConfigObj_, but is designed to be |
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
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 |
||
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
69 |
The current version is **0.2.1**, dated 16th December 2005. |
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
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 |
|
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
79 |
version and download links. |
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
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 |
|
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
104 |
.. _configobj.zip: http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=configobj-4.1.0.zip |
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
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() |
|
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
206 |
newval1 = vtor.check('integer', value1) |
207 |
newval2 = vtor.check('bool', value2) |
|
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
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 |
||
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
218 |
|
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
219 |
Using Validator |
220 |
=============== |
|
221 |
||
222 |
Using ``Validator`` is very easy. It has one public attribute and one public |
|
223 |
method. |
|
224 |
||
225 |
Shown below are the different steps in using ``Validator``. |
|
226 |
||
227 |
The only additional thing you need to know, is about `Writing check |
|
228 |
functions`_. |
|
229 |
||
230 |
Instantiate |
|
231 |
----------- |
|
232 |
||
233 |
.. raw:: html |
|
234 |
||
235 |
{+coloring} |
|
236 |
||
237 |
from validate import Validator |
|
238 |
vtor = Validator() |
|
239 |
||
240 |
{-coloring} |
|
241 |
||
242 |
or even : |
|
243 |
||
244 |
.. raw:: html |
|
245 |
||
246 |
{+coloring} |
|
247 |
||
248 |
from validate import Validator |
|
249 |
# |
|
250 |
fdict = { |
|
251 |
'check_name1': function1, |
|
252 |
'check_name2': function2, |
|
253 |
'check_name3': function3, |
|
254 |
} |
|
255 |
# |
|
256 |
vtor = Validator(fdict) |
|
257 |
||
258 |
{-coloring} |
|
259 |
||
260 |
The second method adds a set of your functions as soon as your validator is |
|
261 |
created. They are stored in the ``vtor.functions`` dictionary. The 'key' you |
|
262 |
give them in this dictionary is the name you use in your checks (not the |
|
263 |
original function name). |
|
264 |
||
265 |
Dictionary keys/functions you pass in can override the built-in ones if you |
|
266 |
want. |
|
267 |
||
268 |
Adding functions |
|
269 |
---------------- |
|
270 |
||
271 |
The code shown above, for adding functions on instantiation, has exactly the |
|
272 |
same effect as the following code : |
|
273 |
||
274 |
.. raw:: html |
|
275 |
||
276 |
{+coloring} |
|
277 |
||
278 |
from validate import Validator |
|
279 |
# |
|
280 |
vtor = Validator() |
|
281 |
vtor.functions['check_name1'] = function1 |
|
282 |
vtor.functions['check_name2'] = function2 |
|
283 |
vtor.functions['check_name3'] = function3 |
|
284 |
||
285 |
{-coloring} |
|
286 |
||
287 |
``vtor.functions``is just a dictionary that maps names to functions, so we |
|
288 |
could also have called ``vtor.functions.update(fdict)``. |
|
289 |
||
290 |
Writing the check |
|
291 |
----------------- |
|
292 |
||
293 |
As we've heard, the checks map to the names in the ``functions`` dictionary. |
|
294 |
You've got a full list of `The standard functions`_ and the arguments they |
|
295 |
take. |
|
296 |
||
297 |
If you're using ``Validator`` from ConfigObj, then your checks will look like |
|
298 |
: :: |
|
299 |
||
300 |
keyword = int_list(max=6) |
|
301 |
||
302 |
but the check part will be identical . |
|
303 |
||
304 |
The check method |
|
305 |
---------------- |
|
306 |
||
307 |
If you're not using ``Validator`` from ConfigObj, then you'll need to call the |
|
308 |
``check`` method yourself. |
|
309 |
||
310 |
If the check fails then it will raise an exception, so you'll want to trap |
|
311 |
that. Here's the basic example : |
|
312 |
||
313 |
.. raw:: html |
|
314 |
||
315 |
{+coloring} |
|
316 |
||
317 |
from validate import Validator, ValidateError |
|
318 |
# |
|
319 |
vtor = Validator() |
|
320 |
check = "integer(0, 9)" |
|
321 |
value = 3 |
|
322 |
try: |
|
323 |
newvalue = vtor.check(check, value) |
|
324 |
except ValidateError: |
|
325 |
print 'Check Failed.' |
|
326 |
else: |
|
327 |
print 'Check passed.' |
|
328 |
||
329 |
{-coloring} |
|
330 |
||
331 |
.. caution:: |
|
332 |
||
333 |
Although the value can be a string, if it represents a list it should |
|
334 |
already have been turned into a list of strings. |
|
335 |
||
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
336 |
|
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
337 |
Default Values |
338 |
~~~~~~~~~~~~~~ |
|
339 |
||
340 |
Some values may not be available, and you may want to be able to specify a |
|
341 |
default as part of the check. |
|
342 |
||
343 |
You do this by passing the keyword ``missing=True`` to the ``check`` method, as |
|
344 |
well as a ``default=value`` in the check. (Constructing these checks is done |
|
345 |
automatically by ConfigObj: you only need to know about the ``default=value`` |
|
346 |
part) : |
|
347 |
||
348 |
.. raw:: html |
|
349 |
||
350 |
{+coloring} |
|
351 |
||
352 |
check1 = 'integer(default=50)' |
|
353 |
check2 = 'option("val 1", "val 2", "val 3", default="val 1")' |
|
354 |
||
355 |
assert vtor.check('', check1, missing=True) == 50 |
|
356 |
assert vtor.check('', check2, missing=True) == "val 1" |
|
357 |
||
358 |
{-coloring} |
|
359 |
||
360 |
If you pass in ``missing=True`` to the check method, then the actual value is |
|
361 |
ignored. If no default is specified in the check, a ``ValidateMissingValue`` |
|
362 |
exception is raised. If a default is specified then that is passed to the |
|
363 |
check instead. |
|
364 |
||
365 |
If the check has ``default=None`` (case sensitive) then ``vtor.check`` will |
|
366 |
*always* return ``None`` (the object). This makes it easy to tell your program |
|
367 |
that this check contains no useful value when missing, i.e. the value is |
|
368 |
optional, and may be omitted without harm. |
|
369 |
||
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
370 |
|
371 |
List Values |
|
372 |
~~~~~~~~~~~ |
|
373 |
||
374 |
It's possible that you would like your default value to be a list. It's even |
|
375 |
possible that you will write your own check functions - and would like to pass |
|
376 |
them keyword arguments as lists from within the check. |
|
377 |
||
378 |
To avoid confusing syntax with commas and quotes you use a list constructor to |
|
379 |
specify that keyword arguments are lists. This includes the ``default`` value. |
|
380 |
This makes checks look something like : :: |
|
381 |
||
382 |
checkname(default=list('val1', 'val2', 'val3')) |
|
383 |
||
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
384 |
Validator Exceptions |
385 |
==================== |
|
386 |
||
387 |
.. note:: |
|
388 |
||
389 |
If you only use Validator through ConfigObj, it traps these Exceptions for |
|
390 |
you. You will still need to know about them for writing your own check |
|
391 |
functions. |
|
392 |
||
393 |
``vtor.check`` indicates that the check has failed by raising an exception. |
|
394 |
The appropriate error should be raised in the check function. |
|
395 |
||
396 |
The base error class is ``ValidateError``. All errors (except for ``VdtParamError``) |
|
397 |
raised are sub-classes of this. |
|
398 |
||
399 |
If an unrecognised check is specified then ``VdtUnknownCheckError`` is |
|
400 |
raised. |
|
401 |
||
402 |
There are also ``VdtTypeError`` and ``VdtValueError``. |
|
403 |
||
404 |
If incorrect parameters are passed to a check function then it will (or should) |
|
405 |
raise ``VdtParamError``. As this indicates *programmer* error, rather than an error |
|
406 |
in the value, it is a subclass of ``SyntaxError`` instead of ``ValidateError``. |
|
407 |
||
408 |
.. note:: |
|
409 |
||
410 |
This means it *won't* be caught by ConfigObj - but propagated instead. |
|
411 |
||
412 |
If the value supplied is the wrong type, then the check should raise |
|
413 |
``VdtTypeError``. e.g. the check requires the value to be an integer (or |
|
414 |
representation of an integer) and something else was supplied. |
|
415 |
||
416 |
If the value supplied is the right type, but an unacceptable value, then the |
|
417 |
check should raise ``VdtValueError``. e.g. the check requires the value to |
|
418 |
be an integer (or representation of an integer) less than ten and a higher |
|
419 |
value was supplied. |
|
420 |
||
421 |
Both ``VdtTypeError`` and ``VdtValueError`` are initialised with the |
|
422 |
incorrect value. In other words you raise them like this : |
|
423 |
||
424 |
.. raw:: html |
|
425 |
||
426 |
{+coloring} |
|
427 |
||
428 |
raise VdtTypeError(value) |
|
429 |
# |
|
430 |
raise VdtValueError(value) |
|
431 |
||
432 |
{-coloring} |
|
433 |
||
434 |
``VdtValueError`` has the following subclasses, which should be raised if |
|
435 |
they are more appropriate. |
|
436 |
||
437 |
* ``VdtValueTooSmallError`` |
|
438 |
* ``VdtValueTooBigError`` |
|
439 |
* ``VdtValueTooShortError`` |
|
440 |
* ``VdtValueTooLongError`` |
|
441 |
||
442 |
Writing check functions |
|
443 |
======================= |
|
444 |
||
445 |
Writing check functions is easy. |
|
446 |
||
447 |
The check function will receive the value as its first argument, followed by |
|
448 |
any other parameters and keyword arguments. |
|
449 |
||
450 |
If the check fails, it should raise a ``VdtTypeError`` or a |
|
451 |
``VdtValueError`` (or an appropriate subclass). |
|
452 |
||
453 |
All parameters and keyword arguments are *always* passed as strings. (Parsed |
|
454 |
from the check string). |
|
455 |
||
456 |
The value might be a string (or list of strings) and need |
|
457 |
converting to the right type - alternatively it might already be a list of |
|
458 |
integers. Our function needs to be able to handle either. |
|
459 |
||
460 |
If the check passes then it should return the value (possibly converted to the |
|
461 |
right type). |
|
462 |
||
463 |
And that's it ! |
|
464 |
||
465 |
Example |
|
466 |
------- |
|
467 |
||
468 |
Here is an example function that requires a list of integers. Each integer |
|
469 |
must be between 0 and 99. |
|
470 |
||
471 |
It takes a single argument specifying the length of the list. (Which allows us |
|
472 |
to use the same check in more than one place). If the length can't be converted |
|
473 |
to an integer then we need to raise ``VdtParamError``. |
|
474 |
||
475 |
Next we check that the value is a list. Anything else should raise a |
|
476 |
``VdtTypeError``. The list should also have 'length' entries. If the list |
|
477 |
has more or less entries then we will need to raise a |
|
478 |
``VdtValueTooShortError`` or a ``VdtValueTooLongError``. |
|
479 |
||
480 |
Then we need to check every entry in the list. Each entry should be an integer |
|
481 |
between 0 and 99, or a string representation of an integer between 0 and 99. |
|
482 |
Any other type is a ``VdtTypeError``, any other value is a |
|
483 |
``VdtValueError`` (either too big, or too small). |
|
484 |
||
485 |
.. raw:: html |
|
486 |
||
487 |
{+coloring} |
|
488 |
||
489 |
def special_list(value, length): |
|
490 |
""" |
|
491 |
Check that the supplied value is a list of integers, |
|
492 |
with 'length' entries, and each entry between 0 and 99. |
|
493 |
""" |
|
494 |
# length is supplied as a string |
|
495 |
# we need to convert it to an integer |
|
496 |
try: |
|
497 |
length = int(length) |
|
498 |
except ValueError: |
|
499 |
raise VdtParamError('length', length) |
|
500 |
# |
|
501 |
# Check the supplied value is a list |
|
502 |
if not isinstance(value, list): |
|
503 |
raise VdtTypeError(value) |
|
504 |
# |
|
505 |
# check the length of the list is correct |
|
506 |
if len(value) > length: |
|
507 |
raise VdtValueTooLongError(value) |
|
508 |
elif len(value) < length: |
|
509 |
raise VdtValueTooShortError(value) |
|
510 |
# |
|
511 |
# Next, check every member in the list |
|
512 |
# converting strings as necessary |
|
513 |
out = [] |
|
514 |
for entry in value: |
|
515 |
if not isinstance(entry, (str, unicode, int)): |
|
516 |
# a value in the list |
|
517 |
# is neither an integer nor a string |
|
518 |
raise VdtTypeError(value) |
|
519 |
elif isinstance(entry, (str, unicode)): |
|
520 |
if not entry.isdigit(): |
|
521 |
raise VdtTypeError(value) |
|
522 |
else: |
|
523 |
entry = int(entry) |
|
524 |
if entry < 0: |
|
525 |
raise VdtValueTooSmallError(value) |
|
526 |
elif entry > 99: |
|
527 |
raise VdtValueTooBigError(value) |
|
528 |
out.append(entry) |
|
529 |
# |
|
530 |
# if we got this far, all is well |
|
531 |
# return the new list |
|
532 |
return out |
|
533 |
||
534 |
{-coloring} |
|
535 |
||
536 |
If you are only using validate from ConfigObj then the error type (*TooBig*, |
|
537 |
*TooSmall*, etc) is lost - so you may only want to raise ``VdtValueError``. |
|
538 |
||
539 |
.. caution:: |
|
540 |
||
541 |
If your function raises an exception that isn't a subclass of |
|
542 |
``ValidateError``, then ConfigObj won't trap it. This means validation will |
|
543 |
fail. |
|
544 |
||
545 |
This is why our function starts by checking the type of the value. If we |
|
546 |
are passed the wrong type (e.g. an integer rather than a list) we get a |
|
547 |
``VdtTypeError`` rather than bombing out when we try to iterate over |
|
548 |
the value. |
|
549 |
||
550 |
If you are using validate in another circumstance you may want to create your |
|
551 |
own subclasses of ``ValidateError``, that convey more specific information. |
|
552 |
||
553 |
TODO |
|
554 |
==== |
|
555 |
||
556 |
* A regex check function ? |
|
557 |
* A timestamp check function ? (Using the ``parse`` function from ``DateUtil``). |
|
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
558 |
* Allow triple quotes ? (getting a bit heavy for a regex) |
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
559 |
|
560 |
ISSUES |
|
561 |
====== |
|
562 |
||
563 |
.. note:: |
|
564 |
||
565 |
Please file any bug reports to `Michael Foord`_ or the ConfigObj |
|
566 |
`Mailing List`_. |
|
567 |
||
568 |
If we could pull tuples out of arguments, it would be easier |
|
569 |
to specify arguments for 'mixed_lists'. |
|
570 |
||
571 |
CHANGELOG |
|
572 |
========= |
|
573 |
||
1556.2.1
by Aaron Bentley
Switched to ConfigObj 4.2.0 |
574 |
2005/12/16 Version 0.2.1 |
575 |
----------------------------- |
|
576 |
||
577 |
Fixed bug so we can handle keyword argument values with commas. |
|
578 |
||
579 |
We now use a list constructor for passing list values to keyword arguments |
|
580 |
(including ``default``) : :: |
|
581 |
||
582 |
default=list("val", "val", "val") |
|
583 |
||
584 |
Added the ``_test`` test. {sm;:-)} |
|
585 |
||
586 |
Moved a function call outside a try...except block. |
|
1185.12.49
by Aaron Bentley
Switched to ConfigObj |
587 |
|
588 |
2005/08/18 Version 0.2.0 |
|
589 |
----------------------------- |
|
590 |
||
591 |
Updated by `Michael Foord`_ and `Nicola Larosa`_ |
|
592 |
||
593 |
Does type conversion as well. |
|
594 |
||
595 |
2005/02/01 Version 0.1.0 |
|
596 |
----------------------------- |
|
597 |
||
598 |
Initial version developed by `Michael Foord`_ |
|
599 |
and `Mark Andrews`_ |
|
600 |
||
601 |
.. note:: |
|
602 |
||
603 |
Rendering this document with docutils also needs the |
|
604 |
textmacros module and the PySrc CSS stuff. See |
|
605 |
http://www.voidspace.org.uk/python/firedrop2/textmacros.shtml |
|
606 |
||
607 |
.. raw:: html |
|
608 |
||
609 |
<div align="center"> |
|
610 |
<a href="http://www.python.org"> |
|
611 |
<img src="images/powered_by_python.jpg" width="602" height="186" border="0" /> |
|
612 |
</a> |
|
613 |
<a href="http://www.opensource.org"> |
|
614 |
<img src="images/osi-certified-120x100.gif" width="120" height="100" border="0" /> |
|
615 |
<br /><strong>Certified Open Source</strong> |
|
616 |
</a> |
|
617 |
<br /><br /> |
|
618 |
<script type="text/javascript" language="JavaScript">var site="s16atlantibots"</script> |
|
619 |
<script type="text/javascript" language="JavaScript1.2" src="http://s16.sitemeter.com/js/counter.js?site=s16atlantibots"></script> |
|
620 |
<noscript> |
|
621 |
<a href="http://s16.sitemeter.com/stats.asp?site=s16atlantibots"> |
|
622 |
<img src="http://s16.sitemeter.com/meter.asp?site=s16atlantibots" alt="Site Meter" border=0 /> |
|
623 |
</a> |
|
624 |
</noscript> |
|
625 |
</div> |