Python: wrapping recursive functions

higher-order-functions, python

Solution

It works if you use your wrapper function as a decorator.

def wrap(f):
    def wrapped(*args, **kwargs):
        print "f was called"
        return f(*args, **kwargs)

    return wrapped

@wrap
def foo(x):
    return foo(x - 1) if x > 0 else 1

Reason being that in your example, you're only calling the result of the `wrap` function once. If you use it as a decorator it actually replaces the definition of `foo` in the module namespace with the decorated function, so its internal call resolves to the wrapped version.

Problem

How can I wrap a recursive function, recursive calls included? For example, given `foo` and `wrap`: ``` def foo(x): return foo(x - 1) if x > 0 else 1 def wrap(f): def wrapped(*args, **kwargs): print "f was called" return f(*args, **kwargs) return wrapped ``` `wrap(foo)(x)` will only output `"f was called"` with the first call. Recursive calls still address `foo()`. I don't mind monkey patching, or poking around internals. I'm not planning to add this code to the next nuclear warhead handling program, so even if it's a bad idea, I'd like to achieve the effect. Edit: for example, would patching `foo.func_globals` to override `foo.__name__` work? If it always does, any side-effects I should be minding?

Original source