@wrapt conditional monkey patching with decorators
Wrapt has two feature
- best practice for decorators
- monkey patching
I'm doing both to be able to conditionally change method called. I've provided an example which is based on pandas version. While this works, I have resorted to barebones monkey patching and not using wrapt capability. How can wrapt be used to monkey patch the alternate method?
import pandas as pd
import wrapt, inspect
from distutils.version import StrictVersion
def alt_impl(alt_fn, cond):
@wrapt.decorator
def wrapper(wrapped, instance, args, kwargs):
nonlocal alt_fn
if cond():
# @staticmethod and @classmethod need to navigate to actual function
if not inspect.isfunction(alt_fn):
alt_fn = alt_fn.__func__
# class instance methods need to be bound to class instance
if instance is not None:
alt_fn = alt_fn.__get__(instance, instance.__class__)
return alt_fn(*args, **kwargs)
else:
return wrapped(*args, **kwargs)
return wrapper
Example usage
class alt_impl_example():
def upgraded_pandas(self, args):
print(f"upgraded {pd.__version__}")
@alt_impl(upgraded_pandas, lambda: StrictVersion(pd.__version__) >= StrictVersion("1.0.0"))
def pandas(self, args):
print(pd.__version__)
t = alt_impl_example()
t.pandas({})