Last active
September 29, 2017 14:41
-
-
Save dhilst/cfd05839c80baa51a1a427b943add40b to your computer and use it in GitHub Desktop.
Monkey patch functions and methods proxy.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps | |
from operator import attrgetter | |
from importlib import import_module | |
from collections import Counter | |
import re | |
def packages(pfqn): | |
dots_n = len(pfqn.split('.')) | |
for i in range(dots_n): | |
yield pfqn.rsplit('.', i)[0] | |
def objgetter(pfqn): | |
for p in packages(pfqn): | |
try: | |
module = import_module(p) | |
except ImportError: | |
pass | |
else: | |
object_path = re.sub(r'^{}\.'.format(p), '', pfqn) | |
if '.' not in object_path: | |
parent = module | |
else: | |
parent_path = object_path.rsplit('.', 1)[0] | |
parent = attrgetter(parent_path)(module) | |
obj = attrgetter(object_path)(module) | |
return obj, parent | |
else: | |
raise ImportError('Cant find an importable at {}'.format(pfqn)) | |
def proxyfunc(pfqn, target_attr): | |
def decorator(func): | |
obj, parent = objgetter(pfqn) | |
setattr(parent, obj.__name__, func) | |
setattr(func, target_attr, obj) | |
return func | |
return decorator | |
from pprint import pprint | |
p = 'foopkg.foomodule.FooClass.BarClass.barmethod' | |
q = 'foopkg.foomodule.foofunc' | |
pprint(objgetter(p)) | |
pprint(objgetter(q)) | |
@proxyfunc(q, 'target') | |
def foofunc(): | |
return foofunc.target().upper() | |
@proxyfunc(p, 'target') | |
def barmethod(self): | |
return barmethod.target(self).upper() | |
from foopkg.foomodule import foofunc as f | |
print(f()) # FOO VALUE | |
from foopkg.foomodule import FooClass | |
print(FooClass.BarClass().barmethod()) # BAR VALUE |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment