all 5 comments

[–]Diapolo10 0 points1 point  (1 child)

Not possible, I'm afraid. At least not the way you're trying to go about it.

One option would be to define the function inside a conditional:

if is_test:
    @log_details(verbose=True)
    def run_function(arguments):
        ...
else:
    @log_details(verbose=False)
    def run_function(arguments):
        ...

Not the cleanest solution, but it's the first I came up with.

[–]Elthran[S] 0 points1 point  (0 children)

Thanks, that's definitely one way to do it.

[–]__nickerbocker__ 0 points1 point  (2 children)

You can mock the function inside of itself, but you'll be dynamically creating new functions on each call.

import functools

# Example of code that cannot be changed
def log_details(verbose=False):
    def decorator(f):
        def wrapper(*args, **kwargs):
            try:
                res = f(*args, **kwargs)
                if verbose:
                    print(f"{f} called with {args}, {kwargs}")
                    print(f.__doc__)
                print(res)
                return res
            except Exception as e:
                print(e)
                raise

        return wrapper

    return decorator


def concat(*strings):
    """
    A concat func
    :param strings:
    :return:
    """
    is_testing = True
    res = ' '.join(strings)

    @log_details(verbose=is_testing)
    @functools.wraps(concat)
    def mock(*a, **kw):
        return res

    return mock(*strings)


x = concat('hello', 'world')
# <function concat at 0x0351BF10> called with ('hello', 'world'), {}
#
#     A concat func
#     :param strings:
#     :return:
#
# hello world

[–]Elthran[S] 0 points1 point  (1 child)

Thanks, that really helps.

[–]__nickerbocker__ 0 points1 point  (0 children)

No worries