Prints value and then returns it. Useful to tap into some functional pipeline for debugging:

fields = (f for f in fields_for(category) if section in tap(tap(f).sections))
# ... do something with fields
@log_calls(print_func, errors=True)

Will log or print all function calls, including arguments, results and raised exceptions. Can be used as decorator or tapped into call expression:

sorted_fields = sorted(fields, key=print_calls(lambda f: f.order))

If errors is set to False then exceptions are not logged. This could be used to separate channels for normal and error logging:

@log_calls(, errors=False)
def some_suspicious_function(...):
    # ...

print_calls() always prints everything.


Will log or print all function errors providing function arguments causing them.

Can be combined with silent() or ignore() to trace occasionally misbehaving function:

def guess_user_id(username):
    initial = first_guess(username)
    # ...

Will time each function call and log or print its duration.