Introspection to get decorator names on a method?

Viewed 25467

I am trying to figure out how to get the names of all decorators on a method. I can already get the method name and docstring, but cannot figure out how to get a list of decorators.

8 Answers

I've add the same question. In my unit tests I just wanted to make sure decorators were used by given functions/methods.

The decorators were tested separately so I didn't need to test the common logic for each decorated function, just that the decorators were used.

I finally came up with the following helper function:

import inspect

def get_decorators(function):
    """Returns list of decorators names

    Args:
        function (Callable): decorated method/function

    Return:
        List of decorators as strings

    Example:
        Given:

        @my_decorator
        @another_decorator
        def decorated_function():
            pass

        >>> get_decorators(decorated_function)
        ['@my_decorator', '@another_decorator']

    """
    source = inspect.getsource(function)
    index = source.find("def ")
    return [
        line.strip().split()[0]
        for line in source[:index].strip().splitlines()
        if line.strip()[0] == "@"
    ]

With the list comprehension, it is a bit "dense" but it does the trick and in my case it's a test helper function.

It works if you are intrested only in the decorators names, not potential decorator arguments. If you want to support decorators taking arguments, something like line.strip().split()[0].split("(")[0] could do the trick (untested)

Finally, you can remove the "@" if you'd like by replacing line.strip().split()[0] by line.strip().split()[0][1:]

Related