Search code examples
pythondecoratorpython-decorators

Get decorated function from within nested decorator


I'm trying to get the reference to the originally decorated function from within a decorator. How can this be done?

import inspect
from functools import wraps


def test_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # the closest I could get to getting the original function:
        # it prints the frame from which the function was called.
        current_frame = inspect.currentframe()
        outer_frames = inspect.getouterframes(current_frame)
        print(outer_frames[-1].frame)
        
        return func(*args, **kwargs)
    return wrapper


@test_decorator
@test_decorator
@test_decorator
def test_func(a, b, c):
    print("func")


test_func(1,2,3)

The 'originally decorated function' in this context would be test_func, since it's the target function we're decorating. I've looked through the inspect module, the closest I could get is by getting the first frame on the stack, but it doesn't help much.

Maybe, there is a solution already in stdlib?


Solution

  • This:

    https://github.com/micheles/decorator

    import inspect
    from decorator import decorator
    
    
    @decorator
    def test_decorator(func, *args, **kwargs):
        print(inspect.getfullargspec(func))
        return func(*args, **kwargs)
    
    
    @test_decorator
    @test_decorator
    @test_decorator
    def test_func(a, b, c):
        print("func")
    
    
    test_func(1,2,3)
    

    Now from within each test_decorator it prints:

    FullArgSpec(args=['a', 'b', 'c'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={})
    

    Bless this man who wrote the module, the guy is a legend.