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:
		| @@ -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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Peter Scheibel
					Peter Scheibel