class TranscriptPrint(object): """Trap all output directed to stdout/err (e.g by print statements) and redirect it to a file. Subclasses may modify the default behavior by overriding the Hook* methods. Highly simplified from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/119404""" def __init__(self,fname='transcript',stream='stdout',start=False): if stream not in ['stdout','stderr']: raise ValueError,'stream must be "stdout" or "stderr"' self.orig_stream = None self.stream = stream self.fname = fname self._closed = False # Each instance starts with a clean transcript file try: os.unlink(fname) except OSError: pass if start: self.start() def hook_start(self): self.f = open(self.fname,'a') def hook(self,text): """hook must return whether to proceed with normal printing or not""" self.f.write(text) return True def hook_stop(self): self.f.close() def start(self,func=None): if self._closed: raise IOError("TranscriptPrint instance is closed.") if self.stream == 'stdout': sys.stdout.flush() self.orig_stream = sys.stdout sys.stdout = self else: sys.stderr.flush() self.orig_stream = sys.stderr sys.stderr= self self.hook_start() def stop(self): """Stop will stop routing of print statements through this class""" self.flush() if self.stream == 'stdout': sys.stdout = self.orig_stream else: sys.stderr = self.orig_stream self.hook_stop() def write(self,text): """override write of output stream. The hook may supress output or modify the text printed to stdout.""" proceed = self.hook(text) if proceed: self.orig_stream.write(text) self.orig_stream.flush() def __getattr__(self, name): """pass all other methods to the original stream""" #print '---Getting:',name # dbg return getattr(self.orig_stream,name)