/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/util/configobj/validate.py

  • Committer: Robert Collins
  • Date: 2005-11-04 23:27:47 UTC
  • Revision ID: robertc@robertcollins.net-20051104232747-5872c68d759bc7be
Bugfix the config test suite to not create .bazaar in the dir where it is run.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
#         nico AT tekNico DOT net
7
7
 
8
8
# This software is licensed under the terms of the BSD license.
9
 
# http://www.voidspace.org.uk/python/license.shtml
 
9
# http://www.voidspace.org.uk/documents/BSD-LICENSE.txt
10
10
# Basically you're free to copy, modify, distribute and relicense it,
11
11
# So long as you keep a copy of the license with it.
12
12
 
112
112
                You specify this check with : ::
113
113
    
114
114
                  option('option 1', 'option 2', 'option 3')
115
 
    
116
 
    You can supply a default value (returned if no value is supplied)
117
 
    using the default keyword argument.
118
 
    
119
 
    You specify a list argument for default using a list constructor syntax in
120
 
    the check : ::
121
 
    
122
 
        checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3'))
123
 
    
124
 
    A badly formatted set of arguments will raise a ``VdtParamError``.
125
115
"""
126
116
 
127
117
__docformat__ = "restructuredtext en"
128
118
 
129
 
__version__ = '0.2.1'
 
119
__version__ = '0.2.0'
130
120
 
131
121
__revision__ = '$Id: validate.py 123 2005-09-08 08:54:28Z fuzzyman $'
132
122
 
169
159
import re
170
160
StringTypes = (str, unicode)
171
161
 
172
 
 
173
 
_list_arg = re.compile(r'''
174
 
    (?:
175
 
        ([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*list\(
176
 
            (
177
 
                (?:
178
 
                    \s*
179
 
                    (?:
180
 
                        (?:".*?")|              # double quotes
181
 
                        (?:'.*?')|              # single quotes
182
 
                        (?:[^'",\s\)][^,\)]*?)  # unquoted
183
 
                    )
184
 
                    \s*,\s*
185
 
                )*
186
 
                (?:
187
 
                    (?:".*?")|              # double quotes
188
 
                    (?:'.*?')|              # single quotes
189
 
                    (?:[^'",\s\)][^,\)]*?)  # unquoted
190
 
                )?                          # last one
191
 
            )
192
 
        \)
193
 
    )
194
 
''', re.VERBOSE)    # two groups
195
 
 
196
 
_list_members = re.compile(r'''
197
 
    (
198
 
        (?:".*?")|              # double quotes
199
 
        (?:'.*?')|              # single quotes
200
 
        (?:[^'",\s=][^,=]*?)       # unquoted
201
 
    )
202
 
    (?:
203
 
    (?:\s*,\s*)|(?:\s*$)            # comma
204
 
    )
205
 
''', re.VERBOSE)    # one group
206
 
 
207
 
_paramstring = r'''
208
 
    (?:
209
 
        (
210
 
            (?:
211
 
                [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*list\(
212
 
                    (?:
213
 
                        \s*
214
 
                        (?:
215
 
                            (?:".*?")|              # double quotes
216
 
                            (?:'.*?')|              # single quotes
217
 
                            (?:[^'",\s\)][^,\)]*?)       # unquoted
218
 
                        )
219
 
                        \s*,\s*
220
 
                    )*
221
 
                    (?:
222
 
                        (?:".*?")|              # double quotes
223
 
                        (?:'.*?')|              # single quotes
224
 
                        (?:[^'",\s\)][^,\)]*?)       # unquoted
225
 
                    )?                              # last one
226
 
                \)
227
 
            )|
228
 
            (?:
229
 
                (?:".*?")|              # double quotes
230
 
                (?:'.*?')|              # single quotes
231
 
                (?:[^'",\s=][^,=]*?)|       # unquoted
232
 
                (?:                         # keyword argument
233
 
                    [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*
234
 
                    (?:
235
 
                        (?:".*?")|              # double quotes
236
 
                        (?:'.*?')|              # single quotes
237
 
                        (?:[^'",\s=][^,=]*?)       # unquoted
238
 
                    )
239
 
                )
240
 
            )
241
 
        )
242
 
        (?:
243
 
            (?:\s*,\s*)|(?:\s*$)            # comma
244
 
        )
245
 
    )
246
 
    '''
247
 
 
248
 
_matchstring = '^%s*' % _paramstring
249
 
 
250
162
# Python pre 2.2.1 doesn't have bool
251
163
try:
252
164
    bool
521
433
        http://www.voidspace.org.uk/python/configobj.html
522
434
    """
