Package pythonutils :: Module validate
[hide private]
[frames] | no frames]

Module validate
source code

The Validator object is used to check that supplied values conform to a specification.

The value can be supplied as a string - e.g. from a config file. In this case the check will also convert the value to the required type. This allows you to add validation as a transparent layer to access data stored as strings. The validation checks that the data is correct and converts it to the expected type.

Some standard checks are provided for basic data types. Additional checks are easy to write. They can be provided when the Validator is instantiated or added afterwards.

The standard functions work with the following basic data types :

plus lists of these datatypes

Adding additional checks is done through coding simple functions.

The full set of standard checks are :

You can supply a default value (returned if no value is supplied) using the default keyword argument.

You specify a list argument for default using a list constructor syntax in the check :

checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3'))

A badly formatted set of arguments will raise a VdtParamError.



Classes [hide private]
ValidateError This error indicates that the check failed.
VdtMissingValue No value was supplied to a check that needed one.
VdtUnknownCheckError An unknown check function was requested
VdtParamError An incorrect parameter was passed
VdtTypeError The value supplied was of the wrong type
VdtValueError The value supplied was of the correct type, but was not an allowed value.
VdtValueTooSmallError The value supplied was of the correct type, but was too small.
VdtValueTooBigError The value supplied was of the correct type, but was too big.
VdtValueTooShortError The value supplied was of the correct type, but was too short.
VdtValueTooLongError The value supplied was of the correct type, but was too long.
Validator Validator is an object that allows you to register a set of 'checks'.

Functions [hide private]
  bool(val)
Simple boolean equivalent function.
  dottedQuadToNum(ip)
Convert decimal dotted quad string to long integer
  numToDottedQuad(num)
Convert long int to dotted quad string
  _is_num_param(names, values, to_float=False)
Return numbers from inputs or raise VdtParamError.
  is_integer(value, min=None, max=None)
A check that tests that a given value is an integer (int, or long) and optionally, between bounds.
  is_float(value, min=None, max=None)
A check that tests that a given value is a float (an integer will be accepted), and optionally - that it is between bounds.
  is_bool(value)
Check if the value represents a boolean.
  is_ip_addr(value)
Check that the supplied value is an Internet Protocol address, v.4, represented by a dotted-quad string, i.e.
  is_list(value, min=None, max=None)
Check that the value is a list of values.
  is_string(value, min=None, max=None)
Check that the supplied value is a string.
  is_int_list(value, min=None, max=None)
Check that the value is a list of integers.
  is_bool_list(value, min=None, max=None)
Check that the value is a list of booleans.
  is_float_list(value, min=None, max=None)
Check that the value is a list of floats.
  is_string_list(value, min=None, max=None)
Check that the value is a list of strings.
  is_ip_addr_list(value, min=None, max=None)
Check that the value is a list of IP addresses.
  is_mixed_list(value, *args)
Check that the value is a list.
  is_option(value, *options)
This check matches the value to any of a set of options.
  _test(value, *args, **keywargs)
A function that exists for test purposes.

Variables [hide private]
__version__  
__revision__  
INTP_VER  
StringTypes  
_list_arg  
_list_members  
_paramstring  
_matchstring  
bool_dict  
fun_dict  
m  
globs  

Imports: sys, re, doctest

Function Details [hide private]

bool(val)

source code 
Simple boolean equivalent function.

dottedQuadToNum(ip)

source code 

Convert decimal dotted quad string to long integer

>>> dottedQuadToNum('1 ')
1L
>>> dottedQuadToNum(' 1.2')
16777218L
>>> dottedQuadToNum(' 1.2.3 ')
16908291L
>>> dottedQuadToNum('1.2.3.4')
16909060L
>>> dottedQuadToNum('1.2.3. 4')
Traceback (most recent call last):
ValueError: Not a good dotted-quad IP: 1.2.3. 4
>>> dottedQuadToNum('255.255.255.255')
4294967295L
>>> dottedQuadToNum('255.255.255.256')
Traceback (most recent call last):
ValueError: Not a good dotted-quad IP: 255.255.255.256

numToDottedQuad(num)

source code 

