How do I clean up these Python decorators? I wrote some type checking decorators for Python. One checks the type that a function returns, the other checks the type that a function accepts.

import functools

def returns(t):
""" Calls a function, and if it returns something of the wrong type,
    throws a TypeError
"""
    def outer(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            output = func(*args, **kwargs)
            if not isinstance(output, t):
                message = "function {} returned an invalid type: {} is a {}"
                raise TypeError(message.format(func.__name__,
                                               output,
                                               type(output)))
            else:
                return output
        return wrapper
    return outer

class accepts:
    def __init__(self, *artypes, **kwtypes):
        """ Pass it a list consisting of types or tuples of types.
        in other words, pass it things that will be valid second
        arguments to the isinstance(arg, type) method.
        """
        self.artypes = artypes
        self.kwtypes = kwtypes

    def checkTypes(self, args, kwargs):
        """ Checks each arg and kwarg for type validity, and if
            they fail, then it throws a TypeError. Not very descriptive,
            but it's just an example.
        """
        type_zip = zip(args, self.artypes)
        for arg, type_ in type_zip:
            if not isinstance(arg, type_):
                raise ValueError()

        for key, value in kwargs.items():
            if not isinstance(value, self.kwtypes[key]):
                raise ValueError()

    def __call__(self, func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            self.checkTypes(args, kwargs)
            return func(*args, **kwargs)
        return wrapper

@accepts(int)
def hitimes(times=1):
    return "hello " * times


@accepts(int, word=str)
def byetimes(times, word="bye"):
    return " ".join([word] * times)

print(hitimes(2)) # works
print(byetimes(5)) # works
print(byetimes(3, word="adios")) # works as expected
print(byetimes(3, word=[])) # fails as expected


For returns, I used nested functions, and for accepts I used the class style of decorator. But both of them get pretty unwieldy with respect to indentation levels. What can I do to make these cleaner?

Note that the wrappers are themselves pretty pointless.
I agree with @minitech that accepts shouldn't be a class. It can be written much more compactly using a nested decorator (like returns, in fact):

def accepts(*artypes, **kwtypes):
    """
    Pass it a list consisting of types or tuples of types.
    in other words, pass it things that will be valid second
    arguments to the isinstance(arg, type) method.
    """
    def outer(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            type_zip = zip(args, artypes)
            for arg, type_ in type_zip:
                if not isinstance(arg, type_):
                    raise ValueError()

            for key, value in kwargs.items():
                if not isinstance(value, kwtypes[key]):
                    raise ValueError()
            return func(*args, **kwargs)
        return wrapper
    return accepts_wrapper


This then works equivalently to returns, and is much shorter (as you need less variable-passing code).