def timer(<EOL>logger=None,<EOL>level=logging.INFO,<EOL>fmt="<STR_LIT>",<EOL>*func_or_func_args,<EOL>**timer_kwargs,<EOL>):
<EOL>def wrapped_f(f):<EOL><INDENT>@functools.wraps(f)<EOL>def wrapped(*args, **kwargs):<EOL><INDENT>with Timer(**timer_kwargs) as t:<EOL><INDENT>out = f(*args, **kwargs)<EOL><DEDENT>context = {"<STR_LIT>": f.__name__, "<STR_LIT>": t.elapsed}<EOL>if logger:<EOL><INDENT>logger.log(level, fmt % context, extra=context)<EOL><DEDENT>else:<EOL><INDENT>print(fmt % context)<EOL><DEDENT>return out<EOL><DEDENT>return wrapped<EOL><DEDENT>if len(func_or_func_args) == <NUM_LIT:1> and isinstance(<EOL>func_or_func_args[<NUM_LIT:0>], collections.Callable<EOL>):<EOL><INDENT>return wrapped_f(func_or_func_args[<NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>return wrapped_f<EOL><DEDENT>
Function decorator displaying the function execution time
    All kwargs are the arguments taken by the Timer class constructor.