112
112
You specify this check with : ::
114
114
option('option 1', 'option 2', 'option 3')
116
You can supply a default value (returned if no value is supplied)
117
using the default keyword argument.
119
You specify a list argument for default using a list constructor syntax in
122
checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3'))
124
A badly formatted set of arguments will raise a ``VdtParamError``.
127
117
__docformat__ = "restructuredtext en"
129
__version__ = '0.2.1'
119
__version__ = '0.2.0'
131
121
__revision__ = '$Id: validate.py 123 2005-09-08 08:54:28Z fuzzyman $'
170
160
StringTypes = (str, unicode)
173
_list_arg = re.compile(r'''
175
([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*list\(
180
(?:".*?")| # double quotes
181
(?:'.*?')| # single quotes
182
(?:[^'",\s\)][^,\)]*?) # unquoted
187
(?:".*?")| # double quotes
188
(?:'.*?')| # single quotes
189
(?:[^'",\s\)][^,\)]*?) # unquoted
194
''', re.VERBOSE) # two groups
196
_list_members = re.compile(r'''
198
(?:".*?")| # double quotes
199
(?:'.*?')| # single quotes
200
(?:[^'",\s=][^,=]*?) # unquoted
203
(?:\s*,\s*)|(?:\s*$) # comma
205
''', re.VERBOSE) # one group
211
[a-zA-Z_][a-zA-Z0-9_]*\s*=\s*list\(
215
(?:".*?")| # double quotes
216
(?:'.*?')| # single quotes
217
(?:[^'",\s\)][^,\)]*?) # unquoted
222
(?:".*?")| # double quotes
223
(?:'.*?')| # single quotes
224
(?:[^'",\s\)][^,\)]*?) # unquoted
229
(?:".*?")| # double quotes
230
(?:'.*?')| # single quotes
231
(?:[^'",\s=][^,=]*?)| # unquoted
232
(?: # keyword argument
233
[a-zA-Z_][a-zA-Z0-9_]*\s*=\s*
235
(?:".*?")| # double quotes
236
(?:'.*?')| # single quotes
237
(?:[^'",\s=][^,=]*?) # unquoted
243
(?:\s*,\s*)|(?:\s*$) # comma
248
_matchstring = '^%s*' % _paramstring
250
162
# Python pre 2.2.1 doesn't have bool
521
433
http://www.voidspace.org.uk/python/configobj.html
436
# this regex pulls values out of a comma separated line
437
_paramfinder = re.compile(r'''(?:'.*?')|(?:".*?")|(?:[^'",\s][^,]*)''')
438
# this regex is used for finding keyword arguments
439
_key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$')
524
440
# this regex does the initial parsing of the checks
525
441
_func_re = re.compile(r'(.+?)\((.*)\)')
527
# this regex takes apart keyword arguments
528
_key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$')
531
# this regex finds keyword=list(....) type values
532
_list_arg = _list_arg
534
# this regex takes individual values out of lists - in one pass
535
_list_members = _list_members
537
# These regexes check a set of arguments for validity
538
# and then pull the members out
539
_paramfinder = re.compile(_paramstring, re.VERBOSE)
540
_matchfinder = re.compile(_matchstring, re.VERBOSE)
543
443
def __init__(self, functions=None):
545
445
>>> vtri = Validator()
587
487
fun_match = self._func_re.match(check)
589
489
fun_name = fun_match.group(1)
590
arg_string = fun_match.group(2)
591
arg_match = self._matchfinder.match(arg_string)
592
if arg_match is None:
597
492
# pull out args of group 2
598
for arg in self._paramfinder.findall(arg_string):
493
for arg in self._paramfinder.findall(fun_match.group(2)):
599
494
# args may need whitespace removing (before removing quotes)
600
495
arg = arg.strip()
601
listmatch = self._list_arg.match(arg)
603
key, val = self._list_handle(listmatch)
604
fun_kwargs[key] = val
606
496
keymatch = self._key_arg.match(arg)
608
val = self._unquote(keymatch.group(2))
498
val = keymatch.group(2)
499
if (val[0] in ("'", '"')) and (val[0] == val[-1]):
609
501
fun_kwargs[keymatch.group(1)] = val
612
fun_args.append(self._unquote(arg))
504
if (arg[0] in ("'", '"')) and (arg[0] == arg[-1]):
614
508
# allows for function names without (args)
615
509
(fun_name, fun_args, fun_kwargs) = (check, (), {})
633
fun = self.functions[fun_name]
527
return self.functions[fun_name](value, *fun_args, **fun_kwargs)
635
529
raise VdtUnknownCheckError(fun_name)
639
return fun(value, *fun_args, **fun_kwargs)
641
def _unquote(self, val):
642
"""Unquote a value if necessary."""
643
if (len(val) > 2) and (val[0] in ("'", '"')) and (val[0] == val[-1]):
647
def _list_handle(self, listmatch):
648
"""Take apart a ``keyword=list('val, 'val')`` type string."""
650
name = listmatch.group(1)
651
args = listmatch.group(2)
652
for arg in self._list_members.findall(args):
653
out.append(self._unquote(arg))
656
531
def _pass(self, value):
1184
1059
raise VdtValueError(value)
1187
def _test(value, *args, **keywargs):
1189
A function that exists for test purposes.
1192
... '3, 6, min=1, max=3, test=list(a, b, c)',
1196
... 'min=1, test="a b c"',
1197
... 'min=5, test="a, b, c"',
1198
... 'min=1, max=3, test="a, b, c"',
1199
... 'min=-100, test=-99',
1201
... '3, 6, test="36"',
1202
... '3, 6, test="a, b, c"',
1203
... '3, max=3, test=list("a", "b", "c")',
1204
... '''3, max=3, test=list("'a'", 'b', "x=(c)")''',
1205
... "test='x=fish(3)'",
1207
>>> v = Validator({'test': _test})
1208
>>> for entry in checks:
1209
... print v.check(('test(%s)' % entry), 3)
1210
(3, ('3', '6'), {'test': ['a', 'b', 'c'], 'max': '3', 'min': '1'})
1214
(3, (), {'test': 'a b c', 'min': '1'})
1215
(3, (), {'test': 'a, b, c', 'min': '5'})
1216
(3, (), {'test': 'a, b, c', 'max': '3', 'min': '1'})
1217
(3, (), {'test': '-99', 'min': '-100'})
1218
(3, (), {'max': '3', 'min': '1'})
1219
(3, ('3', '6'), {'test': '36'})
1220
(3, ('3', '6'), {'test': 'a, b, c'})
1221
(3, ('3',), {'test': ['a', 'b', 'c'], 'max': '3'})
1222
(3, ('3',), {'test': ["'a'", 'b', 'x=(c)'], 'max': '3'})
1223
(3, (), {'test': 'x=fish(3)'})
1225
return (value, args, keywargs)
1228
1062
if __name__ == '__main__':
1229
1063
# run the code tests in doctest format
1084
Lists passed as function arguments need additional quotes. Ugly, could do
1250
1087
If we could pull tuples out of arguments, it would be easier
1251
1088
to specify arguments for 'mixed_lists'.
1259
Fixed bug so we can handle keyword argument values with commas.
1261
We now use a list constructor for passing list values to keyword arguments
1262
(including ``default``) : ::
1264
default=list("val", "val", "val")
1266
Added the ``_test`` test. {sm;:-)}
1273
Moved a function call outside a try...except block.