# encoding: utf-8 """ Stdout/stderr redirector, at the OS level, using file descriptors. This also works under windows. """ __docformat__ = "restructuredtext en" #------------------------------------------------------------------------------- # Copyright (C) 2008 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #------------------------------------------------------------------------------- import os import sys STDOUT = 1 STDERR = 2 class FDRedirector(object): """ Class to redirect output (stdout or stderr) at the OS level using file descriptors. """ def __init__(self, fd=STDOUT): """ fd is the file descriptor of the outpout you want to capture. It can be STDOUT or STERR. """ self.fd = fd self.started = False self.piper = None self.pipew = None def start(self): """ Setup the redirection. """ if not self.started: self.oldhandle = os.dup(self.fd) self.piper, self.pipew = os.pipe() os.dup2(self.pipew, self.fd) os.close(self.pipew) self.started = True def flush(self): """ Flush the captured output, similar to the flush method of any stream. """ if self.fd == STDOUT: sys.stdout.flush() elif self.fd == STDERR: sys.stderr.flush() def stop(self): """ Unset the redirection and return the captured output. """ if self.started: self.flush() os.dup2(self.oldhandle, self.fd) os.close(self.oldhandle) f = os.fdopen(self.piper, 'r') output = f.read() f.close() self.started = False return output else: return '' def getvalue(self): """ Return the output captured since the last getvalue, or the start of the redirection. """ output = self.stop() self.start() return output