~ubuntu-branches/debian/stretch/configobj/stretch

« back to all changes in this revision

Viewing changes to validate.py

  • Committer: Package Import Robot
  • Author(s): Benjamin Drung
  • Date: 2014-08-28 18:42:29 UTC
  • mfrom: (1.3.4)
  • Revision ID: package-import@ubuntu.com-20140828184229-yisw15o0j2r334jx
Tags: 5.0.6-1
* Team upload.
* Update watch file to point to GitHub releases.
* Bump Standards-Version to 3.9.5
* Use the pybuild buildsystem.
* Release a package for Python 3. (Closes: #660172)
* Refresh eggify.diff
* Drop report-doctest-failure.diff and py27-test.diff (fixed upstream).
* Disable triplequotes.diff (fail to apply).
* Fix deprecation warning test case.
* Adjust autopkgtests to run pytest for Python 2.x and 3.x.
* Move documentation into separate package and build Sphinx documentation.
* Update debian/copyright

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# validate.py
2
2
# A Validator object
3
 
# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
4
 
# E-mail: fuzzyman AT voidspace DOT org DOT uk
5
 
#         mark AT la-la DOT com
6
 
#         nico AT tekNico DOT net
 
3
# Copyright (C) 2005-2014:
 
4
# (name) : (email)
 
5
# Michael Foord: fuzzyman AT voidspace DOT org DOT uk
 
6
# Mark Andrews: mark AT la-la DOT com
 
7
# Nicola Larosa: nico AT tekNico DOT net
 
8
# Rob Dennis: rdennis AT gmail DOT com
 
9
# Eli Courtwright: eli AT courtwright DOT org
7
10
 
8
11
# This software is licensed under the terms of the BSD license.
9
 
# http://www.voidspace.org.uk/python/license.shtml
10
 
# Basically you're free to copy, modify, distribute and relicense it,
11
 
# So long as you keep a copy of the license with it.
 
12
# http://opensource.org/licenses/BSD-3-Clause
12
13
 
13
 
# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
14
 
# For information about bugfixes, updates and support, please join the
15
 
# ConfigObj mailing list:
16
 
# http://lists.sourceforge.net/lists/listinfo/configobj-develop
17
 
# Comments, suggestions and bug reports welcome.
 
14
# ConfigObj 5 - main repository for documentation and issue tracking:
 
15
# https://github.com/DiffSK/configobj
18
16
 
19
17
"""
20
18
    The Validator object is used to check that supplied values 
165
163
 
166
164
 
167
165
import re
 
166
import sys
 
167
from pprint import pprint
168
168
 
 
169
#TODO - #21 - six is part of the repo now, but we didn't switch over to it here
 
170
# this could be replaced if six is used for compatibility, or there are no
 
171
# more assertions about items being a string
 
172
if sys.version_info < (3,):
 
173
    string_type = basestring
 
174
else:
 
175
    string_type = str
 
176
    # so tests that care about unicode on 2.x can specify unicode, and the same
 
177
    # tests when run on 3.x won't complain about a undefined name "unicode"
 
178
    # since all strings are unicode on 3.x we just want to pass it through
 
179
    # unchanged
 
180
    unicode = lambda x: x
 
181
    # in python 3, all ints are equivalent to python 2 longs, and they'll
 
182
    # never show "L" in the repr
 
183
    long = int
169
184
 
170
185
_list_arg = re.compile(r'''
171
186
    (?:
269
284
    >>> int(dottedQuadToNum('1.2.3.4'))
270
285
    16909060
271
286
    >>> dottedQuadToNum('255.255.255.255')
272
 
    4294967295L
 
287
    4294967295
273
288
    >>> dottedQuadToNum('255.255.255.256')
274
289
    Traceback (most recent call last):
275
290
    ValueError: Not a good dotted-quad IP: 255.255.255.256
282
297
        return struct.unpack('!L',
283
298
            socket.inet_aton(ip.strip()))[0]
284
299
    except socket.error:
285
 
        # bug in inet_aton, corrected in Python 2.4
286
 
        if ip.strip() == '255.255.255.255':
287
 
            return 0xFFFFFFFFL
288
 
        else:
289
 
            raise ValueError('Not a good dotted-quad IP: %s' % ip)
 
300
        raise ValueError('Not a good dotted-quad IP: %s' % ip)
290
301
    return
291
302
 
292
303
 
293
304
def numToDottedQuad(num):
294
305
    """
295
 
    Convert long int to dotted quad string
 
306
    Convert int or long int to dotted quad string
296
307
    
297
 
    >>> numToDottedQuad(-1L)
298
 
    Traceback (most recent call last):
299
 
    ValueError: Not a good numeric IP: -1
300
 
    >>> numToDottedQuad(1L)
301
 
    '0.0.0.1'
302
 
    >>> numToDottedQuad(16777218L)
303
 
    '1.0.0.2'
304
 
    >>> numToDottedQuad(16908291L)
305
 
    '1.2.0.3'
306
 
    >>> numToDottedQuad(16909060L)
307
 
    '1.2.3.4'
308
 
    >>> numToDottedQuad(4294967295L)
309
 
    '255.255.255.255'
310
 
    >>> numToDottedQuad(4294967296L)
311
 
    Traceback (most recent call last):
312
 
    ValueError: Not a good numeric IP: 4294967296
 
308
    >>> numToDottedQuad(long(-1))
 
309
    Traceback (most recent call last):
 
310
    ValueError: Not a good numeric IP: -1
 
311
    >>> numToDottedQuad(long(1))
 
312
    '0.0.0.1'
 
313
    >>> numToDottedQuad(long(16777218))
 
314
    '1.0.0.2'
 
315
    >>> numToDottedQuad(long(16908291))
 
316
    '1.2.0.3'
 
317
    >>> numToDottedQuad(long(16909060))
 
318
    '1.2.3.4'
 
319
    >>> numToDottedQuad(long(4294967295))
 
320
    '255.255.255.255'
 
321
    >>> numToDottedQuad(long(4294967296))
 
322
    Traceback (most recent call last):
 
323
    ValueError: Not a good numeric IP: 4294967296
 
324
    >>> numToDottedQuad(-1)
 
325
    Traceback (most recent call last):
 
326
    ValueError: Not a good numeric IP: -1
 
327
    >>> numToDottedQuad(1)
 
328
    '0.0.0.1'
 
329
    >>> numToDottedQuad(16777218)
 
330
    '1.0.0.2'
 
331
    >>> numToDottedQuad(16908291)
 
332
    '1.2.0.3'
 
333
    >>> numToDottedQuad(16909060)
 
334
    '1.2.3.4'
 
335
    >>> numToDottedQuad(4294967295)
 
336
    '255.255.255.255'
 
337
    >>> numToDottedQuad(4294967296)
 
338
    Traceback (most recent call last):
 
339
    ValueError: Not a good numeric IP: 4294967296
 
340
 
313
341
    """
314
342
    
315
343
    # import here to avoid it when ip_addr values are not used
316
344
    import socket, struct
317
345
    
318
346
    # no need to intercept here, 4294967295L is fine
319
 
    if num > 4294967295L or num < 0:
 
347
    if num > long(4294967295) or num < 0:
320
348
        raise ValueError('Not a good numeric IP: %s' % num)
321
349
    try:
322
350
        return socket.inet_ntoa(
464
492
    ...     # check that value is of the correct type.
465
493
    ...     # possible valid inputs are integers or strings
466
494
    ...     # that represent integers
467
 
    ...     if not isinstance(value, (int, long, basestring)):
 
495
    ...     if not isinstance(value, (int, long, string_type)):
468
496
    ...         raise VdtTypeError(value)
469
 
    ...     elif isinstance(value, basestring):
 
497
    ...     elif isinstance(value, string_type):
470
498
    ...         # if we are given a string
471
499
    ...         # attempt to convert to an integer
472
500
    ...         try:
510
538
    ConfigObj, an alternative to ConfigParser which supports lists and
511
539
    can validate a config file using a config schema.
512
540
    For more details on using Validator with ConfigObj see:
513
 
    http://www.voidspace.org.uk/python/configobj.html
 
541
    https://configobj.readthedocs.org/en/latest/configobj.html
514
542
    """
515
543
 
516
544
    # this regex does the initial parsing of the checks
615
643
            fun_kwargs = dict(fun_kwargs)
616
644
        else:
617
645
            fun_name, fun_args, fun_kwargs, default = self._parse_check(check)
618
 
            fun_kwargs = dict([(str(key), value) for (key, value) in fun_kwargs.items()])
 
646
            fun_kwargs = dict([(str(key), value) for (key, value) in list(fun_kwargs.items())])
619
647
            self._cache[check] = fun_name, list(fun_args), dict(fun_kwargs), default
620
648
        return fun_name, fun_args, fun_kwargs, default
621
649
        
736
764
    for (name, val) in zip(names, values):
737
765
        if val is None:
738
766
            out_params.append(val)
739
 
        elif isinstance(val, (int, long, float, basestring)):
 
767
        elif isinstance(val, (int, long, float, string_type)):
740
768
            try:
741
769
                out_params.append(fun(val))
742
 
            except ValueError, e:
 
770
            except ValueError as e:
743
771
                raise VdtParamError(name, val)
744
772
        else:
745
773
            raise VdtParamError(name, val)
793
821
    0
794
822
    """
795
823
    (min_val, max_val) = _is_num_param(('min', 'max'), (min, max))
796
 
    if not isinstance(value, (int, long, basestring)):
 
824
    if not isinstance(value, (int, long, string_type)):
797
825
        raise VdtTypeError(value)
798
 
    if isinstance(value, basestring):
 
826
    if isinstance(value, string_type):
799
827
        # if it's a string - does it represent an integer ?
800
828
        try:
801
829
            value = int(value)
845
873
    """
846
874
    (min_val, max_val) = _is_num_param(
847
875
        ('min', 'max'), (min, max), to_float=True)
848
 
    if not isinstance(value, (int, long, float, basestring)):
 
876
    if not isinstance(value, (int, long, float, string_type)):
849
877
        raise VdtTypeError(value)
850
878
    if not isinstance(value, float):
851
879
        # if it's a string - does it represent a float ?
910
938
    VdtTypeError: the value "up" is of the wrong type.
911
939
    
912
940
    """
913
 
    if isinstance(value, basestring):
 
941
    if isinstance(value, string_type):
914
942
        try:
915
943
            return bool_dict[value.lower()]
916
944
        except KeyError:
953
981
    Traceback (most recent call last):
954
982
    VdtTypeError: the value "0" is of the wrong type.
955
983
    """
956
 
    if not isinstance(value, basestring):
 
984
    if not isinstance(value, string_type):
957
985
        raise VdtTypeError(value)
958
986
    value = value.strip()
959
987
    try:
995
1023
    VdtTypeError: the value "12" is of the wrong type.
996
1024
    """
997
1025
    (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
998
 
    if isinstance(value, basestring):
 
1026
    if isinstance(value, string_type):
999
1027
        raise VdtTypeError(value)
1000
1028
    try:
1001
1029
        num_members = len(value)
1064
1092
    Traceback (most recent call last):
1065
1093
    VdtValueTooLongError: the value "1234" is too long.
1066
1094
    """
1067
 
    if not isinstance(value, basestring):
 
1095
    if not isinstance(value, string_type):
1068
1096
        raise VdtTypeError(value)
1069
1097
    (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
1070
1098
    try:
1170
1198
    Traceback (most recent call last):
1171
1199
    VdtTypeError: the value "hello" is of the wrong type.
1172
1200
    """
1173
 
    if isinstance(value, basestring):
 
1201
    if isinstance(value, string_type):
1174
1202
        raise VdtTypeError(value)
1175
1203
    return [is_string(mem) for mem in is_list(value, min, max)]
1176
1204
 
1266
1294
    >>> vtor.check(mix_str, 0)
1267
1295
    Traceback (most recent call last):
1268
1296
    VdtTypeError: the value "0" is of the wrong type.
1269
 
    
1270
 
    This test requires an elaborate setup, because of a change in error string
1271
 
    output from the interpreter between Python 2.2 and 2.3 .
1272
 
    
1273
 
    >>> res_seq = (
1274
 
    ...     'passed an incorrect value "',
1275
 
    ...     'yoda',
1276
 
    ...     '" for parameter "mixed_list".',
1277
 
    ... )
1278
 
    >>> res_str = "'".join(res_seq)
1279
 
    >>> try:
1280
 
    ...     vtor.check('mixed_list("yoda")', ('a'))
1281
 
    ... except VdtParamError, err:
1282
 
    ...     str(err) == res_str
1283
 
    1
 
1297
 
 
1298
    >>> vtor.check('mixed_list("yoda")', ('a'))
 
1299
    Traceback (most recent call last):
 
1300
    VdtParamError: passed an incorrect value "KeyError('yoda',)" for parameter "'mixed_list'"
1284
1301
    """
1285
1302
    try:
1286
1303
        length = len(value)
1292
1309
        raise VdtValueTooLongError(value)
1293
1310
    try:
1294
1311
        return [fun_dict[arg](val) for arg, val in zip(args, value)]
1295
 
    except KeyError, e:
 
1312
    except KeyError as e:
1296
1313
        raise VdtParamError('mixed_list', e)
1297
1314
 
1298
1315
 
1309
1326
    Traceback (most recent call last):
1310
1327
    VdtTypeError: the value "0" is of the wrong type.
1311
1328
    """
1312
 
    if not isinstance(value, basestring):
 
1329
    if not isinstance(value, string_type):
1313
1330
        raise VdtTypeError(value)
1314
1331
    if not value in options:
1315
1332
        raise VdtValueError(value)
1338
1355
    ...    ]
1339
1356
    >>> v = Validator({'test': _test})
1340
1357
    >>> for entry in checks:
1341
 
    ...     print v.check(('test(%s)' % entry), 3)
1342
 
    (3, ('3', '6'), {'test': ['a', 'b', 'c'], 'max': '3', 'min': '1'})
 
1358
    ...     pprint(v.check(('test(%s)' % entry), 3))
 
1359
    (3, ('3', '6'), {'max': '3', 'min': '1', 'test': ['a', 'b', 'c']})
1343
1360
    (3, ('3',), {})
1344
1361
    (3, ('3', '6'), {})
1345
1362
    (3, ('3',), {})
1346
 
    (3, (), {'test': 'a b c', 'min': '1'})
1347
 
    (3, (), {'test': 'a, b, c', 'min': '5'})
1348
 
    (3, (), {'test': 'a, b, c', 'max': '3', 'min': '1'})
1349
 
    (3, (), {'test': '-99', 'min': '-100'})
 
1363
    (3, (), {'min': '1', 'test': 'a b c'})
 
1364
    (3, (), {'min': '5', 'test': 'a, b, c'})
 
1365
    (3, (), {'max': '3', 'min': '1', 'test': 'a, b, c'})
 
1366
    (3, (), {'min': '-100', 'test': '-99'})
1350
1367
    (3, (), {'max': '3', 'min': '1'})
1351
1368
    (3, ('3', '6'), {'test': '36'})
1352
1369
    (3, ('3', '6'), {'test': 'a, b, c'})
1353
 
    (3, ('3',), {'test': ['a', 'b', 'c'], 'max': '3'})
1354
 
    (3, ('3',), {'test': ["'a'", 'b', 'x=(c)'], 'max': '3'})
 
1370
    (3, ('3',), {'max': '3', 'test': ['a', 'b', 'c']})
 
1371
    (3, ('3',), {'max': '3', 'test': ["'a'", 'b', 'x=(c)']})
1355
1372
    (3, (), {'test': 'x=fish(3)'})
1356
1373
    
1357
1374
    >>> v = Validator()
1383
1400
    
1384
1401
    Bug test for unicode arguments
1385
1402
    >>> v = Validator()
1386
 
    >>> v.check(u'string(min=4)', u'test')
1387
 
    u'test'
 
1403
    >>> v.check(unicode('string(min=4)'), unicode('test')) == unicode('test')
 
1404
    True
1388
1405
    
1389
1406
    >>> v = Validator()
1390
 
    >>> v.get_default_value(u'string(min=4, default="1234")')
1391
 
    u'1234'
1392
 
    >>> v.check(u'string(min=4, default="1234")', u'test')
1393
 
    u'test'
 
1407
    >>> v.get_default_value(unicode('string(min=4, default="1234")')) == unicode('1234')
 
1408
    True
 
1409
    >>> v.check(unicode('string(min=4, default="1234")'), unicode('test')) == unicode('test')
 
1410
    True
1394
1411
    
1395
1412
    >>> v = Validator()
1396
1413
    >>> default = v.get_default_value('string(default=None)')
1416
1433
    ''
1417
1434
    >>> vtor.check('string(default="\n")', '', missing=True)
1418
1435
    '\n'
1419
 
    >>> print vtor.check('string(default="\n")', '', missing=True),
 
1436
    >>> print(vtor.check('string(default="\n")', '', missing=True))
 
1437
    <BLANKLINE>
1420
1438
    <BLANKLINE>
1421
1439
    >>> vtor.check('string()', '\n')
1422
1440
    '\n'
1447
1465
    globs.update({
1448
1466
        'vtor': Validator(),
1449
1467
    })
1450
 
    doctest.testmod(m, globs=globs)
 
1468
 
 
1469
    failures, tests = doctest.testmod(
 
1470
        m, globs=globs,
 
1471
        optionflags=doctest.IGNORE_EXCEPTION_DETAIL | doctest.ELLIPSIS)
 
1472
    assert not failures, '{} failures out of {} tests'.format(failures, tests)