from functools import wraps
import time
class Debugger(object):
attribute_acceses = []
method_calls = []
def wrap(f):
@wraps(f)
def new_func(*args, **kwargs):
start = time.time()
ret = f(*args, **kwargs)
Debugger.method_calls.append({
'class': type(args[0]),
'method': f.__name__,
'args': args,
'kwargs': kwargs,
'time': time.time()-start
})
return ret
return new_func
class Meta(type):
def __new__(meta_cls, cls_name, cls_parent, cls_attr):
for k, v in cls_attr.items():
if callable(v):
cls_attr[k] = wrap(v)
def __getattribute__(self, name):
value = super(cls, self).__getattribute__(name)
Debugger.attribute_acceses.append({
'action': 'get',
'class': type(self),
'attribute': name,
'value': value # actual value
})
return value
cls_attr['__getattribute__'] = __getattribute__
def __setattr__(self, name, value):
Debugger.attribute_acceses.append({
'action': 'set',
'class': type(self),
'attribute': name,
'value': value
})
return super(cls, self).__setattr__(name, value)
cls_attr['__setattr__'] = __setattr__
cls = type.__new__(meta_cls, cls_name, cls_parent, cls_attr)
return cls