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