Ejemplo n.º 1
0
 def _buf_fixture(self):
     # try to simulate how sys.stdout looks - we send it u''
     # but then it's trying to encode to something.
     buf = BytesIO()
     wrapper = TextIOWrapper(buf, encoding="ascii", line_buffering=True)
     wrapper.getvalue = buf.getvalue
     return wrapper
Ejemplo n.º 2
0
class OutputCapture:
    """Capture stdout and stderr by redirecting to inmemory streams

    :param raw: Expecting raw bytes from stdout and stderr
    :type raw: bool
    """
    def __init__(self, raw: bool = False):
        self.raw = raw
        self._init_stdout(raw)
        self._init_stderr()

        self.formatter = logging.Formatter("%(message)s")
        self._init_list_capture()
        self._init_stats_capture()

    def _init_stdout(self, raw: bool):
        self.stdout = TextIOWrapper(BytesIO()) if raw else StringIO()
        self.stdout_original = sys.stdout
        sys.stdout = self.stdout

    def _init_stderr(self):
        self.stderr = StringIO()
        self.stderr_original = sys.stderr
        sys.stderr = self.stderr

    def _init_list_capture(self):
        self.list_handler = logging.StreamHandler(StringIO())
        self.list_handler.setFormatter(self.formatter)
        self.list_handler.setLevel("INFO")

        self.list_logger = logging.getLogger("borg.output.list")
        self.list_logger.addHandler(self.list_handler)

    def _init_stats_capture(self):
        self.stats_handler = logging.StreamHandler(StringIO())
        self.stats_handler.setFormatter(self.formatter)
        self.stats_handler.setLevel("INFO")

        self.stats_logger = logging.getLogger("borg.output.stats")
        self.stats_logger.addHandler(self.stats_handler)

    # pylint: disable=no-member
    def getvalues(self) -> Union[str, bytes]:
        """Get the captured values from the redirected stdout and stderr

        :return: Redirected values from stdout and stderr
        :rtype: Union[str, bytes]
        """
        stdout_value = stderr_value = None
        if self.raw:
            stdout_value = self.stdout.buffer.getvalue()
        else:
            stdout_value = self.stdout.getvalue().strip()
        stderr_value = self.stderr.getvalue().strip()

        list_value = self.list_handler.stream.getvalue()
        stats_value = self.stats_handler.stream.getvalue()

        return {
            "stdout": stdout_value,
            "stderr": stderr_value,
            "list": list_value,
            "stats": stats_value,
        }

    def close(self):
        """Close the underlying IO streams and reset stdout and stderr"""
        try:
            self.stdout.close()
            self.stderr.close()
            self.list_handler.stream.close()
            self.list_logger.removeHandler(self.list_handler)
            self.stats_handler.stream.close()
            self.stats_logger.removeHandler(self.stats_handler)
        finally:
            sys.stdout = self.stdout_original
            sys.stderr = self.stderr_original
Ejemplo n.º 3
-1
 def _buf_fixture(self):
     # try to simulate how sys.stdout looks - we send it u''
     # but then it's trying to encode to something.
     buf = BytesIO()
     wrapper = TextIOWrapper(buf, encoding='ascii', line_buffering=True)
     wrapper.getvalue = buf.getvalue
     return wrapper