Update log_output to handle cases where sys.stdout/stderr streams do not have

an associated file descriptor (e.g. holds for nose tests where sys.stdout is
assigned to a StringIO object)
This commit is contained in:
Peter Scheibel 2015-11-24 17:58:17 -08:00
parent 5081ba6802
commit 0adf93853d

View File

@ -122,6 +122,10 @@ def __init__(self, stream, echo=False, force_color=False, debug=False):
self.force_color = force_color
self.debug = debug
# Default is to try file-descriptor reassignment unless the system
# out/err streams do not have an associated file descriptor
self.directAssignment = False
def trace(self, frame, event, arg):
"""Jumps to __exit__ on the child process."""
raise _SkipWithBlock()
@ -185,13 +189,21 @@ def __enter__(self):
# Child: redirect output, execute the with block.
os.close(read)
# Save old stdout and stderr
self._stdout = os.dup(sys.stdout.fileno())
self._stderr = os.dup(sys.stderr.fileno())
try:
# Save old stdout and stderr
self._stdout = os.dup(sys.stdout.fileno())
self._stderr = os.dup(sys.stderr.fileno())
# redirect to the pipe.
os.dup2(write, sys.stdout.fileno())
os.dup2(write, sys.stderr.fileno())
# redirect to the pipe.
os.dup2(write, sys.stdout.fileno())
os.dup2(write, sys.stderr.fileno())
except AttributeError:
self.directAssignment = True
self._stdout = sys.stdout
self._stderr = sys.stderr
output_redirect = os.fdopen(write, 'w')
sys.stdout = output_redirect
sys.stderr = output_redirect
if self.force_color:
color._force_color = True
@ -218,8 +230,12 @@ def __exit__(self, exc_type, exception, traceback):
#
# TODO: think about how this works outside install.
# TODO: ideally would propagate exception to parent...
os.dup2(self._stdout, sys.stdout.fileno())
os.dup2(self._stderr, sys.stderr.fileno())
if self.directAssignment:
sys.stdout = self._stdout
sys.stderr = self._stderr
else:
os.dup2(self._stdout, sys.stdout.fileno())
os.dup2(self._stderr, sys.stderr.fileno())
return False