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