def declare_types(**types):
    "\n    Decorator to declare argument and result types for a function\n\n    Usage is similar to `check_units` except that types must be one of ``{VALID_ARG_TYPES}``\n    and the result type must be one of ``{VALID_RETURN_TYPES}``. Unspecified argument\n    types are assumed to be ``'all'`` (i.e. anything is permitted), and an unspecified\n    result type is assumed to be ``'float'``. Note that the ``'highest'`` option for\n    result type will give the highest type of its argument, e.g. if the arguments\n    were boolean and integer then the result would be integer, if the arguments were\n    integer and float it would be float.\n    "

    def annotate_function_with_types(f):
        if hasattr(f, '_orig_arg_names'):
            arg_names = f._orig_arg_names
        else:
            arg_names = f.__code__.co_varnames[0:f.__code__.co_argcount]
        argtypes = []
        for name in arg_names:
            arg_type = types.get(name, 'any')
            if (arg_type not in VALID_ARG_TYPES):
                raise ValueError(('Argument type %s is not valid, must be one of %s, for argument %s' % (arg_type, VALID_ARG_TYPES, name)))
            argtypes.append(arg_type)
        for n in types:
            if ((n not in arg_names) and (n != 'result')):
                raise ValueError(('Type specified for unknown argument ' + n))
        return_type = types.get('result', 'float')
        if (return_type not in VALID_RETURN_TYPES):
            raise ValueError(('Result type %s is not valid, must be one of %s' % (return_type, VALID_RETURN_TYPES)))
        f._arg_types = argtypes
        f._return_type = return_type
        f._orig_arg_names = arg_names
        f._annotation_attributes = (getattr(f, '_annotation_attributes', []) + ['_arg_types', '_return_type'])
        return f
    return annotate_function_with_types
Decorator to declare argument and result types for a function

Usage is similar to `check_units` except that types must be one of ``{VALID_ARG_TYPES}``
and the result type must be one of ``{VALID_RETURN_TYPES}``. Unspecified argument
types are assumed to be ``'all'`` (i.e. anything is permitted), and an unspecified
result type is assumed to be ``'float'``. Note that the ``'highest'`` option for
result type will give the highest type of its argument, e.g. if the arguments
were boolean and integer then the result would be integer, if the arguments were
integer and float it would be float.
def declare_types(**types):
    "\n    Decorator to declare argument and result types for a function\n\n    Usage is similar to `check_units` except that types must be one of ``{VALID_ARG_TYPES}``\n    and the result type must be one of ``{VALID_RETURN_TYPES}``. Unspecified argument\n    types are assumed to be ``'all'`` (i.e. anything is permitted), and an unspecified\n    result type is assumed to be ``'float'``. Note that the ``'highest'`` option for\n    result type will give the highest type of its argument, e.g. if the arguments\n    were boolean and integer then the result would be integer, if the arguments were\n    integer and float it would be float.\n    "

    def annotate_function_with_types(f):
        if hasattr(f, '_orig_arg_names'):
            arg_names = f._orig_arg_names
        else:
            arg_names = f.__code__.co_varnames[0:f.__code__.co_argcount]
        argtypes = []
        for name in arg_names:
            arg_type = types.get(name, 'any')
            if (arg_type not in VALID_ARG_TYPES):
                raise ValueError(('Argument type %s is not valid, must be one of %s, for argument %s' % (arg_type, VALID_ARG_TYPES, name)))
            argtypes.append(arg_type)
        for n in types:
            if ((n not in arg_names) and (n != 'result')):
                raise ValueError(('Type specified for unknown argument ' + n))
        return_type = types.get('result', 'float')
        if (return_type not in VALID_RETURN_TYPES):
            raise ValueError(('Result type %s is not valid, must be one of %s' % (return_type, VALID_RETURN_TYPES)))
        f._arg_types = argtypes
        f._return_type = return_type
        f._orig_arg_names = arg_names
        f._annotation_attributes = (getattr(f, '_annotation_attributes', []) + ['_arg_types', '_return_type'])
        return f
    return annotate_function_with_types