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