def trace(func):
    name = func.func_name
    def substitute(*posargs, **kwargs):
        print ("Calling %s with args=%s and kwargs=%r ..."
               % (name, posargs, kwargs))
        return func(*posargs, **kwargs)
    return substitute


if __name__ == '__main__':

    @trace
    def factorial(n):
        if n == 0:
            return 1
        else:
            return n*factorial(n-1)

    factorial(5)