Convert long int to dotted quad string

>>> numToDottedQuad(-1L)
Traceback (most recent call last):
ValueError: Not a good numeric IP: -1
>>> numToDottedQuad(1L)
'0.0.0.1'
>>> numToDottedQuad(16777218L)
'1.0.0.2'
>>> numToDottedQuad(16908291L)
'1.2.0.3'
>>> numToDottedQuad(16909060L)
'1.2.3.4'
>>> numToDottedQuad(4294967295L)
'255.255.255.255'
>>> numToDottedQuad(4294967296L)
Traceback (most recent call last):
ValueError: Not a good numeric IP: 4294967296

_is_num_param(names, values, to_float=False)

source code 

Return numbers from inputs or raise VdtParamError.

Lets None pass through. Pass in keyword argument to_float=True to use float for the conversion rather than int.

>>> _is_num_param(('', ''), (0, 1.0))
[0, 1]
>>> _is_num_param(('', ''), (0, 1.0), to_float=True)
[0.0, 1.0]
>>> _is_num_param(('a'), ('a'))
Traceback (most recent call last):
VdtParamError: passed an incorrect value "a" for parameter "a".

is_integer(value, min=None, max=None)

source code 

A check that tests that a given value is an integer (int, or long) and optionally, between bounds. A negative value is accepted, while a float will fail.

If the value is a string, then the conversion is done - if possible. Otherwise a VdtError is raised.

>>> vtor.check('integer', '-1')
-1
>>> vtor.check('integer', '0')
0
>>> vtor.check('integer', 9)
9
>>> vtor.check('integer', 'a')
Traceback (most recent call last):
VdtTypeError: the value "a" is of the wrong type.
>>> vtor.check('integer', '2.2')
Traceback (most recent call last):
VdtTypeError: the value "2.2" is of the wrong type.
>>> vtor.check('integer(10)', '20')
20
>>> vtor.check('integer(max=20)', '15')
15
>>> vtor.check('integer(10)', '9')
Traceback (most recent call last):
VdtValueTooSmallError: the value "9" is too small.
>>> vtor.check('integer(10)', 9)
Traceback (most recent call last):
VdtValueTooSmallError: the value "9" is too small.
>>> vtor.check('integer(max=20)', '35')
Traceback (most recent call last):
VdtValueTooBigError: the value "35" is too big.
>>> vtor.check('integer(max=20)', 35)
Traceback (most recent call last):
VdtValueTooBigError: the value "35" is too big.
>>> vtor.check('integer(0, 9)', False)
0

is_float(value, min=None, max=None)

source code 

A check that tests that a given value is a float (an integer will be accepted), and optionally - that it is between bounds.

If the value is a string, then the conversion is done - if possible. Otherwise a VdtError is raised.

This can accept negative values.

>>> vtor.check('float', '2')
2.0

From now on we multiply the value to avoid comparing decimals

>>> vtor.check('float', '-6.8') * 10
-68.0
>>> vtor.check('float', '12.2') * 10
122.0
>>> vtor.check('float', 8.4) * 10
84.0
>>> vtor.check('float', 'a')
Traceback (most recent call last):
VdtTypeError: the value "a" is of the wrong type.
>>> vtor.check('float(10.1)', '10.2') * 10
102.0
>>> vtor.check('float(max=20.2)', '15.1') * 10
151.0
>>> vtor.check('float(10.0)', '9.0')
Traceback (most recent call last):
VdtValueTooSmallError: the value "9.0" is too small.
>>> vtor.check('float(max=20.0)', '35.0')
Traceback (most recent call last):
VdtValueTooBigError: the value "35.0" is too big.

is_bool(value)

source code 

Check if the value represents a boolean.

