Search code examples
pythonfunctionenvironmentfixtures

same code running in two different environments with different library function signatures


I need to run some code in two different python environments. There is one library, which I am using two slighlty different versions of.

Env1.
mylib.myfun(*args) # as expected
mylib.myfun(*args,extra_arg=val) # raise error

Env2.
mylib.myfun(*args) # raise warning
mylib.myfun(*args,extra_arg=val) # as expected

Ideally, I would like to run the same identical code and get same results in the two environments. I was thinking to get away with a fixture

def fix_myfun():
    if mylib.version<needed:
       mylib.myfun(*args)
    else:
       mylib.myfun(*args)

is this the pythonic way to do so?


Solution

  • Python functions are objects, and are attributes of their modules, so you can just monkeypatch the module once at startup (ie in your main script):

    # this has to be executed BEFORE any use of `mylib.myfun`
    import mylib
    
    def patch_myfun():
        realfun = mylib.myfun
    
        if mylib.version < needed:
            # Env 1
            def patched(*args, extra_arg=None):
                return realfun(*args)
        else:
            # Env 2
            def patched(*args, extra_arg=None):
                return realfun(*args, extra_arg=extra_arg)
    
        mylib.myfun = patched
    
    
    patch_my_fun()
    

    NB: this code must be executed only once per process of course (else myfun will be patched more than once). The best way to ensure this is to either put it at the top of your script or in a module that is imported before any use of mylib.myfun - for a module, top-level code is only executed once (per process) the first time the module is imported, following imports will only retrieve the already loaded module from sys.modules.