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