class TailCall(object):

    def __init__(self, __function__):
        self.__function__ = __function__
self.args = None
self.kwargs = None
self.has_params = False

def __call__(self, *args, **kwargs):
    self.args = args
self.kwargs = kwargs
self.has_params = True
return self

def __handle__(self):
    if not self.has_params:
        raise TypeError
if type(self.__function__) is TailCaller:
    return self.__function__.call(*self.args, **self.kwargs)
return self.__function__(*self.args, **self.kwargs)


class TailCaller(object):

    def __init__(self, call):
        self.call = call

def __call__(self, *args, **kwargs):
    ret = self.call(*args, **kwargs)
while type(ret) is TailCall:
    ret = ret.__handle__()
return ret

@TailCaller
def factorial(n, prev=1):
    if n < 2:
        return prev
return TailCall(factorial)(n - 1, n * prev)
How to eliminate recursion in Python function containing control flow