I have written some unittests that analyze data that is logged with the standard python logging function. Using some of the ideas that I found here: Capture stdout from a script in Python about how to capture data from stderr, I have come up with the following script, which I have simplified down to the bare minimum to illustrate a problem that I have encountered. (the loop below is simulates the fact that this function might be called from various unittests)
import logging, sys
from StringIO import StringIO
def get_stderr():
saved_stderr = sys.stderr
stderr_string_io = StringIO()
sys.stderr = stderr_string_io
try:
logging.error("Foobar!!!")
finally:
# set the stdout and stderr back to their original values
sys.stderr = saved_stderr
err_output = stderr_string_io.getvalue()
return err_output
for x in [1, 2]:
err_output = get_stderr()
print "Run %d: %s" % (x, err_output)
If you run the script it will give the following output, in which the logging output from the second loop iteration is totally lost:
Run 1: ERROR:root:Foobar!!!
Run 2:
Process finished with exit code 0
While I would expect it to give the following output:
Run 1: ERROR:root:Foobar!!!
Run 2: ERROR:root:Foobar!!!
Process finished with exit code 0
Note: that executing stderr_string_io.close()
at the end of the function does not work, as the script then throws an ValueError
the next time the function is executed.
Why does this code not behave as expected, and what is the solution to correct this problem?