metaprogramming - From python, can we track module-level assignments before (other) user code executes? -
i'm working on tool benefit ability track references given object within python.
specifically, i'd make test doubles system replace module-level attributes of given type. example, assume following code in module c:
from import b if module, b reference object named a.b, separate reference. if test double system later replaces a.b, c.b still refer original object.
i have tool track assignments of a.b aliases, module-level aliasing go long way toward goal.
metaphorically, i'd override module.__setattribute__:
def __setattribute__(self, name, value): if isinstance(value, interesting_types): # remember use of interesting object , call super normal processing. assume can code loaded before modules might tracked can loaded.
this sort of thing may work you. first, code:
a.py
b = 42 # other module definitions fakery.py
class fakery(object): def __init__(self, mod): self.module = __import__(mod) import sys sys.modules[self.module.__name__] = self def __getattr__(self, name): print "__getattr__ called '%s'" % name result = getattr(self.module, name) if name == 'b': result += 1 return result example
>>> import fakery >>> fakery.fakery('a') <fakery.fakery object @ 0x109007110> >>> import b __getattr__ called '__path__' __getattr__ called 'b' >>> print b 43 >>> import >>> print <fakery.fakery object @ 0x109007110> all have modify fakery class whatever want do. in case, i'm adding 1 a's b.
i hope it's clear how works, here's quick explanation.
when module imported, record of gets stuffed sys.modules. when instantiate fakery object, import module name (using __import__), , replaces module's entry in sys.modules itself.
python imports modules once, storing imported module in sys.modules. every import after first returns entry in sys.modules. fakery object inserts itself sys.modules['a'], taking place of real module. subsequent import a or from import <whatever> statements directed instance of fakery. since it's class, can kinds of crazy stuff using magic methods or metaprogramming.
__getattr__ convenient because gets called when requested attribute doesn't exist.
Comments
Post a Comment