523
435
 
 
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'(.+?)\((.*)\)')
526
442
 
527
 
    # this regex takes apart keyword arguments
528
 
    _key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$')
529
 
 
530
 
 
531
 
    # this regex finds keyword=list(....) type values
532
 
    _list_arg = _list_arg
533
 
 
534
 
    # this regex takes individual values out of lists - in one pass
535
 
    _list_members = _list_members
536
 
 
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)
541
 
 
542
 
 
543
443
    def __init__(self, functions=None):
544
444
        """
545
445
        >>> vtri = Validator()
587
487
        fun_match = self._func_re.match(check)
588
488
        if fun_match:
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:
593
 
                # Bad syntax
594
 
                raise VdtParamError
595
490
            fun_args = []
596
491
            fun_kwargs = {}
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)
602
 
                if listmatch:
603
 
                    key, val = self._list_handle(listmatch)
604
 
                    fun_kwargs[key] = val
605
 
                    continue
606
496
                keymatch = self._key_arg.match(arg)
607
497
                if keymatch:
608
 
                    val = self._unquote(keymatch.group(2))
 
498
                    val = keymatch.group(2)
 
499
                    if (val[0] in ("'", '"')) and (val[0] == val[-1]):
 
500
                        val = val[1:-1]
609
501
                    fun_kwargs[keymatch.group(1)] = val
610
502
                    continue
611
503
                #
612
 
                fun_args.append(self._unquote(arg))
 
504
                if (arg[0] in ("'", '"')) and (arg[0] == arg[-1]):
 
505
                    arg = arg[1:-1]
 
506
                fun_args.append(arg)
613
507
        else:
614
508
            # allows for function names without (args)
615
509
            (fun_name, fun_args, fun_kwargs) = (check, (), {})
630
524
        except KeyError:
631
525
            pass
632
526
        try:
633
 
            fun = self.functions[fun_name]
 
527
            return self.functions[fun_name](value, *fun_args, **fun_kwargs)
634
528
        except KeyError:
635
529
            raise VdtUnknownCheckError(fun_name)
636
 
        else:
637
 
##            print fun_args
638
 
##            print fun_kwargs
639
 
            return fun(value, *fun_args, **fun_kwargs)
640
 
 
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]):
644
 
            val = val[1:-1]
645
 
        return val
646
 
 
647
 
    def _list_handle(self, listmatch):
648
 
        """Take apart a ``keyword=list('val, 'val')`` type string."""
649
 
        out = []
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))
654
 
        return name, out
655
530
 
656
531
    def _pass(self, value):
657
532
        """
1184
1059
        raise VdtValueError(value)
1185
1060
    return value
1186
1061
 
1187
 
def _test(value, *args, **keywargs):
1188
 
    """
1189
 
    A function that exists for test purposes.
1190
 
    
1191
 
    >>> checks = [
1192
 
    ...     '3, 6, min=1, max=3, test=list(a, b, c)',
1193
 
    ...     '3',
1194
 
    ...     '3, 6',
1195
 
    ...     '3,',
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',
1200
 
    ...     'min=1, max=3',
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)'",
1206
 
    ...    ]
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'})
1211
 
    (3, ('3',), {})
1212
 
    (3, ('3', '6'), {})
1213
 
    (3, ('3',), {})
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)'})
1224
 
    """
1225
 
    return (value, args, keywargs)
1226
 
 
1227
 
 
1228
1062
if __name__ == '__main__':
1229
1063
    # run the code tests in doctest format
1230
1064
    import doctest
1247
1081
    ISSUES
1248
1082
    ======
1249
1083
    
 
1084
    Lists passed as function arguments need additional quotes. Ugly, could do
 
1085
    with fixing this.
 
1086
    
1250
1087
    If we could pull tuples out of arguments, it would be easier
1251
1088
    to specify arguments for 'mixed_lists'.
1252
1089
    
1253
1090
    CHANGELOG
1254
1091
    =========
1255
1092
    
1256
 
    2005/12/16
1257
 
    ----------
1258
 
    
1259
 
    Fixed bug so we can handle keyword argument values with commas.
1260
 
    
1261
 
    We now use a list constructor for passing list values to keyword arguments
1262
 
    (including ``default``) : ::
1263
 
    
1264
 
        default=list("val", "val", "val")
1265
 
    
1266
 
    Added the ``_test`` test. {sm;:-)}
1267
 
    
1268
 
    0.2.1
1269
 
    
1270
 
    2005/12/12
1271
 
    ----------
1272
 
    
1273
 
    Moved a function call outside a try...except block.
1274
 
    
1275
1093
    2005/08/25
1276
1094
    ----------
1277
1095