Blame tools/extra/packager/jsonschema-2.3.0/jsonschema/_format.py

Packit 534379
import datetime
Packit 534379
import re
Packit 534379
import socket
Packit 534379
Packit 534379
from jsonschema.compat import str_types
Packit 534379
from jsonschema.exceptions import FormatError
Packit 534379
Packit 534379
Packit 534379
class FormatChecker(object):
Packit 534379
    """
Packit 534379
    A ``format`` property checker.
Packit 534379
Packit 534379
    JSON Schema does not mandate that the ``format`` property actually do any
Packit 534379
    validation. If validation is desired however, instances of this class can
Packit 534379
    be hooked into validators to enable format validation.
Packit 534379
Packit 534379
    :class:`FormatChecker` objects always return ``True`` when asked about
Packit 534379
    formats that they do not know how to validate.
Packit 534379
Packit 534379
    To check a custom format using a function that takes an instance and
Packit 534379
    returns a ``bool``, use the :meth:`FormatChecker.checks` or
Packit 534379
    :meth:`FormatChecker.cls_checks` decorators.
Packit 534379
Packit 534379
    :argument iterable formats: the known formats to validate. This argument
Packit 534379
                                can be used to limit which formats will be used
Packit 534379
                                during validation.
Packit 534379
Packit 534379
    """
Packit 534379
Packit 534379
    checkers = {}
Packit 534379
Packit 534379
    def __init__(self, formats=None):
Packit 534379
        if formats is None:
Packit 534379
            self.checkers = self.checkers.copy()
Packit 534379
        else:
Packit 534379
            self.checkers = dict((k, self.checkers[k]) for k in formats)
Packit 534379
Packit 534379
    def checks(self, format, raises=()):
Packit 534379
        """
Packit 534379
        Register a decorated function as validating a new format.
Packit 534379
Packit 534379
        :argument str format: the format that the decorated function will check
Packit 534379
        :argument Exception raises: the exception(s) raised by the decorated
Packit 534379
            function when an invalid instance is found. The exception object
Packit 534379
            will be accessible as the :attr:`ValidationError.cause` attribute
Packit 534379
            of the resulting validation error.
Packit 534379
Packit 534379
        """
Packit 534379
Packit 534379
        def _checks(func):
Packit 534379
            self.checkers[format] = (func, raises)
Packit 534379
            return func
Packit 534379
        return _checks
Packit 534379
Packit 534379
    cls_checks = classmethod(checks)
Packit 534379
Packit 534379
    def check(self, instance, format):
Packit 534379
        """
Packit 534379
        Check whether the instance conforms to the given format.
Packit 534379
Packit 534379
        :argument instance: the instance to check
Packit 534379
        :type: any primitive type (str, number, bool)
Packit 534379
        :argument str format: the format that instance should conform to
Packit 534379
        :raises: :exc:`FormatError` if instance does not conform to format
Packit 534379
Packit 534379
        """
Packit 534379
Packit 534379
        if format not in self.checkers:
Packit 534379
            return
Packit 534379
Packit 534379
        func, raises = self.checkers[format]
Packit 534379
        result, cause = None, None
Packit 534379
        try:
Packit 534379
            result = func(instance)
Packit 534379
        except raises as e:
Packit 534379
            cause = e
Packit 534379
        if not result:
Packit 534379
            raise FormatError(
Packit 534379
                "%r is not a %r" % (instance, format), cause=cause,
Packit 534379
            )
Packit 534379
Packit 534379
    def conforms(self, instance, format):
Packit 534379
        """
Packit 534379
        Check whether the instance conforms to the given format.
Packit 534379
Packit 534379
        :argument instance: the instance to check
Packit 534379
        :type: any primitive type (str, number, bool)
Packit 534379
        :argument str format: the format that instance should conform to
Packit 534379
        :rtype: bool
Packit 534379
Packit 534379
        """
Packit 534379
Packit 534379
        try:
Packit 534379
            self.check(instance, format)
Packit 534379
        except FormatError:
Packit 534379
            return False
Packit 534379
        else:
Packit 534379
            return True
Packit 534379
Packit 534379
Packit 534379
_draft_checkers = {"draft3": [], "draft4": []}
Packit 534379
Packit 534379
Packit 534379
def _checks_drafts(both=None, draft3=None, draft4=None, raises=()):
Packit 534379
    draft3 = draft3 or both
Packit 534379
    draft4 = draft4 or both
Packit 534379
Packit 534379
    def wrap(func):
Packit 534379
        if draft3:
Packit 534379
            _draft_checkers["draft3"].append(draft3)
Packit 534379
            func = FormatChecker.cls_checks(draft3, raises)(func)
Packit 534379
        if draft4:
Packit 534379
            _draft_checkers["draft4"].append(draft4)
Packit 534379
            func = FormatChecker.cls_checks(draft4, raises)(func)
Packit 534379
        return func
Packit 534379
    return wrap
Packit 534379
Packit 534379
Packit 534379
@_checks_drafts("email")
Packit 534379
def is_email(instance):
Packit 534379
    if not isinstance(instance, str_types):
