Search code examples
pythonimportnamespacesmonkeypatching

Does monkey patching in Python affect direct imports?


If I monkey patch a module:

# mokeypatch.py
import other_module

def replacement(*args, **kwargs):
    pass

other_module.some_func = replacement

Will this affect a module that imports some_func directly, or will it depend on the order of imports? If a third module is like this:

# third_module.py
from other_module import some_func

First, this code is run, then our monkey patch. Will third_module.some_func be the old one?


Solution

  • Yes, it will point to the old function.

    When doing from mod import func inside mod2, func will be bound in scope of mod2.
    Monkeypatching mod.func will bind mod.func to the new function but neither mod nor mod.func know that mod2.func even exist - and even if they did (internally they might know it somewhere) they couldn't know if it should be replaced or now.

    A practical example why rebinding the imported name would be problematic is this:

    # monkeypatch.py
    import other_module
    from other_module import func as orig_func
    def replacement():
        do_stuff()
        orig_func()
        do_stuff()
    other_module.func = replacement
    

    If it was rebound, you'd now have infinite recursion and no way to call the original function.