Source code for staticconf.validation

"""
Validate a configuration value by converting it to a specific type.

These functions are used by :mod:`staticconf.readers` and
:mod:`staticconf.schema` to coerce config values to a type.
"""
import datetime
import logging
import re
import time

import six

from staticconf.errors import ValidationError


[docs]def validate_string(value): return None if value is None else six.text_type(value)
[docs]def validate_bool(value): return None if value is None else bool(value)
[docs]def validate_numeric(type_func, value): try: return type_func(value) except ValueError: raise ValidationError("Invalid %s: %s" % (type_func.__name__, value))
[docs]def validate_int(value): return validate_numeric(int, value)
[docs]def validate_float(value): return validate_numeric(float, value)
date_formats = [ "%Y-%m-%d %H:%M:%S", "%Y-%m-%d %I:%M:%S %p", "%Y-%m-%d", "%y-%m-%d", "%m/%d/%y", "%m/%d/%Y", ]
[docs]def validate_datetime(value): if isinstance(value, datetime.datetime): return value for format_ in date_formats: try: return datetime.datetime.strptime(value, format_) except ValueError: pass raise ValidationError("Invalid date format: %s" % value)
[docs]def validate_date(value): if isinstance(value, datetime.date): return value return validate_datetime(value).date()
time_formats = [ "%I %p", "%H:%M", "%I:%M %p", "%H:%M:%S", "%I:%M:%S %p" ]
[docs]def validate_time(value): if isinstance(value, datetime.time): return value for format_ in time_formats: try: return datetime.time(*time.strptime(value, format_)[3:6]) except ValueError: pass raise ValidationError("Invalid time format: %s" % value)
def _validate_iterable(iterable_type, value): """Convert the iterable to iterable_type, or raise a Configuration exception. """ if isinstance(value, six.string_types): msg = "Invalid iterable of type(%s): %s" raise ValidationError(msg % (type(value), value)) try: return iterable_type(value) except TypeError: raise ValidationError("Invalid iterable: %s" % (value))
[docs]def validate_list(value): return _validate_iterable(list, value)
[docs]def validate_set(value): return _validate_iterable(set, value)
[docs]def validate_tuple(value): return _validate_iterable(tuple, value)
[docs]def validate_regex(value): try: return re.compile(value) except (re.error, TypeError) as e: raise ValidationError("Invalid regex: %s, %s" % (e, value))
[docs]def build_list_type_validator(item_validator): """Return a function which validates that the value is a list of items which are validated using item_validator. """ def validate_list_of_type(value): return [item_validator(item) for item in validate_list(value)] return validate_list_of_type
[docs]def build_map_type_validator(item_validator): """Return a function which validates that the value is a mapping of items. The function should return pairs of items that will be passed to the `dict` constructor. """ def validate_mapping(value): return dict(item_validator(item) for item in validate_list(value)) return validate_mapping
[docs]def validate_log_level(value): """Validate a log level from a string value. Returns a constant from the :mod:`logging` module. """ try: return getattr(logging, value) except AttributeError: raise ValidationError("Unknown log level: %s" % value)
[docs]def validate_any(value): return value
validators = { '': validate_any, 'bool': validate_bool, 'date': validate_date, 'datetime': validate_datetime, 'float': validate_float, 'int': validate_int, 'list': validate_list, 'set': validate_set, 'string': validate_string, 'time': validate_time, 'tuple': validate_tuple, 'regex': validate_regex, 'log_level': validate_log_level, }
[docs]def get_validators(): """Return an iterator of (validator_name, validator) pairs.""" return six.iteritems(validators)