>>> vtor.check('boolean', 0)
0
>>> vtor.check('boolean', False)
0
>>> vtor.check('boolean', '0')
0
>>> vtor.check('boolean', 'off')
0
>>> vtor.check('boolean', 'false')
0
>>> vtor.check('boolean', 'no')
0
>>> vtor.check('boolean', 'nO')
0
>>> vtor.check('boolean', 'NO')
0
>>> vtor.check('boolean', 1)
1
>>> vtor.check('boolean', True)
1
>>> vtor.check('boolean', '1')
1
>>> vtor.check('boolean', 'on')
1
>>> vtor.check('boolean', 'true')
1
>>> vtor.check('boolean', 'yes')
1
>>> vtor.check('boolean', 'Yes')
1
>>> vtor.check('boolean', 'YES')
1
>>> vtor.check('boolean', '')
Traceback (most recent call last):
VdtTypeError: the value "" is of the wrong type.
>>> vtor.check('boolean', 'up')
Traceback (most recent call last):
VdtTypeError: the value "up" is of the wrong type.

is_ip_addr(value)

source code 

Check that the supplied value is an Internet Protocol address, v.4, represented by a dotted-quad string, i.e. '1.2.3.4'.

>>> vtor.check('ip_addr', '1 ')
'1'
>>> vtor.check('ip_addr', ' 1.2')
'1.2'
>>> vtor.check('ip_addr', ' 1.2.3 ')
'1.2.3'
>>> vtor.check('ip_addr', '1.2.3.4')
'1.2.3.4'
>>> vtor.check('ip_addr', '0.0.0.0')
'0.0.0.0'
>>> vtor.check('ip_addr', '255.255.255.255')
'255.255.255.255'
>>> vtor.check('ip_addr', '255.255.255.256')
Traceback (most recent call last):
VdtValueError: the value "255.255.255.256" is unacceptable.
>>> vtor.check('ip_addr', '1.2.3.4.5')
Traceback (most recent call last):
VdtValueError: the value "1.2.3.4.5" is unacceptable.
>>> vtor.check('ip_addr', '1.2.3. 4')
Traceback (most recent call last):
VdtValueError: the value "1.2.3. 4" is unacceptable.
>>> vtor.check('ip_addr', 0)
Traceback (most recent call last):
VdtTypeError: the value "0" is of the wrong type.

is_list(value, min=None, max=None)

source code 

Check that the value is a list of values.

You can optionally specify the minimum and maximum number of members.

It does no check on list members.

>>> vtor.check('list', ())
()
>>> vtor.check('list', [])
[]
>>> vtor.check('list', (1, 2))
(1, 2)
>>> vtor.check('list', [1, 2])
[1, 2]
>>> vtor.check('list', '12')
'12'
>>> vtor.check('list(3)', (1, 2))
Traceback (most recent call last):
VdtValueTooShortError: the value "(1, 2)" is too short.
>>> vtor.check('list(max=5)', (1, 2, 3, 4, 5, 6))
Traceback (most recent call last):
VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long.
>>> vtor.check('list(min=3, max=5)', (1, 2, 3, 4))
(1, 2, 3, 4)
>>> vtor.check('list', 0)
Traceback (most recent call last):
VdtTypeError: the value "0" is of the wrong type.

is_string(value, min=None, max=None)

source code 

Check that the supplied value is a string.

You can optionally specify the minimum and maximum number of members.

>>> vtor.check('string', '0')
'0'
>>> vtor.check('string', 0)
Traceback (most recent call last):
VdtTypeError: the value "0" is of the wrong type.
>>> vtor.check('string(2)', '12')
'12'
>>> vtor.check('string(2)', '1')
Traceback (most recent call last):
VdtValueTooShortError: the value "1" is too short.
>>> vtor.check('string(min=2, max=3)', '123')
'123'
>>> vtor.check('string(min=2, max=3)', '1234')
Traceback (most recent call last):
VdtValueTooLongError: the value "1234" is too long.

is_int_list(value, min=None, max=None)

source code 

Check that the value is a list of integers.

You can optionally specify the minimum and maximum number of members.

Each list member is checked that it is an integer.

>>> vtor.check('int_list', ())
[]
>>> vtor.check('int_list', [])
[]
>>> vtor.check('int_list', (1, 2))
[1, 2]
>>> vtor.check('int_list', [1, 2])
[1, 2]
>>> vtor.check('int_list', [1, 'a'])
Traceback (most recent call last):
VdtTypeError: the value "a" is of the wrong type.

is_bool_list(value, min=None, max=None)

