Search code examples
pythonpython-decorators

Python decorator runs during import before function is called


I'm trying to use a decorator check_wake_server to check if a remote host is available before before executing a host_function that interacts with that host. The issue I'm hitting is that the decorator fires off immediately during import before host_function is ever called.

Both check_wake_server and host_function are top level functions in a file called foo.py which doesn't have a main function.

# foo.py

import functools

def check_wake_server(func):
    @functools.wraps(func)
    def host_wrapper(func):
        return func(*args, **kwargs)

    print('Decoration is happening!')  
    # check/wake server logic goes here
    return host_wrapper


@check_wake_server
def host_function(*args, **kwargs):
    # this does nothing
    pass

When I fire up my interpreter I get the following:

[1] from foo import host_function

Decoration is happening!

check_wake_server takes a minute to complete so I want to structure this so check_wake_server is only run if host_function gets called. Ideally I'd also use a decorator so I can re-use this for multiple functions that interact with the remote host.


Solution

  • @Nickolay 's comment got me to the desired behavior:

    If I want something to execute only when the decorated function is invoked the code needs to be placed within the wrapper.

    So the solution is:

    def check_wake_server(func):
        @functools.wraps(func)
        def host_wrapper(func):
            # check/wake server logic goes here
            print('Decoration is happening!')
            return func(*args, **kwargs)  
        return host_wrapper