Search code examples
pythonpython-3.xmonkeypatching

Inject function calls into python function


Let's say I have some simple python function in a module

def f(x):
    print(x)

This function just prints its argument. However, I want to modify this function or class method, depending on what it actually is.

I have a second function:

def g(x):
    x.append(1)

which manipulates the input argument (probably a list) and appends some item. Now, I want to inject a call to g into f so that the latter would behave as

def f_patched(x):
    g(x)
    print(x)

Clearly, this can be done by monkey patching f. This however is not always practical, especially if f is some larger function as I would have to copy large portions of code (if this is even legal) just to change a single line. By injecting a call tog given some reference, for example "after line XXX" or "after instruction XXX" I could easily modify the behavior of f.

Is there a way to inject a function call into a different function? You can assume, that I know the source of f or at least that f is known well enough and unchanging for this to be possible.


Solution

  • Perhaps you could redefine the function early in the program (i.e. before it is first called) to replace it with your patched version:

    import myModule
    
    # before this f() is the original
    
    old_f = myModule.f           # capture a reference to the original
    def f_patched(x):
        g(x)                     # inject your code
        return old_f(x)          # use the original
    myModule.f = f_patched       # replace the original
    
    # from here onward, f() will be the patched version that calls the original