source code 

Check that the value is a list of booleans.

You can optionally specify the minimum and maximum number of members.

Each list member is checked that it is a boolean.

>>> vtor.check('bool_list', ())
[]
>>> vtor.check('bool_list', [])
[]
>>> check_res = vtor.check('bool_list', (True, False))
>>> check_res == [True, False]
1
>>> check_res = vtor.check('bool_list', [True, False])
>>> check_res == [True, False]
1
>>> vtor.check('bool_list', [True, 'a'])
Traceback (most recent call last):
VdtTypeError: the value "a" is of the wrong type.

is_float_list(value, min=None, max=None)

source code 

Check that the value is a list of floats.

You can optionally specify the minimum and maximum number of members.

Each list member is checked that it is a float.

>>> vtor.check('float_list', ())
[]
>>> vtor.check('float_list', [])
[]
>>> vtor.check('float_list', (1, 2.0))
[1.0, 2.0]
>>> vtor.check('float_list', [1, 2.0])
[1.0, 2.0]
>>> vtor.check('float_list', [1, 'a'])
Traceback (most recent call last):
VdtTypeError: the value "a" is of the wrong type.

is_string_list(value, min=None, max=None)

source code 

Check that the value is a list of strings.

You can optionally specify the minimum and maximum number of members.

Each list member is checked that it is a string.

>>> vtor.check('string_list', ())
[]
>>> vtor.check('string_list', [])
[]
>>> vtor.check('string_list', ('a', 'b'))
['a', 'b']
>>> vtor.check('string_list', ['a', 1])
Traceback (most recent call last):
VdtTypeError: the value "1" is of the wrong type.
>>> vtor.check('string_list', 'hello')
Traceback (most recent call last):
VdtTypeError: the value "hello" is of the wrong type.

is_ip_addr_list(value, min=None, max=None)

source code 

Check that the value is a list of IP addresses.

You can optionally specify the minimum and maximum number of members.

Each list member is checked that it is an IP address.

>>> vtor.check('ip_addr_list', ())
[]
>>> vtor.check('ip_addr_list', [])
[]
>>> vtor.check('ip_addr_list', ('1.2.3.4', '5.6.7.8'))
['1.2.3.4', '5.6.7.8']
>>> vtor.check('ip_addr_list', ['a'])
Traceback (most recent call last):
VdtValueError: the value "a" is unacceptable.

is_mixed_list(value, *args)

source code 

Check that the value is a list. Allow specifying the type of each member. Work on lists of specific lengths.

You specify each member as a positional argument specifying type

Each type should be one of the following strings :
'integer', 'float', 'ip_addr', 'string', 'boolean'

So you can specify a list of two strings, followed by two integers as :

mixed_list('string', 'string', 'integer', 'integer')

The length of the list must match the number of positional arguments you supply.

>>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')"
>>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True))
>>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
1
>>> check_res = vtor.check(mix_str, ('1', '2.0', '1.2.3.4', 'a', 'True'))
>>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
1
>>> vtor.check(mix_str, ('b', 2.0, '1.2.3.4', 'a', True))
Traceback (most recent call last):
VdtTypeError: the value "b" is of the wrong type.
>>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a'))
Traceback (most recent call last):
VdtValueTooShortError: the value "(1, 2.0, '1.2.3.4', 'a')" is too short.
>>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', 1, 'b'))
Traceback (most recent call last):
VdtValueTooLongError: the value "(1, 2.0, '1.2.3.4', 'a', 1, 'b')" is too long.
>>> vtor.check(mix_str, 0)
Traceback (most recent call last):
VdtTypeError: the value "0" is of the wrong type.

This test requires an elaborate setup, because of a change in error string output from the interpreter between Python 2.2 and 2.3 .

>>> res_seq = (
...     'passed an incorrect value "',
...     'yoda',
...     '" for parameter "mixed_list".',
... )
>>> if INTP_VER == (2, 2):
...     res_str = "".join(res_seq)
... else:
...     res_str = "'".join(res_seq)
>>> try:
...     vtor.check('mixed_list("yoda")', ('a'))
... except VdtParamError, err:
...     str(err) == res_str
1

