Robot Framework
outputcapture.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from io import StringIO
17 import sys
18 
19 from robot.output import LOGGER
20 from robot.utils import console_decode, console_encode
21 
22 
24 
25  def __init__(self, library_import=False):
26  self._library_import_library_import = library_import
27  self._python_out_python_out = PythonCapturer(stdout=True)
28  self._python_err_python_err = PythonCapturer(stdout=False)
29 
30  def __enter__(self):
31  if self._library_import_library_import:
32  LOGGER.enable_library_import_logging()
33  return self
34 
35  def __exit__(self, exc_type, exc_value, exc_trace):
36  self._release_and_log_release_and_log()
37  if self._library_import_library_import:
38  LOGGER.disable_library_import_logging()
39  return False
40 
41  def _release_and_log(self):
42  stdout, stderr = self._release_release()
43  if stdout:
44  LOGGER.log_output(stdout)
45  if stderr:
46  LOGGER.log_output(stderr)
47  sys.__stderr__.write(console_encode(stderr, stream=sys.__stderr__))
48 
49  def _release(self):
50  stdout = self._python_out_python_out.release()
51  stderr = self._python_err_python_err.release()
52  return stdout, stderr
53 
54 
56 
57  def __init__(self, stdout=True):
58  if stdout:
59  self._original_original = sys.stdout
60  self._set_stream_set_stream = self._set_stdout_set_stdout
61  else:
62  self._original_original = sys.stderr
63  self._set_stream_set_stream = self._set_stderr_set_stderr
64  self._stream_stream = StringIO()
65  self._set_stream_set_stream(self._stream_stream)
66 
67  def _set_stdout(self, stream):
68  sys.stdout = stream
69 
70  def _set_stderr(self, stream):
71  sys.stderr = stream
72 
73  def release(self):
74  # Original stream must be restored before closing the current
75  self._set_stream_set_stream(self._original_original)
76  try:
77  return self._get_value_get_value(self._stream_stream)
78  finally:
79  self._stream_stream.close()
80  self._avoid_at_exit_errors_avoid_at_exit_errors(self._stream_stream)
81 
82  def _get_value(self, stream):
83  try:
84  return console_decode(stream.getvalue())
85  except UnicodeError:
86  # Error occurs if non-ASCII chars logged both as str and unicode.
87  stream.buf = console_decode(stream.buf)
88  stream.buflist = [console_decode(item) for item in stream.buflist]
89  return stream.getvalue()
90 
91  def _avoid_at_exit_errors(self, stream):
92  # Avoid ValueError at program exit when logging module tries to call
93  # methods of streams it has intercepted that are already closed.
94  # Which methods are called, and does logging silence possible errors,
95  # depends on Python version. For related discussion see
96  # http://bugs.python.org/issue6333
97  stream.write = lambda s: None
98  stream.flush = lambda: None
def __init__(self, library_import=False)
def __exit__(self, exc_type, exc_value, exc_trace)
def console_decode(string, encoding=CONSOLE_ENCODING)
Decodes bytes from console encoding to Unicode.
Definition: encoding.py:39
def console_encode(string, encoding=None, errors='replace', stream=sys.__stdout__, force=False)
Encodes the given string so that it can be used in the console.
Definition: encoding.py:61