Question

I would like to write a context manager in python that temporarily disables a function globally. Is such a thing possible to do generically? Here is an example of the desired behavior:

#in module x
def disable_me(): print "do stuff"

#in module y
import x
def run_me():
    print "run_me"
    x.disable_me()

#in module z
import x
import y
with disable_function(x.disable_me):
    y.run_me()

#desired output: run_me

I know that, in principle, I can temporarily assign lambda *args, **kwargs: None to x.disable_me but it's not clear to me if the context manager has enough information to actually do this.

Was it helpful?

Solution

This is actually reasonably easy to do, provided you don't mind passing the containing object and the name of the variable, rather than the variable itself (which shouldn't be an issue).

from contextlib import contextmanager

class X:
    def disable_me():
        print("do stuff")

def run_me(x):
    print("run_me")
    x.disable_me()

@contextmanager
def disable_function(obj, name):
    temp = getattr(obj, name)
    setattr(obj, name, lambda: None)
    yield
    setattr(obj, name, temp)

x = X()
with disable_function(x, "disable_me"):
    run_me(x)

This will work with modules as well as objects, but it's easier to show in one file like this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top