user1633272
user1633272

Reputation: 2309

Python how to patch a function in another module and call it internally?

In original.py, it is not controlled by myself

def func():
    print("func")

Is there a way to patch original.func?

patch_original.py, it is controlled by myself

def patched_func():
    original.func()
    print("patched_func")

call.py

import original # can not change this
import patch_original


func()

I want to be able to print

func

patched_func


Update: original.py is not under my control.

patch_original.py is fully controllable.

call.py is partially under my control, it has already import original

Upvotes: 0

Views: 1245

Answers (3)

original.py

def func():
    print("func")

patch_original.py

import original

def patched_func():
    original.func()
    print("patched_func")

call.py

import original
import patch_original

patch_original.patched_func()

Upvotes: 0

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95993

This sort of patch is perfect for the decorator pattern:

In original.py:

def func():
    print("func")

In patch_original:

def patch(f): # this function is a decorator
    def p():
        f()
        print("patched_func")
    return p

In call.py:

import original
import patch_original

func = patch_original.patch(original.func) # here we decorate `original.func`

func()

Running call.py:

Juans-MacBook-Pro:temp juan$ python call.py
func
patched_func
Juans-MacBook-Pro:temp juan$

Then you can resuse this patch as you define new function in call.py:

import original
import patch_original

func = patch_original.patch(original.func)

func()

@patch_original.patch # decorator syntax
def func2():
    print("func2")

func2()

And running this:

Juans-MacBook-Pro:temp juan$ python call.py
func
patched_func
func2
patched_func

Upvotes: 3

John Zwinck
John Zwinck

Reputation: 249293

Do this in patch_original.py:

import original

_original_func = original.func

def patched_func():
    _original_func()
    print("patched_func")

Then in your main script:

import patch_original
func = patch_original.patched_func

Upvotes: 0

Related Questions