50 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			50 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Python
		
	
	
	
 | 
						|
import os, sys
 | 
						|
 | 
						|
class FDCapture: 
 | 
						|
    def __init__(self, targetfd, sysattr=None): 
 | 
						|
        self.targetfd = targetfd
 | 
						|
        self.tmpfile = self.maketmpfile()
 | 
						|
        self._savefd = os.dup(targetfd)
 | 
						|
        os.dup2(self.tmpfile.fileno(), targetfd) 
 | 
						|
        if sysattr is not None: 
 | 
						|
            self._reset = (lambda oldval=getattr(sys, sysattr): 
 | 
						|
                               setattr(sys, sysattr, oldval))
 | 
						|
            setattr(sys, sysattr, self.tmpfile) 
 | 
						|
 | 
						|
    def done(self): 
 | 
						|
        os.dup2(self._savefd, self.targetfd) 
 | 
						|
        if hasattr(self, '_reset'): 
 | 
						|
            self._reset() 
 | 
						|
            del self._reset 
 | 
						|
        os.close(self._savefd) 
 | 
						|
        f = self.tmpfile
 | 
						|
        f.seek(0)
 | 
						|
        del self._savefd 
 | 
						|
        del self.tmpfile 
 | 
						|
        return f 
 | 
						|
 | 
						|
    def maketmpfile(self): 
 | 
						|
        f = os.tmpfile()
 | 
						|
        fd = f.fileno()
 | 
						|
        newfd = os.dup(fd) 
 | 
						|
        newf = os.fdopen(newfd, 'w+b', 0)
 | 
						|
        f.close()
 | 
						|
        return newf 
 | 
						|
 | 
						|
class Capture: 
 | 
						|
    def __init__(self): 
 | 
						|
        self._out = FDCapture(1, 'stdout') 
 | 
						|
        self._oldsysout = sys.stdout 
 | 
						|
        sys.stdout = self._out.tmpfile
 | 
						|
 | 
						|
        self._err = FDCapture(2, 'stderr') 
 | 
						|
        self._olderrout = sys.stderr 
 | 
						|
        sys.stderr = self._err.tmpfile
 | 
						|
 | 
						|
    def reset(self): 
 | 
						|
        outfile = self._out.done() 
 | 
						|
        errfile = self._err.done() 
 | 
						|
        return outfile.read(), errfile.read() 
 | 
						|
 |