Packit 534379
        return True
Packit 534379
    return "@" in instance
Packit 534379
Packit 534379
Packit 534379
@_checks_drafts(draft3="ip-address", draft4="ipv4", raises=socket.error)
Packit 534379
def is_ipv4(instance):
Packit 534379
    if not isinstance(instance, str_types):
Packit 534379
        return True
Packit 534379
    return socket.inet_aton(instance)
Packit 534379
Packit 534379
Packit 534379
if hasattr(socket, "inet_pton"):
Packit 534379
    @_checks_drafts("ipv6", raises=socket.error)
Packit 534379
    def is_ipv6(instance):
Packit 534379
        if not isinstance(instance, str_types):
Packit 534379
            return True
Packit 534379
        return socket.inet_pton(socket.AF_INET6, instance)
Packit 534379
Packit 534379
Packit 534379
_host_name_re = re.compile(r"^[A-Za-z0-9][A-Za-z0-9\.\-]{1,255}$")
Packit 534379
Packit 534379
Packit 534379
@_checks_drafts(draft3="host-name", draft4="hostname")
Packit 534379
def is_host_name(instance):
Packit 534379
    if not isinstance(instance, str_types):
Packit 534379
        return True
Packit 534379
    if not _host_name_re.match(instance):
Packit 534379
        return False
Packit 534379
    components = instance.split(".")
Packit 534379
    for component in components:
Packit 534379
        if len(component) > 63:
Packit 534379
            return False
Packit 534379
    return True
Packit 534379
Packit 534379
Packit 534379
try:
Packit 534379
    import rfc3987
Packit 534379
except ImportError:
Packit 534379
    pass
Packit 534379
else:
Packit 534379
    @_checks_drafts("uri", raises=ValueError)
Packit 534379
    def is_uri(instance):
Packit 534379
        if not isinstance(instance, str_types):
Packit 534379
            return True
Packit 534379
        return rfc3987.parse(instance, rule="URI")
Packit 534379
Packit 534379
Packit 534379
try:
Packit 534379
    import strict_rfc3339
Packit 534379
except ImportError:
Packit 534379
    try:
Packit 534379
        import isodate
Packit 534379
    except ImportError:
Packit 534379
        pass
Packit 534379
    else:
Packit 534379
        @_checks_drafts("date-time", raises=(ValueError, isodate.ISO8601Error))
Packit 534379
        def is_date(instance):
Packit 534379
            if not isinstance(instance, str_types):
Packit 534379
                return True
Packit 534379
            return isodate.parse_datetime(instance)
Packit 534379
else:
Packit 534379
        @_checks_drafts("date-time")
Packit 534379
        def is_date(instance):
Packit 534379
            if not isinstance(instance, str_types):
Packit 534379
                return True
Packit 534379
            return strict_rfc3339.validate_rfc3339(instance)
Packit 534379
Packit 534379
Packit 534379
@_checks_drafts("regex", raises=re.error)
Packit 534379
def is_regex(instance):
Packit 534379
    if not isinstance(instance, str_types):
Packit 534379
        return True
Packit 534379
    return re.compile(instance)
Packit 534379
Packit 534379
Packit 534379
@_checks_drafts(draft3="date", raises=ValueError)
Packit 534379
def is_date(instance):
Packit 534379
    if not isinstance(instance, str_types):
Packit 534379
        return True
Packit 534379
    return datetime.datetime.strptime(instance, "%Y-%m-%d")
Packit 534379
Packit 534379
Packit 534379
@_checks_drafts(draft3="time", raises=ValueError)
Packit 534379
def is_time(instance):
Packit 534379
    if not isinstance(instance, str_types):
Packit 534379
        return True
Packit 534379
    return datetime.datetime.strptime(instance, "%H:%M:%S")
Packit 534379
Packit 534379
Packit 534379
try:
Packit 534379
    import webcolors
Packit 534379
except ImportError:
Packit 534379
    pass
Packit 534379
else:
Packit 534379
    def is_css_color_code(instance):
Packit 534379
        return webcolors.normalize_hex(instance)
Packit 534379
Packit 534379
    @_checks_drafts(draft3="color", raises=(ValueError, TypeError))
Packit 534379
    def is_css21_color(instance):
Packit 534379
        if (
Packit 534379
            not isinstance(instance, str_types) or
Packit 534379
            instance.lower() in webcolors.css21_names_to_hex
Packit 534379
        ):
Packit 534379
            return True
Packit 534379
        return is_css_color_code(instance)
Packit 534379
Packit 534379
    def is_css3_color(instance):
Packit 534379
        if instance.lower() in webcolors.css3_names_to_hex:
Packit 534379
            return True
Packit 534379
        return is_css_color_code(instance)
Packit 534379
Packit 534379
Packit 534379
draft3_format_checker = FormatChecker(_draft_checkers["draft3"])
Packit 534379
draft4_format_checker = FormatChecker(_draft_checkers["draft4"])