def fraction(value,
             allow_empty = False,
             minimum = None,
             maximum = None,
             **kwargs):
    """Validate that ``value`` is a :class:`Fraction <python:fractions.Fraction>`.

    :param value: The value to validate.

    :param allow_empty: If ``True``, returns :obj:`None <python:None>` if ``value``
      is :obj:`None <python:None>`. If  ``False``, raises a
      :class:`EmptyValueError <validator_collection.errors.EmptyValueError>` if
      ``value`` is :obj:`None <python:None>`. Defaults to ``False``.
    :type allow_empty: :class:`bool <python:bool>`

    :returns: ``value`` / :obj:`None <python:None>`
    :rtype: :class:`Fraction <python:fractions.Fraction>` / :obj:`None <python:None>`

    :raises EmptyValueError: if ``value`` is :obj:`None <python:None>` and
      ``allow_empty`` is ``False``
    :raises MinimumValueError: if ``minimum`` is supplied and ``value`` is less
      than the ``minimum``
    :raises MaximumValueError: if ``maximum`` is supplied and ``value`` is more
      than the ``maximum``
    :raises CannotCoerceError: if unable to coerce ``value`` to a
      :class:`Fraction <python:fractions.Fraction>`

    """
    try:
        value = _numeric_coercion(value,
                                  coercion_function = fractions.Fraction,
                                  allow_empty = allow_empty,
                                  minimum = minimum,
                                  maximum = maximum)
    except (errors.EmptyValueError,
            errors.CannotCoerceError,
            errors.MinimumValueError,
            errors.MaximumValueError) as error:
        raise error
    except Exception as error:
        raise errors.CannotCoerceError('unable to coerce value (%s) to Fraction, '
                                       'for an unknown reason - please see '
                                       'stack trace' % value)

    return value
Validate that ``value`` is a :class:`Fraction <python:fractions.Fraction>`.

    :param value: The value to validate.

    :param allow_empty: If ``True``, returns :obj:`None <python:None>` if ``value``
      is :obj:`None <python:None>`. If  ``False``, raises a
      :class:`EmptyValueError <validator_collection.errors.EmptyValueError>` if
      ``value`` is :obj:`None <python:None>`. Defaults to ``False``.
    :type allow_empty: :class:`bool <python:bool>`

    :returns: ``value`` / :obj:`None <python:None>`
    :rtype: :class:`Fraction <python:fractions.Fraction>` / :obj:`None <python:None>`

    :raises EmptyValueError: if ``value`` is :obj:`None <python:None>` and
      ``allow_empty`` is ``False``
    :raises MinimumValueError: if ``minimum`` is supplied and ``value`` is less
      than the ``minimum``
    :raises MaximumValueError: if ``maximum`` is supplied and ``value`` is more
      than the ``maximum``
    :raises CannotCoerceError: if unable to coerce ``value`` to a
      :class:`Fraction <python:fractions.Fraction>`