Source code for validator_collection.checkers

# -*- coding: utf-8 -*-

# The lack of a module docstring for this module is **INTENTIONAL**.
# The module is imported into the documentation using Sphinx's autodoc
# extension, and its member function documentation is automatically incorporated
# there as needed.

# pylint: disable=W0703

import io

import validator_collection.validators as validators
from validator_collection._compat import integer_types, basestring


## CORE

[docs]def is_type(obj, type_): """Indicate if ``obj`` is a type in ``type_``. .. hint:: This checker is particularly useful when you want to evaluate whether ``obj`` is of a particular type, but importing that type directly to use in :func:`isinstance() <python:isinstance>` would cause a circular import error. To use this checker in that kind of situation, you can instead pass the *name* of the type you want to check as a string in ``type_``. The checker will evaluate it and see whether ``obj`` is of a type or inherits from a type whose name matches the string you passed. :param obj: The object whose type should be checked. :type obj: :class:`object <python:object>` :param type_: The type(s) to check against. :type type_: :class:`type <python:type>` / iterable of :class:`type <python:type>` / :class:`str <python:str>` with type name / iterable of :class:`str <python:str>` with type name :returns: ``True`` if ``obj`` is a type in ``type_``. Otherwise, ``False``. :rtype: :class:`bool <python:bool>` """ if not is_iterable(type_): type_ = [type_] return_value = False for check_for_type in type_: if isinstance(check_for_type, type): return_value = isinstance(obj, check_for_type) elif obj.__class__.__name__ == check_for_type: return_value = True else: return_value = _check_base_classes(obj.__class__.__bases__, check_for_type) if return_value is True: break return return_value
def _check_base_classes(base_classes, check_for_type): """Indicate whether ``check_for_type`` exists in ``base_classes``. """ return_value = False for base in base_classes: if base.__name__ == check_for_type: return_value = True break else: return_value = _check_base_classes(base.__bases__, check_for_type) if return_value is True: break return return_value
[docs]def are_equivalent(*args): """Indicate if arguments passed to this function are equivalent. .. hint:: This checker operates recursively on the members contained within iterables and :class:`dict <python:dict>` objects. .. caution:: If you only pass one argument to this checker - even if it is an iterable - the checker will *always* return ``True``. To evaluate members of an iterable for equivalence, you should instead unpack the iterable into the function like so: .. code-block:: python obj = [1, 1, 1, 2] result = are_equivalent(*obj) # Will return ``False`` by unpacking and evaluating the iterable's members result = are_equivalent(obj) # Will always return True :param args: One or more values, passed as positional arguments. :returns: ``True`` if ``args`` are equivalent, and ``False`` if not. :rtype: :class:`bool <python:bool>` """ if len(args) == 1: return True first_item = args[0] for item in args[1:]: if type(item) != type(first_item): # pylint: disable=C0123 return False if isinstance(item, dict): if not are_dicts_equivalent(item, first_item): return False elif hasattr(item, '__iter__') and not isinstance(item, (str, bytes, dict)): if len(item) != len(first_item): return False for value in item: if value not in first_item: return False for value in first_item: if value not in item: return False else: if item != first_item: return False return True
[docs]def are_dicts_equivalent(*args): """Indicate if :ref:`dicts <python:dict>` passed to this function have identical keys and values. :param args: One or more values, passed as positional arguments. :returns: ``True`` if ``args`` have identical keys/values, and ``False`` if not. :rtype: :class:`bool <python:bool>` """ # pylint: disable=too-many-return-statements if not args: return False if len(args) == 1: return True if not all(is_dict(x) for x in args): return False first_item = args[0] for item in args[1:]: if len(item) != len(first_item): return False for key in item: if key not in first_item: print('key not in first item') return False if not are_equivalent(item[key], first_item[key]): print(item[key]) print(first_item[key]) return False for key in first_item: if key not in item: return False if not are_equivalent(first_item[key], item[key]): return False return True
[docs]def is_between(value, minimum = None, maximum = None): """Indicate whether ``value`` is greater than or equal to a supplied ``minimum`` and/or less than or equal to ``maximum``. .. note:: This function works on any ``value`` that support comparison operators, whether they are numbers or not. Technically, this means that ``value``, ``minimum``, or ``maximum`` need to implement the Python magic methods :func:`__lte__ <python:object.__lte__>` and :func:`__gte__ <python:object.__gte__>`. If ``value``, ``minimum``, or ``maximum`` do not support comparison operators, they will raise :class:`NotImplemented <python:NotImplemented>`. :param value: The ``value`` to check. :type value: anything that supports comparison operators :param minimum: If supplied, will return ``True`` if ``value`` is greater than or equal to this value. :type minimum: anything that supports comparison operators / :class:`None <python:None>` :param maximum: If supplied, will return ``True`` if ``value`` is less than or equal to this value. :type maximum: anything that supports comparison operators / :class:`None <python:None>` :returns: ``True`` if ``value`` is greater than or equal to a supplied ``minimum`` and less than or equal to a supplied ``maximum``. Otherwise, returns ``False``. :rtype: :class:`bool <python:bool>` :raises NotImplemented: if ``value``, ``minimum``, or ``maximum`` do not support comparison operators :raises ValueError: if both ``minimum`` and ``maximum`` are :class:`None <python:None>` """ if minimum is None and maximum is None: raise ValueError('minimum and maximum cannot both be None') if value is None: return False if minimum is not None and maximum is None: return value >= minimum elif minimum is None and maximum is not None: return value <= maximum elif minimum is not None and maximum is not None: return value >= minimum and value <= maximum
[docs]def has_length(value, minimum = None, maximum = None): """Indicate whether ``value`` has a length greater than or equal to a supplied ``minimum`` and/or less than or equal to ``maximum``. .. note:: This function works on any ``value`` that supports the :func:`len() <python:len>` operation. This means that ``value`` must implement the :func:`__len__ <python:__len__>` magic method. If ``value`` does not support length evaluation, the checker will raise :class:`NotImplemented <python:NotImplemented>`. :param value: The ``value`` to check. :type value: anything that supports length evaluation :param minimum: If supplied, will return ``True`` if ``value`` is greater than or equal to this value. :type minimum: numeric :param maximum: If supplied, will return ``True`` if ``value`` is less than or equal to this value. :type maximum: numeric :returns: ``True`` if ``value`` has length greater than or equal to a supplied ``minimum`` and less than or equal to a supplied ``maximum``. Otherwise, returns ``False``. :rtype: :class:`bool <python:bool>` :raises TypeError: if ``value`` does not support length evaluation :raises ValueError: if both ``minimum`` and ``maximum`` are :class:`None <python:None>` """ if minimum is None and maximum is None: raise ValueError('minimum and maximum cannot both be None') length = len(value) minimum = validators.numeric(minimum, allow_empty = True) maximum = validators.numeric(maximum, allow_empty = True) return is_between(length, minimum = minimum, maximum = maximum)
[docs]def is_dict(value): """Indicate whether ``value`` is a valid :class:`dict <python:dict>` .. note:: This will return ``True`` even if ``value`` is an empty :class:`dict <python:dict>`. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ if isinstance(value, dict): return True try: value = validators.dict(value) except Exception: return False return True
[docs]def is_string(value, coerce_value = False, minimum_length = None, maximum_length = None, whitespace_padding = False): """Indicate whether ``value`` is a string. :param value: The value to evaluate. :param coerce_value: If ``True``, will check whether ``value`` can be coerced to a string if it is not already. Defaults to ``False``. :type coerce_value: :class:`bool <python:bool>` :param minimum_length: If supplied, indicates the minimum number of characters needed to be valid. :type minimum_length: :class:`int <python:int>` :param maximum_length: If supplied, indicates the minimum number of characters needed to be valid. :type maximum_length: :class:`int <python:int>` :param whitespace_padding: If ``True`` and the value is below the ``minimum_length``, pad the value with spaces. Defaults to ``False``. :type whitespace_padding: :class:`bool <python:bool>` :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ if value is None: return False minimum_length = validators.integer(minimum_length, allow_empty = True) maximum_length = validators.integer(maximum_length, allow_empty = True) if isinstance(value, basestring) and not value: if minimum_length and minimum_length > 0 and not whitespace_padding: return False return True try: value = validators.string(value, coerce_value = coerce_value, minimum_length = minimum_length, maximum_length = maximum_length, whitespace_padding = whitespace_padding) except Exception: return False return True
[docs]def is_iterable(obj, forbid_literals = (str, bytes), minimum_length = None, maximum_length = None): """Indicate whether ``obj`` is iterable. :param forbid_literals: A collection of literals that will be considered invalid even if they are (actually) iterable. Defaults to a :class:`tuple <python:tuple>` containing :class:`str <python:str>` and :class:`bytes <python:bytes>`. :type forbid_literals: iterable :param minimum_length: If supplied, indicates the minimum number of members needed to be valid. :type minimum_length: :class:`int <python:int>` :param maximum_length: If supplied, indicates the minimum number of members needed to be valid. :type maximum_length: :class:`int <python:int>` :returns: ``True`` if ``obj`` is a valid iterable, ``False`` if not. :rtype: :class:`bool <python:bool>` """ if obj is None: return False if obj in forbid_literals: return False try: obj = validators.iterable(obj, allow_empty = True, forbid_literals = forbid_literals, minimum_length = minimum_length, maximum_length = maximum_length) except Exception: return False return True
[docs]def is_not_empty(value): """Indicate whether ``value`` is empty. :param value: The value to evaluate. :returns: ``True`` if ``value`` is empty, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.not_empty(value) except Exception: return False return True
[docs]def is_none(value, allow_empty = False): """Indicate whether ``value`` is :class:`None <python:None>`. :param value: The value to evaluate. :param allow_empty: If ``True``, accepts falsey values as equivalent to :class:`None <python:None>`. Defaults to ``False``. :type allow_empty: :class:`bool <python:bool>` :returns: ``True`` if ``value`` is :class:`None <python:None>`, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: validators.none(value, allow_empty = allow_empty) except Exception: return False return True
[docs]def is_variable_name(value): """Indicate whether ``value`` is a valid Python variable name. .. caution:: This function does **NOT** check whether the variable exists. It only checks that the ``value`` would work as a Python variable (or class, or function, etc.) name. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: validators.variable_name(value) except Exception: return False return True
[docs]def is_callable(value): """Indicate whether ``value`` is callable (like a function, method, or class). :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ return hasattr(value, '__call__')
[docs]def is_uuid(value): """Indicate whether ``value`` contains a :class:`UUID <python:uuid.UUID>` :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: validators.uuid(value) except Exception: return False return True
## DATE / TIME
[docs]def is_date(value, minimum = None, maximum = None): """Indicate whether ``value`` is a :class:`date <python:datetime.date>`. :param value: The value to evaluate. :param minimum: If supplied, will make sure that ``value`` is on or after this value. :type minimum: :class:`datetime <python:datetime.datetime>` / :class:`date <python:datetime.date>` / compliant :class:`str <python:str>` / :class:`None <python:None>` :param maximum: If supplied, will make sure that ``value`` is on or before this value. :type maximum: :class:`datetime <python:datetime.datetime>` / :class:`date <python:datetime.date>` / compliant :class:`str <python:str>` / :class:`None <python:None>` :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.date(value, minimum = minimum, maximum = maximum) except Exception: return False return True
[docs]def is_datetime(value, minimum = None, maximum = None): """Indicate whether ``value`` is a :class:`datetime <python:datetime.datetime>`. :param value: The value to evaluate. :param minimum: If supplied, will make sure that ``value`` is on or after this value. :type minimum: :class:`datetime <python:datetime.datetime>` / :class:`date <python:datetime.date>` / compliant :class:`str <python:str>` / :class:`None <python:None>` :param maximum: If supplied, will make sure that ``value`` is on or before this value. :type maximum: :class:`datetime <python:datetime.datetime>` / :class:`date <python:datetime.date>` / compliant :class:`str <python:str>` / :class:`None <python:None>` :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.datetime(value, minimum = minimum, maximum = maximum) except Exception: return False return True
[docs]def is_time(value, minimum = None, maximum = None): """Indicate whether ``value`` is a :class:`time <python:datetime.time>`. :param value: The value to evaluate. :param minimum: If supplied, will make sure that ``value`` is on or after this value. :type minimum: :func:`datetime <validator_collection.validators.datetime>` or :func:`time <validator_collection.validators.time>`-compliant :class:`str <python:str>` / :class:`datetime <python:datetime.datetime>` / :class:`time <python:datetime.time> / numeric / :class:`None <python:None>` :param maximum: If supplied, will make sure that ``value`` is on or before this value. :type maximum: :func:`datetime <validator_collection.validators.datetime>` or :func:`time <validator_collection.validators.time>`-compliant :class:`str <python:str>` / :class:`datetime <python:datetime.datetime>` / :class:`time <python:datetime.time> / numeric / :class:`None <python:None>` :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.time(value, minimum = minimum, maximum = maximum) except Exception: return False return True
[docs]def is_timezone(value, positive = True): """Indicate whether ``value`` is a :class:`tzinfo <python:datetime.tzinfo>`. .. caution:: This does **not** validate whether the value is a timezone that actually exists, nor can it resolve timzone names (e.g. ``'Eastern'`` or ``'CET'``). For that kind of functionality, we recommend you utilize: `pytz <https://pypi.python.org/pypi/pytz>`_ :param value: The value to evaluate. :param positive: Indicates whether the ``value`` is positive or negative (only has meaning if ``value`` is a string). Defaults to ``True``. :type positive: :class:`bool <python:bool>` :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.timezone(value, positive = positive) except Exception: return False return True
## NUMBERS
[docs]def is_numeric(value, minimum = None, maximum = None): """Indicate whether ``value`` is a numeric value. :param value: The value to evaluate. :param minimum: If supplied, will make sure that ``value`` is greater than or equal to this value. :type minimum: numeric :param maximum: If supplied, will make sure that ``value`` is less than or equal to this value. :type maximum: numeric :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.numeric(value, minimum = minimum, maximum = maximum) except Exception: return False return True
[docs]def is_integer(value, coerce_value = False, minimum = None, maximum = None, base = 10): """Indicate whether ``value`` contains a whole number. :param value: The value to evaluate. :param coerce_value: If ``True``, will return ``True`` if ``value`` can be coerced to whole number. If ``False``, will only return ``True`` if ``value`` is already a whole number (regardless of type). Defaults to ``False``. :type coerce_value: :class:`bool <python:bool>` :param minimum: If supplied, will make sure that ``value`` is greater than or equal to this value. :type minimum: numeric :param maximum: If supplied, will make sure that ``value`` is less than or equal to this value. :type maximum: numeric :param base: Indicates the base that is used to determine the integer value. The allowed values are 0 and 2–36. Base-2, -8, and -16 literals can be optionally prefixed with ``0b/0B``, ``0o/0O/0``, or ``0x/0X``, as with integer literals in code. Base 0 means to interpret the string exactly as an integer literal, so that the actual base is 2, 8, 10, or 16. Defaults to ``10``. :type base: :class:`int <python:int>` :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.integer(value, coerce_value = coerce_value, minimum = minimum, maximum = maximum, base = base) except Exception: return False return True
[docs]def is_float(value, minimum = None, maximum = None): """Indicate whether ``value`` is a :class:`float <python:float>`. :param value: The value to evaluate. :param minimum: If supplied, will make sure that ``value`` is greater than or equal to this value. :type minimum: numeric :param maximum: If supplied, will make sure that ``value`` is less than or equal to this value. :type maximum: numeric :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.float(value, minimum = minimum, maximum = maximum) except Exception: return False return True
[docs]def is_fraction(value, minimum = None, maximum = None): """Indicate whether ``value`` is a :class:`Fraction <python:fractions.Fraction>`. :param value: The value to evaluate. :param minimum: If supplied, will make sure that ``value`` is greater than or equal to this value. :type minimum: numeric :param maximum: If supplied, will make sure that ``value`` is less than or equal to this value. :type maximum: numeric :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.fraction(value, minimum = minimum, maximum = maximum) except Exception: return False return True
[docs]def is_decimal(value, minimum = None, maximum = None): """Indicate whether ``value`` contains a :class:`Decimal <python:decimal.Decimal>`. :param value: The value to evaluate. :param minimum: If supplied, will make sure that ``value`` is greater than or equal to this value. :type minimum: numeric :param maximum: If supplied, will make sure that ``value`` is less than or equal to this value. :type maximum: numeric :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.decimal(value, minimum = minimum, maximum = maximum) except Exception: return False return True
## FILE-RELATED
[docs]def is_bytesIO(value): """Indicate whether ``value`` is a :class:`BytesIO <python:io.BytesIO>` object. .. note:: This checker will return ``True`` even if ``value`` is empty, so long as its type is a :class:`BytesIO <python:io.BytesIO>`. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ return isinstance(value, io.BytesIO)
[docs]def is_stringIO(value): """Indicate whether ``value`` is a :class:`StringIO <python:io.StringIO>` object. .. note:: This checker will return ``True`` even if ``value`` is empty, so long as its type is a :class:`String <python:io.StringIO>`. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ return isinstance(value, io.StringIO)
[docs]def is_pathlike(value): """Indicate whether ``value`` is a path-like object. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.path(value) except Exception: return False return True
[docs]def is_on_filesystem(value): """Indicate whether ``value`` is a file or directory that exists on the local filesystem. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.path_exists(value) except Exception: return False return True
[docs]def is_file(value): """Indicate whether ``value`` is a file that exists on the local filesystem. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.file_exists(value) except Exception: return False return True
[docs]def is_directory(value): """Indicate whether ``value`` is a directory that exists on the local filesystem. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.directory_exists(value) except Exception: return False return True
## INTERNET-RELATED
[docs]def is_email(value): """Indicate whether ``value`` is an email address. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.email(value) except Exception: return False return True
[docs]def is_url(value): """Indicate whether ``value`` is a URL. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.url(value) except Exception: return False return True
[docs]def is_ip_address(value): """Indicate whether ``value`` is a valid IP address (version 4 or version 6). :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.ip_address(value) except Exception: return False return True
[docs]def is_ipv4(value): """Indicate whether ``value`` is a valid IP version 4 address. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.ipv4(value) except Exception: return False return True
[docs]def is_ipv6(value): """Indicate whether ``value`` is a valid IP version 6 address. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.ipv6(value) except Exception: return False return True
[docs]def is_mac_address(value): """Indicate whether ``value`` is a valid MAC address. :param value: The value to evaluate. :returns: ``True`` if ``value`` is valid, ``False`` if it is not. :rtype: :class:`bool <python:bool>` """ try: value = validators.mac_address(value) except Exception: return False return True