59 lines
1.7 KiB
Python
59 lines
1.7 KiB
Python
|
"""
|
||
|
|
||
|
capture stdout/stderr
|
||
|
|
||
|
"""
|
||
|
import sys
|
||
|
try: from cStringIO import StringIO
|
||
|
except ImportError: from StringIO import StringIO
|
||
|
|
||
|
class SimpleOutErrCapture:
|
||
|
""" capture sys.stdout/sys.stderr (but not system level fd 1 and 2).
|
||
|
|
||
|
this captures only "In-Memory" and is currently intended to be
|
||
|
used by the unittest package to capture print-statements in tests.
|
||
|
"""
|
||
|
def __init__(self):
|
||
|
self.oldin = sys.stdin
|
||
|
self.oldout = sys.stdout
|
||
|
self.olderr = sys.stderr
|
||
|
sys.stdin = self.newin = DontReadFromInput()
|
||
|
sys.stdout = self.newout = StringIO()
|
||
|
sys.stderr = self.newerr = StringIO()
|
||
|
|
||
|
def reset(self):
|
||
|
""" return captured output and restore sys.stdout/err."""
|
||
|
x, y = self.done()
|
||
|
return x.read(), y.read()
|
||
|
|
||
|
def done(self):
|
||
|
o,e = sys.stdout, sys.stderr
|
||
|
sys.stdin, sys.stdout, sys.stderr = (
|
||
|
self.oldin, self.oldout, self.olderr)
|
||
|
del self.oldin, self.oldout, self.olderr
|
||
|
o, e = self.newout, self.newerr
|
||
|
o.seek(0)
|
||
|
e.seek(0)
|
||
|
return o,e
|
||
|
|
||
|
class DontReadFromInput:
|
||
|
"""Temporary stub class. Ideally when stdin is accessed, the
|
||
|
capturing should be turned off, with possibly all data captured
|
||
|
so far sent to the screen. This should be configurable, though,
|
||
|
because in automated test runs it is better to crash than
|
||
|
hang indefinitely.
|
||
|
"""
|
||
|
def read(self, *args):
|
||
|
raise IOError("reading from stdin while output is captured")
|
||
|
readline = read
|
||
|
readlines = read
|
||
|
__iter__ = read
|
||
|
|
||
|
def callcapture(func, *args, **kwargs):
|
||
|
so = SimpleOutErrCapture()
|
||
|
try:
|
||
|
res = func(*args, **kwargs)
|
||
|
finally:
|
||
|
out, err = so.reset()
|
||
|
return res, out, err
|