def trace(module):
from inspect import getmembers, isfunction, isclass, getmodule, classify_class_attrs
import inspect
def maketrace(name, func):
def _trace(*args, **kwargs):
print>>trace.fobj, ">>%*s%s(%s)" % (trace.indent, "",
name, ", ".join(map(repr, args) +
["%s=%r" % (k,v) for (k,v) in kwargs.iteritems()]))
trace.indent += 2
val = Exception
try:
val = func(*args, **kwargs)
finally:
trace.indent -= 2
print>>trace.fobj,"<<%*s%s: %r" % (trace.indent, "", name, val)
return val
return _trace
for name, func in getmembers(module, isfunction):
if getmodule(func) != module: continue
if name.startswith('__') and name.endswith('__'): continue
print 'replacing', module.__name__, name
setattr(module, name, maketrace(name, func))
for name, cls in getmembers(module, isclass):
if getmodule(cls) != module: continue
print 'checking out class', name
for name, kind, cls, obj in list(classify_class_attrs(cls)):
if name.startswith('__') and name.endswith('__'): continue
if name in ('items', 'keys', 'values'): continue
if cls is list: continue
if kind == 'class method':
print 'replacing classmethod', name
setattr(cls, name, staticmethod(maketrace(name, getattr(cls, name))))
elif kind == 'static method':
print 'replacing staticmethod', name
setattr(cls, name, staticmethod(maketrace(name, getattr(cls, name))))
elif kind == 'property2':
print 'replacing property', name
setattr(cls, name, property(
obj.fget and maketrace('get_' + name, obj.fget),
obj.fset and maketrace('set_' + name, obj.fset),
obj.fdel and maketrace('del_' + name, obj.fdel),
obj.__doc__))
elif kind == 'method':
print 'replacing method', name
setattr(cls, name, maketrace(name, obj))
if not hasattr(trace, 'fobj'):
trace.indent = 0
trace.fobj = open("tracelog", "w")
class tracefile(file):
def read(self, *size):
print>>trace.fobj,">>%*sfile#read%r at %d" % (trace.indent, "", size, self.tell())
trace.indent += 2
val = Exception
try:
val = super(tracefile, self).read(*size)
finally:
trace.indent -= 2
print>>trace.fobj,"<<%*sfile#read: %r" % (trace.indent, "", val[:15])
return val
def write(self, *data):
print>>trace.fobj,">>%*sfile#write%r at %d" % (trace.indent, "", data[0][:15], self.tell())
trace.indent += 2
val = Exception
try:
val = super(tracefile, self).write(*data)
finally:
trace.indent -= 2
print>>trace.fobj,"<<%*sfile#write: %r" % (trace.indent, "", val)
return val
import __builtin__
__builtin__.file = __builtin__.open = tracefile