is_option(value, *options)

source code 

This check matches the value to any of a set of options.

>>> vtor.check('option("yoda", "jedi")', 'yoda')
'yoda'
>>> vtor.check('option("yoda", "jedi")', 'jed')
Traceback (most recent call last):
VdtValueError: the value "jed" is unacceptable.
>>> vtor.check('option("yoda", "jedi")', 0)
Traceback (most recent call last):
VdtTypeError: the value "0" is of the wrong type.

_test(value, *args, **keywargs)

source code 

A function that exists for test purposes.

>>> checks = [
...     '3, 6, min=1, max=3, test=list(a, b, c)',
...     '3',
...     '3, 6',
...     '3,',
...     'min=1, test="a b c"',
...     'min=5, test="a, b, c"',
...     'min=1, max=3, test="a, b, c"',
...     'min=-100, test=-99',
...     'min=1, max=3',
...     '3, 6, test="36"',
...     '3, 6, test="a, b, c"',
...     '3, max=3, test=list("a", "b", "c")',
...     '''3, max=3, test=list("'a'", 'b', "x=(c)")''',
...     "test='x=fish(3)'",
...    ]
>>> v = Validator({'test': _test})
>>> for entry in checks:
...     print v.check(('test(%s)' % entry), 3)
(3, ('3', '6'), {'test': ['a', 'b', 'c'], 'max': '3', 'min': '1'})
(3, ('3',), {})
(3, ('3', '6'), {})
(3, ('3',), {})
(3, (), {'test': 'a b c', 'min': '1'})
(3, (), {'test': 'a, b, c', 'min': '5'})
(3, (), {'test': 'a, b, c', 'max': '3', 'min': '1'})
(3, (), {'test': '-99', 'min': '-100'})
(3, (), {'max': '3', 'min': '1'})
(3, ('3', '6'), {'test': '36'})
(3, ('3', '6'), {'test': 'a, b, c'})
(3, ('3',), {'test': ['a', 'b', 'c'], 'max': '3'})
(3, ('3',), {'test': ["'a'", 'b', 'x=(c)'], 'max': '3'})
(3, (), {'test': 'x=fish(3)'})

Variables Details [hide private]

__version__

Value:
'0.2.2'                                                                
      

__revision__

Value:
'$Id: validate.py 123 2005-09-08 08:54:28Z fuzzyman $'                 
      

INTP_VER

Value:
(2, 4)                                                                 
      

StringTypes

Value:
(<type 'str'>, <type 'unicode'>)                                       
      

_list_arg

Value:
(?:([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*list\(((?:\s*(?:(?:".*?")|(?:'.*?')|\
(?:[^'",\s\)][^,\)]*?))\s*,\s*)*(?:(?:".*?")|(?:'.*?')|(?:[^'",\s\)][^\
,\)]*?))?)\))                                                          
      

_list_members

Value:
((?:".*?")|(?:'.*?')|(?:[^'",\s=][^,=]*?))(?:(?:\s*,\s*)|(?:\s*$))     
      

_paramstring

Value:
'''
    (?:
        (
            (?:
                [a-zA-Z_][a-zA-Z0-9_]*\\s*=\\s*list\\(
                    (?:
                        \\s*
                        (?:
...                                                                    
      

_matchstring

Value:
'''^
    (?:
        (
            (?:
                [a-zA-Z_][a-zA-Z0-9_]*\\s*=\\s*list\\(
                    (?:
                        \\s*
                        (?:
...                                                                    
      

bool_dict

Value:
{False: False,
 True: True,
 '0': False,
 '1': True,
 'false': False,
 'no': False,
 'off': False,
 'on': True,
...                                                                    
      

fun_dict

Value:
{'boolean': <function is_bool at 0x00DC07B0>,
 'float': <function is_float at 0x00DC0770>,
 'integer': <function is_integer at 0x00DC0730>,
 'ip_addr': <function is_ip_addr at 0x00DC07F0>,
 'string': <function is_string at 0x00DC0870>}                         
      

m

Value:
sys.modules.get('__main__')                                            
      

globs

Value:
m.__dict__.copy()