python/configobj/validate.py

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 # validate.py
     2 # A Validator object
     3 # Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
     4 # E-mail: fuzzyman AT voidspace DOT org DOT uk
     5 #         mark AT la-la DOT com
     6 #         nico AT tekNico DOT net
     8 # This software is licensed under the terms of the BSD license.
     9 # http://www.voidspace.org.uk/python/license.shtml
    10 # Basically you're free to copy, modify, distribute and relicense it,
    11 # So long as you keep a copy of the license with it.
    13 # Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
    14 # For information about bugfixes, updates and support, please join the
    15 # ConfigObj mailing list:
    16 # http://lists.sourceforge.net/lists/listinfo/configobj-develop
    17 # Comments, suggestions and bug reports welcome.
    19 """
    20     The Validator object is used to check that supplied values 
    21     conform to a specification.
    23     The value can be supplied as a string - e.g. from a config file.
    24     In this case the check will also *convert* the value to
    25     the required type. This allows you to add validation
    26     as a transparent layer to access data stored as strings.
    27     The validation checks that the data is correct *and*
    28     converts it to the expected type.
    30     Some standard checks are provided for basic data types.
    31     Additional checks are easy to write. They can be
    32     provided when the ``Validator`` is instantiated or
    33     added afterwards.
    35     The standard functions work with the following basic data types :
    37     * integers
    38     * floats
    39     * booleans
    40     * strings
    41     * ip_addr
    43     plus lists of these datatypes
    45     Adding additional checks is done through coding simple functions.
    47     The full set of standard checks are : 
    49     * 'integer': matches integer values (including negative)
    50                  Takes optional 'min' and 'max' arguments : ::
    52                    integer()
    53                    integer(3, 9)  # any value from 3 to 9
    54                    integer(min=0) # any positive value
    55                    integer(max=9)
    57     * 'float': matches float values
    58                Has the same parameters as the integer check.
    60     * 'boolean': matches boolean values - ``True`` or ``False``
    61                  Acceptable string values for True are :
    62                    true, on, yes, 1
    63                  Acceptable string values for False are :
    64                    false, off, no, 0
    66                  Any other value raises an error.
    68     * 'ip_addr': matches an Internet Protocol address, v.4, represented
    69                  by a dotted-quad string, i.e. '1.2.3.4'.
    71     * 'string': matches any string.
    72                 Takes optional keyword args 'min' and 'max'
    73                 to specify min and max lengths of the string.
    75     * 'list': matches any list.
    76               Takes optional keyword args 'min', and 'max' to specify min and
    77               max sizes of the list. (Always returns a list.)
    79     * 'tuple': matches any tuple.
    80               Takes optional keyword args 'min', and 'max' to specify min and
    81               max sizes of the tuple. (Always returns a tuple.)
    83     * 'int_list': Matches a list of integers.
    84                   Takes the same arguments as list.
    86     * 'float_list': Matches a list of floats.
    87                     Takes the same arguments as list.
    89     * 'bool_list': Matches a list of boolean values.
    90                    Takes the same arguments as list.
    92     * 'ip_addr_list': Matches a list of IP addresses.
    93                      Takes the same arguments as list.
    95     * 'string_list': Matches a list of strings.
    96                      Takes the same arguments as list.
    98     * 'mixed_list': Matches a list with different types in 
    99                     specific positions. List size must match
   100                     the number of arguments.
   102                     Each position can be one of :
   103                     'integer', 'float', 'ip_addr', 'string', 'boolean'
   105                     So to specify a list with two strings followed
   106                     by two integers, you write the check as : ::
   108                       mixed_list('string', 'string', 'integer', 'integer')
   110     * 'pass': This check matches everything ! It never fails
   111               and the value is unchanged.
   113               It is also the default if no check is specified.
   115     * 'option': This check matches any from a list of options.
   116                 You specify this check with : ::
   118                   option('option 1', 'option 2', 'option 3')
   120     You can supply a default value (returned if no value is supplied)
   121     using the default keyword argument.
   123     You specify a list argument for default using a list constructor syntax in
   124     the check : ::
   126         checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3'))
   128     A badly formatted set of arguments will raise a ``VdtParamError``.
   129 """
   131 __version__ = '1.0.1'
   134 __all__ = (
   135     '__version__',
   136     'dottedQuadToNum',
   137     'numToDottedQuad',
   138     'ValidateError',
   139     'VdtUnknownCheckError',
   140     'VdtParamError',
   141     'VdtTypeError',
   142     'VdtValueError',
   143     'VdtValueTooSmallError',
   144     'VdtValueTooBigError',
   145     'VdtValueTooShortError',
   146     'VdtValueTooLongError',
   147     'VdtMissingValue',
   148     'Validator',
   149     'is_integer',
   150     'is_float',
   151     'is_boolean',
   152     'is_list',
   153     'is_tuple',
   154     'is_ip_addr',
   155     'is_string',
   156     'is_int_list',
   157     'is_bool_list',
   158     'is_float_list',
   159     'is_string_list',
   160     'is_ip_addr_list',
   161     'is_mixed_list',
   162     'is_option',
   163     '__docformat__',
   164 )
   167 import re
   170 _list_arg = re.compile(r'''
   171     (?:
   172         ([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*list\(
   173             (
   174                 (?:
   175                     \s*
   176                     (?:
   177                         (?:".*?")|              # double quotes
   178                         (?:'.*?')|              # single quotes
   179                         (?:[^'",\s\)][^,\)]*?)  # unquoted
   180                     )
   181                     \s*,\s*
   182                 )*
   183                 (?:
   184                     (?:".*?")|              # double quotes
   185                     (?:'.*?')|              # single quotes
   186                     (?:[^'",\s\)][^,\)]*?)  # unquoted
   187                 )?                          # last one
   188             )
   189         \)
   190     )
   191 ''', re.VERBOSE | re.DOTALL)    # two groups
   193 _list_members = re.compile(r'''
   194     (
   195         (?:".*?")|              # double quotes
   196         (?:'.*?')|              # single quotes
   197         (?:[^'",\s=][^,=]*?)       # unquoted
   198     )
   199     (?:
   200     (?:\s*,\s*)|(?:\s*$)            # comma
   201     )
   202 ''', re.VERBOSE | re.DOTALL)    # one group
   204 _paramstring = r'''
   205     (?:
   206         (
   207             (?:
   208                 [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*list\(
   209                     (?:
   210                         \s*
   211                         (?:
   212                             (?:".*?")|              # double quotes
   213                             (?:'.*?')|              # single quotes
   214                             (?:[^'",\s\)][^,\)]*?)       # unquoted
   215                         )
   216                         \s*,\s*
   217                     )*
   218                     (?:
   219                         (?:".*?")|              # double quotes
   220                         (?:'.*?')|              # single quotes
   221                         (?:[^'",\s\)][^,\)]*?)       # unquoted
   222                     )?                              # last one
   223                 \)
   224             )|
   225             (?:
   226                 (?:".*?")|              # double quotes
   227                 (?:'.*?')|              # single quotes
   228                 (?:[^'",\s=][^,=]*?)|       # unquoted
   229                 (?:                         # keyword argument
   230                     [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*
   231                     (?:
   232                         (?:".*?")|              # double quotes
   233                         (?:'.*?')|              # single quotes
   234                         (?:[^'",\s=][^,=]*?)       # unquoted
   235                     )
   236                 )
   237             )
   238         )
   239         (?:
   240             (?:\s*,\s*)|(?:\s*$)            # comma
   241         )
   242     )
   243     '''
   245 _matchstring = '^%s*' % _paramstring
   247 # Python pre 2.2.1 doesn't have bool
   248 try:
   249     bool
   250 except NameError:
   251     def bool(val):
   252         """Simple boolean equivalent function. """
   253         if val:
   254             return 1
   255         else:
   256             return 0
   259 def dottedQuadToNum(ip):
   260     """
   261     Convert decimal dotted quad string to long integer
   263     >>> int(dottedQuadToNum('1 '))
   264     1
   265     >>> int(dottedQuadToNum(' 1.2'))
   266     16777218
   267     >>> int(dottedQuadToNum(' 1.2.3 '))
   268     16908291
   269     >>> int(dottedQuadToNum('1.2.3.4'))
   270     16909060
   271     >>> dottedQuadToNum('255.255.255.255')
   272     4294967295L
   273     >>> dottedQuadToNum('255.255.255.256')
   274     Traceback (most recent call last):
   275     ValueError: Not a good dotted-quad IP: 255.255.255.256
   276     """
   278     # import here to avoid it when ip_addr values are not used
   279     import socket, struct
   281     try:
   282         return struct.unpack('!L',
   283             socket.inet_aton(ip.strip()))[0]
   284     except socket.error:
   285         # bug in inet_aton, corrected in Python 2.4
   286         if ip.strip() == '255.255.255.255':
   287             return 0xFFFFFFFFL
   288         else:
   289             raise ValueError('Not a good dotted-quad IP: %s' % ip)
   290     return
   293 def numToDottedQuad(num):
   294     """
   295     Convert long int to dotted quad string
   297     >>> numToDottedQuad(-1L)
   298     Traceback (most recent call last):
   299     ValueError: Not a good numeric IP: -1
   300     >>> numToDottedQuad(1L)
   301     '0.0.0.1'
   302     >>> numToDottedQuad(16777218L)
   303     '1.0.0.2'
   304     >>> numToDottedQuad(16908291L)
   305     '1.2.0.3'
   306     >>> numToDottedQuad(16909060L)
   307     '1.2.3.4'
   308     >>> numToDottedQuad(4294967295L)
   309     '255.255.255.255'
   310     >>> numToDottedQuad(4294967296L)
   311     Traceback (most recent call last):
   312     ValueError: Not a good numeric IP: 4294967296
   313     """
   315     # import here to avoid it when ip_addr values are not used
   316     import socket, struct
   318     # no need to intercept here, 4294967295L is fine
   319     if num > 4294967295L or num < 0:
   320         raise ValueError('Not a good numeric IP: %s' % num)
   321     try:
   322         return socket.inet_ntoa(
   323             struct.pack('!L', long(num)))
   324     except (socket.error, struct.error, OverflowError):
   325         raise ValueError('Not a good numeric IP: %s' % num)
   328 class ValidateError(Exception):
   329     """
   330     This error indicates that the check failed.
   331     It can be the base class for more specific errors.
   333     Any check function that fails ought to raise this error.
   334     (or a subclass)
   336     >>> raise ValidateError
   337     Traceback (most recent call last):
   338     ValidateError
   339     """
   342 class VdtMissingValue(ValidateError):
   343     """No value was supplied to a check that needed one."""
   346 class VdtUnknownCheckError(ValidateError):
   347     """An unknown check function was requested"""
   349     def __init__(self, value):
   350         """
   351         >>> raise VdtUnknownCheckError('yoda')
   352         Traceback (most recent call last):
   353         VdtUnknownCheckError: the check "yoda" is unknown.
   354         """
   355         ValidateError.__init__(self, 'the check "%s" is unknown.' % (value,))
   358 class VdtParamError(SyntaxError):
   359     """An incorrect parameter was passed"""
   361     def __init__(self, name, value):
   362         """
   363         >>> raise VdtParamError('yoda', 'jedi')
   364         Traceback (most recent call last):
   365         VdtParamError: passed an incorrect value "jedi" for parameter "yoda".
   366         """
   367         SyntaxError.__init__(self, 'passed an incorrect value "%s" for parameter "%s".' % (value, name))
   370 class VdtTypeError(ValidateError):
   371     """The value supplied was of the wrong type"""
   373     def __init__(self, value):
   374         """
   375         >>> raise VdtTypeError('jedi')
   376         Traceback (most recent call last):
   377         VdtTypeError: the value "jedi" is of the wrong type.
   378         """
   379         ValidateError.__init__(self, 'the value "%s" is of the wrong type.' % (value,))
   382 class VdtValueError(ValidateError):
   383     """The value supplied was of the correct type, but was not an allowed value."""
   385     def __init__(self, value):
   386         """
   387         >>> raise VdtValueError('jedi')
   388         Traceback (most recent call last):
   389         VdtValueError: the value "jedi" is unacceptable.
   390         """
   391         ValidateError.__init__(self, 'the value "%s" is unacceptable.' % (value,))
   394 class VdtValueTooSmallError(VdtValueError):
   395     """The value supplied was of the correct type, but was too small."""
   397     def __init__(self, value):
   398         """
   399         >>> raise VdtValueTooSmallError('0')
   400         Traceback (most recent call last):
   401         VdtValueTooSmallError: the value "0" is too small.
   402         """
   403         ValidateError.__init__(self, 'the value "%s" is too small.' % (value,))
   406 class VdtValueTooBigError(VdtValueError):
   407     """The value supplied was of the correct type, but was too big."""
   409     def __init__(self, value):
   410         """
   411         >>> raise VdtValueTooBigError('1')
   412         Traceback (most recent call last):
   413         VdtValueTooBigError: the value "1" is too big.
   414         """
   415         ValidateError.__init__(self, 'the value "%s" is too big.' % (value,))
   418 class VdtValueTooShortError(VdtValueError):
   419     """The value supplied was of the correct type, but was too short."""
   421     def __init__(self, value):
   422         """
   423         >>> raise VdtValueTooShortError('jed')
   424         Traceback (most recent call last):
   425         VdtValueTooShortError: the value "jed" is too short.
   426         """
   427         ValidateError.__init__(
   428             self,
   429             'the value "%s" is too short.' % (value,))
   432 class VdtValueTooLongError(VdtValueError):
   433     """The value supplied was of the correct type, but was too long."""
   435     def __init__(self, value):
   436         """
   437         >>> raise VdtValueTooLongError('jedie')
   438         Traceback (most recent call last):
   439         VdtValueTooLongError: the value "jedie" is too long.
   440         """
   441         ValidateError.__init__(self, 'the value "%s" is too long.' % (value,))
   444 class Validator(object):
   445     """
   446     Validator is an object that allows you to register a set of 'checks'.
   447     These checks take input and test that it conforms to the check.
   449     This can also involve converting the value from a string into
   450     the correct datatype.
   452     The ``check`` method takes an input string which configures which
   453     check is to be used and applies that check to a supplied value.
   455     An example input string would be:
   456     'int_range(param1, param2)'
   458     You would then provide something like:
   460     >>> def int_range_check(value, min, max):
   461     ...     # turn min and max from strings to integers
   462     ...     min = int(min)
   463     ...     max = int(max)
   464     ...     # check that value is of the correct type.
   465     ...     # possible valid inputs are integers or strings
   466     ...     # that represent integers
   467     ...     if not isinstance(value, (int, long, basestring)):
   468     ...         raise VdtTypeError(value)
   469     ...     elif isinstance(value, basestring):
   470     ...         # if we are given a string
   471     ...         # attempt to convert to an integer
   472     ...         try:
   473     ...             value = int(value)
   474     ...         except ValueError:
   475     ...             raise VdtValueError(value)
   476     ...     # check the value is between our constraints
   477     ...     if not min <= value:
   478     ...          raise VdtValueTooSmallError(value)
   479     ...     if not value <= max:
   480     ...          raise VdtValueTooBigError(value)
   481     ...     return value
   483     >>> fdict = {'int_range': int_range_check}
   484     >>> vtr1 = Validator(fdict)
   485     >>> vtr1.check('int_range(20, 40)', '30')
   486     30
   487     >>> vtr1.check('int_range(20, 40)', '60')
   488     Traceback (most recent call last):
   489     VdtValueTooBigError: the value "60" is too big.
   491     New functions can be added with : ::
   493     >>> vtr2 = Validator()       
   494     >>> vtr2.functions['int_range'] = int_range_check
   496     Or by passing in a dictionary of functions when Validator 
   497     is instantiated.
   499     Your functions *can* use keyword arguments,
   500     but the first argument should always be 'value'.
   502     If the function doesn't take additional arguments,
   503     the parentheses are optional in the check.
   504     It can be written with either of : ::
   506         keyword = function_name
   507         keyword = function_name()
   509     The first program to utilise Validator() was Michael Foord's
   510     ConfigObj, an alternative to ConfigParser which supports lists and
   511     can validate a config file using a config schema.
   512     For more details on using Validator with ConfigObj see:
   513     http://www.voidspace.org.uk/python/configobj.html
   514     """
   516     # this regex does the initial parsing of the checks
   517     _func_re = re.compile(r'(.+?)\((.*)\)', re.DOTALL)
   519     # this regex takes apart keyword arguments
   520     _key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$',  re.DOTALL)
   523     # this regex finds keyword=list(....) type values
   524     _list_arg = _list_arg
   526     # this regex takes individual values out of lists - in one pass
   527     _list_members = _list_members
   529     # These regexes check a set of arguments for validity
   530     # and then pull the members out
   531     _paramfinder = re.compile(_paramstring, re.VERBOSE | re.DOTALL)
   532     _matchfinder = re.compile(_matchstring, re.VERBOSE | re.DOTALL)
   535     def __init__(self, functions=None):
   536         """
   537         >>> vtri = Validator()
   538         """
   539         self.functions = {
   540             '': self._pass,
   541             'integer': is_integer,
   542             'float': is_float,
   543             'boolean': is_boolean,
   544             'ip_addr': is_ip_addr,
   545             'string': is_string,
   546             'list': is_list,
   547             'tuple': is_tuple,
   548             'int_list': is_int_list,
   549             'float_list': is_float_list,
   550             'bool_list': is_bool_list,
   551             'ip_addr_list': is_ip_addr_list,
   552             'string_list': is_string_list,
   553             'mixed_list': is_mixed_list,
   554             'pass': self._pass,
   555             'option': is_option,
   556             'force_list': force_list,
   557         }
   558         if functions is not None:
   559             self.functions.update(functions)
   560         # tekNico: for use by ConfigObj
   561         self.baseErrorClass = ValidateError
   562         self._cache = {}
   565     def check(self, check, value, missing=False):
   566         """
   567         Usage: check(check, value)
   569         Arguments:
   570             check: string representing check to apply (including arguments)
   571             value: object to be checked
   572         Returns value, converted to correct type if necessary
   574         If the check fails, raises a ``ValidateError`` subclass.
   576         >>> vtor.check('yoda', '')
   577         Traceback (most recent call last):
   578         VdtUnknownCheckError: the check "yoda" is unknown.
   579         >>> vtor.check('yoda()', '')
   580         Traceback (most recent call last):
   581         VdtUnknownCheckError: the check "yoda" is unknown.
   583         >>> vtor.check('string(default="")', '', missing=True)
   584         ''
   585         """
   586         fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check)
   588         if missing:
   589             if default is None:
   590                 # no information needed here - to be handled by caller
   591                 raise VdtMissingValue()
   592             value = self._handle_none(default)
   594         if value is None:
   595             return None
   597         return self._check_value(value, fun_name, fun_args, fun_kwargs)
   600     def _handle_none(self, value):
   601         if value == 'None':
   602             return None
   603         elif value in ("'None'", '"None"'):
   604             # Special case a quoted None
   605             value = self._unquote(value)
   606         return value
   609     def _parse_with_caching(self, check):
   610         if check in self._cache:
   611             fun_name, fun_args, fun_kwargs, default = self._cache[check]
   612             # We call list and dict below to work with *copies* of the data
   613             # rather than the original (which are mutable of course)
   614             fun_args = list(fun_args)
   615             fun_kwargs = dict(fun_kwargs)
   616         else:
   617             fun_name, fun_args, fun_kwargs, default = self._parse_check(check)
   618             fun_kwargs = dict([(str(key), value) for (key, value) in fun_kwargs.items()])
   619             self._cache[check] = fun_name, list(fun_args), dict(fun_kwargs), default
   620         return fun_name, fun_args, fun_kwargs, default
   623     def _check_value(self, value, fun_name, fun_args, fun_kwargs):
   624         try:
   625             fun = self.functions[fun_name]
   626         except KeyError:
   627             raise VdtUnknownCheckError(fun_name)
   628         else:
   629             return fun(value, *fun_args, **fun_kwargs)
   632     def _parse_check(self, check):
   633         fun_match = self._func_re.match(check)
   634         if fun_match:
   635             fun_name = fun_match.group(1)
   636             arg_string = fun_match.group(2)
   637             arg_match = self._matchfinder.match(arg_string)
   638             if arg_match is None:
   639                 # Bad syntax
   640                 raise VdtParamError('Bad syntax in check "%s".' % check)
   641             fun_args = []
   642             fun_kwargs = {}
   643             # pull out args of group 2
   644             for arg in self._paramfinder.findall(arg_string):
   645                 # args may need whitespace removing (before removing quotes)
   646                 arg = arg.strip()
   647                 listmatch = self._list_arg.match(arg)
   648                 if listmatch:
   649                     key, val = self._list_handle(listmatch)
   650                     fun_kwargs[key] = val
   651                     continue
   652                 keymatch = self._key_arg.match(arg)
   653                 if keymatch:
   654                     val = keymatch.group(2)
   655                     if not val in ("'None'", '"None"'):
   656                         # Special case a quoted None
   657                         val = self._unquote(val)
   658                     fun_kwargs[keymatch.group(1)] = val
   659                     continue
   661                 fun_args.append(self._unquote(arg))
   662         else:
   663             # allows for function names without (args)
   664             return check, (), {}, None
   666         # Default must be deleted if the value is specified too,
   667         # otherwise the check function will get a spurious "default" keyword arg
   668         default = fun_kwargs.pop('default', None)
   669         return fun_name, fun_args, fun_kwargs, default
   672     def _unquote(self, val):
   673         """Unquote a value if necessary."""
   674         if (len(val) >= 2) and (val[0] in ("'", '"')) and (val[0] == val[-1]):
   675             val = val[1:-1]
   676         return val
   679     def _list_handle(self, listmatch):
   680         """Take apart a ``keyword=list('val, 'val')`` type string."""
   681         out = []
   682         name = listmatch.group(1)
   683         args = listmatch.group(2)
   684         for arg in self._list_members.findall(args):
   685             out.append(self._unquote(arg))
   686         return name, out
   689     def _pass(self, value):
   690         """
   691         Dummy check that always passes
   693         >>> vtor.check('', 0)
   694         0
   695         >>> vtor.check('', '0')
   696         '0'
   697         """
   698         return value
   701     def get_default_value(self, check):
   702         """
   703         Given a check, return the default value for the check
   704         (converted to the right type).
   706         If the check doesn't specify a default value then a
   707         ``KeyError`` will be raised.
   708         """
   709         fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check)
   710         if default is None:
   711             raise KeyError('Check "%s" has no default value.' % check)
   712         value = self._handle_none(default)
   713         if value is None:
   714             return value
   715         return self._check_value(value, fun_name, fun_args, fun_kwargs)
   718 def _is_num_param(names, values, to_float=False):
   719     """
   720     Return numbers from inputs or raise VdtParamError.
   722     Lets ``None`` pass through.
   723     Pass in keyword argument ``to_float=True`` to
   724     use float for the conversion rather than int.
   726     >>> _is_num_param(('', ''), (0, 1.0))
   727     [0, 1]
   728     >>> _is_num_param(('', ''), (0, 1.0), to_float=True)
   729     [0.0, 1.0]
   730     >>> _is_num_param(('a'), ('a'))
   731     Traceback (most recent call last):
   732     VdtParamError: passed an incorrect value "a" for parameter "a".
   733     """
   734     fun = to_float and float or int
   735     out_params = []
   736     for (name, val) in zip(names, values):
   737         if val is None:
   738             out_params.append(val)
   739         elif isinstance(val, (int, long, float, basestring)):
   740             try:
   741                 out_params.append(fun(val))
   742             except ValueError, e:
   743                 raise VdtParamError(name, val)
   744         else:
   745             raise VdtParamError(name, val)
   746     return out_params
   749 # built in checks
   750 # you can override these by setting the appropriate name
   751 # in Validator.functions
   752 # note: if the params are specified wrongly in your input string,
   753 #       you will also raise errors.
   755 def is_integer(value, min=None, max=None):
   756     """
   757     A check that tests that a given value is an integer (int, or long)
   758     and optionally, between bounds. A negative value is accepted, while
   759     a float will fail.
   761     If the value is a string, then the conversion is done - if possible.
   762     Otherwise a VdtError is raised.
   764     >>> vtor.check('integer', '-1')
   765     -1
   766     >>> vtor.check('integer', '0')
   767     0
   768     >>> vtor.check('integer', 9)
   769     9
   770     >>> vtor.check('integer', 'a')
   771     Traceback (most recent call last):
   772     VdtTypeError: the value "a" is of the wrong type.
   773     >>> vtor.check('integer', '2.2')
   774     Traceback (most recent call last):
   775     VdtTypeError: the value "2.2" is of the wrong type.
   776     >>> vtor.check('integer(10)', '20')
   777     20
   778     >>> vtor.check('integer(max=20)', '15')
   779     15
   780     >>> vtor.check('integer(10)', '9')
   781     Traceback (most recent call last):
   782     VdtValueTooSmallError: the value "9" is too small.
   783     >>> vtor.check('integer(10)', 9)
   784     Traceback (most recent call last):
   785     VdtValueTooSmallError: the value "9" is too small.
   786     >>> vtor.check('integer(max=20)', '35')
   787     Traceback (most recent call last):
   788     VdtValueTooBigError: the value "35" is too big.
   789     >>> vtor.check('integer(max=20)', 35)
   790     Traceback (most recent call last):
   791     VdtValueTooBigError: the value "35" is too big.
   792     >>> vtor.check('integer(0, 9)', False)
   793     0
   794     """
   795     (min_val, max_val) = _is_num_param(('min', 'max'), (min, max))
   796     if not isinstance(value, (int, long, basestring)):
   797         raise VdtTypeError(value)
   798     if isinstance(value, basestring):
   799         # if it's a string - does it represent an integer ?
   800         try:
   801             value = int(value)
   802         except ValueError:
   803             raise VdtTypeError(value)
   804     if (min_val is not None) and (value < min_val):
   805         raise VdtValueTooSmallError(value)
   806     if (max_val is not None) and (value > max_val):
   807         raise VdtValueTooBigError(value)
   808     return value
   811 def is_float(value, min=None, max=None):
   812     """
   813     A check that tests that a given value is a float
   814     (an integer will be accepted), and optionally - that it is between bounds.
   816     If the value is a string, then the conversion is done - if possible.
   817     Otherwise a VdtError is raised.
   819     This can accept negative values.
   821     >>> vtor.check('float', '2')
   822     2.0
   824     From now on we multiply the value to avoid comparing decimals
   826     >>> vtor.check('float', '-6.8') * 10
   827     -68.0
   828     >>> vtor.check('float', '12.2') * 10
   829     122.0
   830     >>> vtor.check('float', 8.4) * 10
   831     84.0
   832     >>> vtor.check('float', 'a')
   833     Traceback (most recent call last):
   834     VdtTypeError: the value "a" is of the wrong type.
   835     >>> vtor.check('float(10.1)', '10.2') * 10
   836     102.0
   837     >>> vtor.check('float(max=20.2)', '15.1') * 10
   838     151.0
   839     >>> vtor.check('float(10.0)', '9.0')
   840     Traceback (most recent call last):
   841     VdtValueTooSmallError: the value "9.0" is too small.
   842     >>> vtor.check('float(max=20.0)', '35.0')
   843     Traceback (most recent call last):
   844     VdtValueTooBigError: the value "35.0" is too big.
   845     """
   846     (min_val, max_val) = _is_num_param(
   847         ('min', 'max'), (min, max), to_float=True)
   848     if not isinstance(value, (int, long, float, basestring)):
   849         raise VdtTypeError(value)
   850     if not isinstance(value, float):
   851         # if it's a string - does it represent a float ?
   852         try:
   853             value = float(value)
   854         except ValueError:
   855             raise VdtTypeError(value)
   856     if (min_val is not None) and (value < min_val):
   857         raise VdtValueTooSmallError(value)
   858     if (max_val is not None) and (value > max_val):
   859         raise VdtValueTooBigError(value)
   860     return value
   863 bool_dict = {
   864     True: True, 'on': True, '1': True, 'true': True, 'yes': True, 
   865     False: False, 'off': False, '0': False, 'false': False, 'no': False,
   866 }
   869 def is_boolean(value):
   870     """
   871     Check if the value represents a boolean.
   873     >>> vtor.check('boolean', 0)
   874     0
   875     >>> vtor.check('boolean', False)
   876     0
   877     >>> vtor.check('boolean', '0')
   878     0
   879     >>> vtor.check('boolean', 'off')
   880     0
   881     >>> vtor.check('boolean', 'false')
   882     0
   883     >>> vtor.check('boolean', 'no')
   884     0
   885     >>> vtor.check('boolean', 'nO')
   886     0
   887     >>> vtor.check('boolean', 'NO')
   888     0
   889     >>> vtor.check('boolean', 1)
   890     1
   891     >>> vtor.check('boolean', True)
   892     1
   893     >>> vtor.check('boolean', '1')
   894     1
   895     >>> vtor.check('boolean', 'on')
   896     1
   897     >>> vtor.check('boolean', 'true')
   898     1
   899     >>> vtor.check('boolean', 'yes')
   900     1
   901     >>> vtor.check('boolean', 'Yes')
   902     1
   903     >>> vtor.check('boolean', 'YES')
   904     1
   905     >>> vtor.check('boolean', '')
   906     Traceback (most recent call last):
   907     VdtTypeError: the value "" is of the wrong type.
   908     >>> vtor.check('boolean', 'up')
   909     Traceback (most recent call last):
   910     VdtTypeError: the value "up" is of the wrong type.
   912     """
   913     if isinstance(value, basestring):
   914         try:
   915             return bool_dict[value.lower()]
   916         except KeyError:
   917             raise VdtTypeError(value)
   918     # we do an equality test rather than an identity test
   919     # this ensures Python 2.2 compatibilty
   920     # and allows 0 and 1 to represent True and False
   921     if value == False:
   922         return False
   923     elif value == True:
   924         return True
   925     else:
   926         raise VdtTypeError(value)
   929 def is_ip_addr(value):
   930     """
   931     Check that the supplied value is an Internet Protocol address, v.4,
   932     represented by a dotted-quad string, i.e. '1.2.3.4'.
   934     >>> vtor.check('ip_addr', '1 ')
   935     '1'
   936     >>> vtor.check('ip_addr', ' 1.2')
   937     '1.2'
   938     >>> vtor.check('ip_addr', ' 1.2.3 ')
   939     '1.2.3'
   940     >>> vtor.check('ip_addr', '1.2.3.4')
   941     '1.2.3.4'
   942     >>> vtor.check('ip_addr', '0.0.0.0')
   943     '0.0.0.0'
   944     >>> vtor.check('ip_addr', '255.255.255.255')
   945     '255.255.255.255'
   946     >>> vtor.check('ip_addr', '255.255.255.256')
   947     Traceback (most recent call last):
   948     VdtValueError: the value "255.255.255.256" is unacceptable.
   949     >>> vtor.check('ip_addr', '1.2.3.4.5')
   950     Traceback (most recent call last):
   951     VdtValueError: the value "1.2.3.4.5" is unacceptable.
   952     >>> vtor.check('ip_addr', 0)
   953     Traceback (most recent call last):
   954     VdtTypeError: the value "0" is of the wrong type.
   955     """
   956     if not isinstance(value, basestring):
   957         raise VdtTypeError(value)
   958     value = value.strip()
   959     try:
   960         dottedQuadToNum(value)
   961     except ValueError:
   962         raise VdtValueError(value)
   963     return value
   966 def is_list(value, min=None, max=None):
   967     """
   968     Check that the value is a list of values.
   970     You can optionally specify the minimum and maximum number of members.
   972     It does no check on list members.
   974     >>> vtor.check('list', ())
   975     []
   976     >>> vtor.check('list', [])
   977     []
   978     >>> vtor.check('list', (1, 2))
   979     [1, 2]
   980     >>> vtor.check('list', [1, 2])
   981     [1, 2]
   982     >>> vtor.check('list(3)', (1, 2))
   983     Traceback (most recent call last):
   984     VdtValueTooShortError: the value "(1, 2)" is too short.
   985     >>> vtor.check('list(max=5)', (1, 2, 3, 4, 5, 6))
   986     Traceback (most recent call last):
   987     VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long.
   988     >>> vtor.check('list(min=3, max=5)', (1, 2, 3, 4))
   989     [1, 2, 3, 4]
   990     >>> vtor.check('list', 0)
   991     Traceback (most recent call last):
   992     VdtTypeError: the value "0" is of the wrong type.
   993     >>> vtor.check('list', '12')
   994     Traceback (most recent call last):
   995     VdtTypeError: the value "12" is of the wrong type.
   996     """
   997     (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
   998     if isinstance(value, basestring):
   999         raise VdtTypeError(value)
  1000     try:
  1001         num_members = len(value)
  1002     except TypeError:
  1003         raise VdtTypeError(value)
  1004     if min_len is not None and num_members < min_len:
  1005         raise VdtValueTooShortError(value)
  1006     if max_len is not None and num_members > max_len:
  1007         raise VdtValueTooLongError(value)
  1008     return list(value)
  1011 def is_tuple(value, min=None, max=None):
  1012     """
  1013     Check that the value is a tuple of values.
  1015     You can optionally specify the minimum and maximum number of members.
  1017     It does no check on members.
  1019     >>> vtor.check('tuple', ())
  1020     ()
  1021     >>> vtor.check('tuple', [])
  1022     ()
  1023     >>> vtor.check('tuple', (1, 2))
  1024     (1, 2)
  1025     >>> vtor.check('tuple', [1, 2])
  1026     (1, 2)
  1027     >>> vtor.check('tuple(3)', (1, 2))
  1028     Traceback (most recent call last):
  1029     VdtValueTooShortError: the value "(1, 2)" is too short.
  1030     >>> vtor.check('tuple(max=5)', (1, 2, 3, 4, 5, 6))
  1031     Traceback (most recent call last):
  1032     VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long.
  1033     >>> vtor.check('tuple(min=3, max=5)', (1, 2, 3, 4))
  1034     (1, 2, 3, 4)
  1035     >>> vtor.check('tuple', 0)
  1036     Traceback (most recent call last):
  1037     VdtTypeError: the value "0" is of the wrong type.
  1038     >>> vtor.check('tuple', '12')
  1039     Traceback (most recent call last):
  1040     VdtTypeError: the value "12" is of the wrong type.
  1041     """
  1042     return tuple(is_list(value, min, max))
  1045 def is_string(value, min=None, max=None):
  1046     """
  1047     Check that the supplied value is a string.
  1049     You can optionally specify the minimum and maximum number of members.
  1051     >>> vtor.check('string', '0')
  1052     '0'
  1053     >>> vtor.check('string', 0)
  1054     Traceback (most recent call last):
  1055     VdtTypeError: the value "0" is of the wrong type.
  1056     >>> vtor.check('string(2)', '12')
  1057     '12'
  1058     >>> vtor.check('string(2)', '1')
  1059     Traceback (most recent call last):
  1060     VdtValueTooShortError: the value "1" is too short.
  1061     >>> vtor.check('string(min=2, max=3)', '123')
  1062     '123'
  1063     >>> vtor.check('string(min=2, max=3)', '1234')
  1064     Traceback (most recent call last):
  1065     VdtValueTooLongError: the value "1234" is too long.
  1066     """
  1067     if not isinstance(value, basestring):
  1068         raise VdtTypeError(value)
  1069     (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
  1070     try:
  1071         num_members = len(value)
  1072     except TypeError:
  1073         raise VdtTypeError(value)
  1074     if min_len is not None and num_members < min_len:
  1075         raise VdtValueTooShortError(value)
  1076     if max_len is not None and num_members > max_len:
  1077         raise VdtValueTooLongError(value)
  1078     return value
  1081 def is_int_list(value, min=None, max=None):
  1082     """
  1083     Check that the value is a list of integers.
  1085     You can optionally specify the minimum and maximum number of members.
  1087     Each list member is checked that it is an integer.
  1089     >>> vtor.check('int_list', ())
  1090     []
  1091     >>> vtor.check('int_list', [])
  1092     []
  1093     >>> vtor.check('int_list', (1, 2))
  1094     [1, 2]
  1095     >>> vtor.check('int_list', [1, 2])
  1096     [1, 2]
  1097     >>> vtor.check('int_list', [1, 'a'])
  1098     Traceback (most recent call last):
  1099     VdtTypeError: the value "a" is of the wrong type.
  1100     """
  1101     return [is_integer(mem) for mem in is_list(value, min, max)]
  1104 def is_bool_list(value, min=None, max=None):
  1105     """
  1106     Check that the value is a list of booleans.
  1108     You can optionally specify the minimum and maximum number of members.
  1110     Each list member is checked that it is a boolean.
  1112     >>> vtor.check('bool_list', ())
  1113     []
  1114     >>> vtor.check('bool_list', [])
  1115     []
  1116     >>> check_res = vtor.check('bool_list', (True, False))
  1117     >>> check_res == [True, False]
  1119     >>> check_res = vtor.check('bool_list', [True, False])
  1120     >>> check_res == [True, False]
  1122     >>> vtor.check('bool_list', [True, 'a'])
  1123     Traceback (most recent call last):
  1124     VdtTypeError: the value "a" is of the wrong type.
  1125     """
  1126     return [is_boolean(mem) for mem in is_list(value, min, max)]
  1129 def is_float_list(value, min=None, max=None):
  1130     """
  1131     Check that the value is a list of floats.
  1133     You can optionally specify the minimum and maximum number of members.
  1135     Each list member is checked that it is a float.
  1137     >>> vtor.check('float_list', ())
  1138     []
  1139     >>> vtor.check('float_list', [])
  1140     []
  1141     >>> vtor.check('float_list', (1, 2.0))
  1142     [1.0, 2.0]
  1143     >>> vtor.check('float_list', [1, 2.0])
  1144     [1.0, 2.0]
  1145     >>> vtor.check('float_list', [1, 'a'])
  1146     Traceback (most recent call last):
  1147     VdtTypeError: the value "a" is of the wrong type.
  1148     """
  1149     return [is_float(mem) for mem in is_list(value, min, max)]
  1152 def is_string_list(value, min=None, max=None):
  1153     """
  1154     Check that the value is a list of strings.
  1156     You can optionally specify the minimum and maximum number of members.
  1158     Each list member is checked that it is a string.
  1160     >>> vtor.check('string_list', ())
  1161     []
  1162     >>> vtor.check('string_list', [])
  1163     []
  1164     >>> vtor.check('string_list', ('a', 'b'))
  1165     ['a', 'b']
  1166     >>> vtor.check('string_list', ['a', 1])
  1167     Traceback (most recent call last):
  1168     VdtTypeError: the value "1" is of the wrong type.
  1169     >>> vtor.check('string_list', 'hello')
  1170     Traceback (most recent call last):
  1171     VdtTypeError: the value "hello" is of the wrong type.
  1172     """
  1173     if isinstance(value, basestring):
  1174         raise VdtTypeError(value)
  1175     return [is_string(mem) for mem in is_list(value, min, max)]
  1178 def is_ip_addr_list(value, min=None, max=None):
  1179     """
  1180     Check that the value is a list of IP addresses.
  1182     You can optionally specify the minimum and maximum number of members.
  1184     Each list member is checked that it is an IP address.
  1186     >>> vtor.check('ip_addr_list', ())
  1187     []
  1188     >>> vtor.check('ip_addr_list', [])
  1189     []
  1190     >>> vtor.check('ip_addr_list', ('1.2.3.4', '5.6.7.8'))
  1191     ['1.2.3.4', '5.6.7.8']
  1192     >>> vtor.check('ip_addr_list', ['a'])
  1193     Traceback (most recent call last):
  1194     VdtValueError: the value "a" is unacceptable.
  1195     """
  1196     return [is_ip_addr(mem) for mem in is_list(value, min, max)]
  1199 def force_list(value, min=None, max=None):
  1200     """
  1201     Check that a value is a list, coercing strings into
  1202     a list with one member. Useful where users forget the
  1203     trailing comma that turns a single value into a list.
  1205     You can optionally specify the minimum and maximum number of members.
  1206     A minumum of greater than one will fail if the user only supplies a
  1207     string.
  1209     >>> vtor.check('force_list', ())
  1210     []
  1211     >>> vtor.check('force_list', [])
  1212     []
  1213     >>> vtor.check('force_list', 'hello')
  1214     ['hello']
  1215     """
  1216     if not isinstance(value, (list, tuple)):
  1217         value = [value]
  1218     return is_list(value, min, max)
  1222 fun_dict = {
  1223     'integer': is_integer,
  1224     'float': is_float,
  1225     'ip_addr': is_ip_addr,
  1226     'string': is_string,
  1227     'boolean': is_boolean,
  1231 def is_mixed_list(value, *args):
  1232     """
  1233     Check that the value is a list.
  1234     Allow specifying the type of each member.
  1235     Work on lists of specific lengths.
  1237     You specify each member as a positional argument specifying type
  1239     Each type should be one of the following strings :
  1240       'integer', 'float', 'ip_addr', 'string', 'boolean'
  1242     So you can specify a list of two strings, followed by
  1243     two integers as :
  1245       mixed_list('string', 'string', 'integer', 'integer')
  1247     The length of the list must match the number of positional
  1248     arguments you supply.
  1250     >>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')"
  1251     >>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True))
  1252     >>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
  1254     >>> check_res = vtor.check(mix_str, ('1', '2.0', '1.2.3.4', 'a', 'True'))
  1255     >>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
  1257     >>> vtor.check(mix_str, ('b', 2.0, '1.2.3.4', 'a', True))
  1258     Traceback (most recent call last):
  1259     VdtTypeError: the value "b" is of the wrong type.
  1260     >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a'))
  1261     Traceback (most recent call last):
  1262     VdtValueTooShortError: the value "(1, 2.0, '1.2.3.4', 'a')" is too short.
  1263     >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', 1, 'b'))
  1264     Traceback (most recent call last):
  1265     VdtValueTooLongError: the value "(1, 2.0, '1.2.3.4', 'a', 1, 'b')" is too long.
  1266     >>> vtor.check(mix_str, 0)
  1267     Traceback (most recent call last):
  1268     VdtTypeError: the value "0" is of the wrong type.
  1270     This test requires an elaborate setup, because of a change in error string
  1271     output from the interpreter between Python 2.2 and 2.3 .
  1273     >>> res_seq = (
  1274     ...     'passed an incorrect value "',
  1275     ...     'yoda',
  1276     ...     '" for parameter "mixed_list".',
  1277     ... )
  1278     >>> res_str = "'".join(res_seq)
  1279     >>> try:
  1280     ...     vtor.check('mixed_list("yoda")', ('a'))
  1281     ... except VdtParamError, err:
  1282     ...     str(err) == res_str
  1284     """
  1285     try:
  1286         length = len(value)
  1287     except TypeError:
  1288         raise VdtTypeError(value)
  1289     if length < len(args):
  1290         raise VdtValueTooShortError(value)
  1291     elif length > len(args):
  1292         raise VdtValueTooLongError(value)
  1293     try:
  1294         return [fun_dict[arg](val) for arg, val in zip(args, value)]
  1295     except KeyError, e:
  1296         raise VdtParamError('mixed_list', e)
  1299 def is_option(value, *options):
  1300     """
  1301     This check matches the value to any of a set of options.
  1303     >>> vtor.check('option("yoda", "jedi")', 'yoda')
  1304     'yoda'
  1305     >>> vtor.check('option("yoda", "jedi")', 'jed')
  1306     Traceback (most recent call last):
  1307     VdtValueError: the value "jed" is unacceptable.
  1308     >>> vtor.check('option("yoda", "jedi")', 0)
  1309     Traceback (most recent call last):
  1310     VdtTypeError: the value "0" is of the wrong type.
  1311     """
  1312     if not isinstance(value, basestring):
  1313         raise VdtTypeError(value)
  1314     if not value in options:
  1315         raise VdtValueError(value)
  1316     return value
  1319 def _test(value, *args, **keywargs):
  1320     """
  1321     A function that exists for test purposes.
  1323     >>> checks = [
  1324     ...     '3, 6, min=1, max=3, test=list(a, b, c)',
  1325     ...     '3',
  1326     ...     '3, 6',
  1327     ...     '3,',
  1328     ...     'min=1, test="a b c"',
  1329     ...     'min=5, test="a, b, c"',
  1330     ...     'min=1, max=3, test="a, b, c"',
  1331     ...     'min=-100, test=-99',
  1332     ...     'min=1, max=3',
  1333     ...     '3, 6, test="36"',
  1334     ...     '3, 6, test="a, b, c"',
  1335     ...     '3, max=3, test=list("a", "b", "c")',
  1336     ...     '''3, max=3, test=list("'a'", 'b', "x=(c)")''',
  1337     ...     "test='x=fish(3)'",
  1338     ...    ]
  1339     >>> v = Validator({'test': _test})
  1340     >>> for entry in checks:
  1341     ...     print v.check(('test(%s)' % entry), 3)
  1342     (3, ('3', '6'), {'test': ['a', 'b', 'c'], 'max': '3', 'min': '1'})
  1343     (3, ('3',), {})
  1344     (3, ('3', '6'), {})
  1345     (3, ('3',), {})
  1346     (3, (), {'test': 'a b c', 'min': '1'})
  1347     (3, (), {'test': 'a, b, c', 'min': '5'})
  1348     (3, (), {'test': 'a, b, c', 'max': '3', 'min': '1'})
  1349     (3, (), {'test': '-99', 'min': '-100'})
  1350     (3, (), {'max': '3', 'min': '1'})
  1351     (3, ('3', '6'), {'test': '36'})
  1352     (3, ('3', '6'), {'test': 'a, b, c'})
  1353     (3, ('3',), {'test': ['a', 'b', 'c'], 'max': '3'})
  1354     (3, ('3',), {'test': ["'a'", 'b', 'x=(c)'], 'max': '3'})
  1355     (3, (), {'test': 'x=fish(3)'})
  1357     >>> v = Validator()
  1358     >>> v.check('integer(default=6)', '3')
  1360     >>> v.check('integer(default=6)', None, True)
  1362     >>> v.get_default_value('integer(default=6)')
  1364     >>> v.get_default_value('float(default=6)')
  1365     6.0
  1366     >>> v.get_default_value('pass(default=None)')
  1367     >>> v.get_default_value("string(default='None')")
  1368     'None'
  1369     >>> v.get_default_value('pass')
  1370     Traceback (most recent call last):
  1371     KeyError: 'Check "pass" has no default value.'
  1372     >>> v.get_default_value('pass(default=list(1, 2, 3, 4))')
  1373     ['1', '2', '3', '4']
  1375     >>> v = Validator()
  1376     >>> v.check("pass(default=None)", None, True)
  1377     >>> v.check("pass(default='None')", None, True)
  1378     'None'
  1379     >>> v.check('pass(default="None")', None, True)
  1380     'None'
  1381     >>> v.check('pass(default=list(1, 2, 3, 4))', None, True)
  1382     ['1', '2', '3', '4']
  1384     Bug test for unicode arguments
  1385     >>> v = Validator()
  1386     >>> v.check(u'string(min=4)', u'test')
  1387     u'test'
  1389     >>> v = Validator()
  1390     >>> v.get_default_value(u'string(min=4, default="1234")')
  1391     u'1234'
  1392     >>> v.check(u'string(min=4, default="1234")', u'test')
  1393     u'test'
  1395     >>> v = Validator()
  1396     >>> default = v.get_default_value('string(default=None)')
  1397     >>> default == None
  1399     """
  1400     return (value, args, keywargs)
  1403 def _test2():
  1404     """
  1405     >>> 
  1406     >>> v = Validator()
  1407     >>> v.get_default_value('string(default="#ff00dd")')
  1408     '#ff00dd'
  1409     >>> v.get_default_value('integer(default=3) # comment')
  1411     """
  1413 def _test3():
  1414     r"""
  1415     >>> vtor.check('string(default="")', '', missing=True)
  1416     ''
  1417     >>> vtor.check('string(default="\n")', '', missing=True)
  1418     '\n'
  1419     >>> print vtor.check('string(default="\n")', '', missing=True),
  1420     <BLANKLINE>
  1421     >>> vtor.check('string()', '\n')
  1422     '\n'
  1423     >>> vtor.check('string(default="\n\n\n")', '', missing=True)
  1424     '\n\n\n'
  1425     >>> vtor.check('string()', 'random \n text goes here\n\n')
  1426     'random \n text goes here\n\n'
  1427     >>> vtor.check('string(default=" \nrandom text\ngoes \n here\n\n ")',
  1428     ... '', missing=True)
  1429     ' \nrandom text\ngoes \n here\n\n '
  1430     >>> vtor.check("string(default='\n\n\n')", '', missing=True)
  1431     '\n\n\n'
  1432     >>> vtor.check("option('\n','a','b',default='\n')", '', missing=True)
  1433     '\n'
  1434     >>> vtor.check("string_list()", ['foo', '\n', 'bar'])
  1435     ['foo', '\n', 'bar']
  1436     >>> vtor.check("string_list(default=list('\n'))", '', missing=True)
  1437     ['\n']
  1438     """
  1441 if __name__ == '__main__':
  1442     # run the code tests in doctest format
  1443     import sys
  1444     import doctest
  1445     m = sys.modules.get('__main__')
  1446     globs = m.__dict__.copy()
  1447     globs.update({
  1448         'vtor': Validator(),
  1449     })
  1450     doctest.testmod(m, globs=globs)

mercurial