slither.utils.output_capture

 1import io
 2import logging
 3import sys
 4
 5
 6class CapturingStringIO(io.StringIO):
 7    """
 8    I/O implementation which captures output, and optionally mirrors it to the original I/O stream it replaces.
 9    """
10
11    def __init__(self, original_io=None):
12        super().__init__()
13        self.original_io = original_io
14
15    def write(self, s):
16        super().write(s)
17        if self.original_io:
18            self.original_io.write(s)
19
20
21class StandardOutputCapture:
22    """
23    Redirects and captures standard output/errors.
24    """
25
26    original_stdout = None
27    original_stderr = None
28    original_logger_handlers = None
29
30    @staticmethod
31    def enable(block_original: bool = True) -> None:
32        """
33        Redirects stdout and stderr to a capturable StringIO.
34        :param block_original: If True, blocks all output to the original stream. If False, duplicates output.
35        :return: None
36        """
37        # Redirect stdout
38        if StandardOutputCapture.original_stdout is None:
39            StandardOutputCapture.original_stdout = sys.stdout
40            sys.stdout = CapturingStringIO(
41                None if block_original else StandardOutputCapture.original_stdout
42            )
43
44        # Redirect stderr
45        if StandardOutputCapture.original_stderr is None:
46            StandardOutputCapture.original_stderr = sys.stderr
47            sys.stderr = CapturingStringIO(
48                None if block_original else StandardOutputCapture.original_stderr
49            )
50
51            # Backup and swap root logger handlers
52            root_logger = logging.getLogger()
53            StandardOutputCapture.original_logger_handlers = root_logger.handlers
54            root_logger.handlers = [logging.StreamHandler(sys.stderr)]
55
56    @staticmethod
57    def disable() -> None:
58        """
59        Disables redirection of stdout/stderr, if previously enabled.
60        :return: None
61        """
62        # If we have a stdout backup, restore it.
63        if StandardOutputCapture.original_stdout is not None:
64            sys.stdout.close()
65            sys.stdout = StandardOutputCapture.original_stdout
66            StandardOutputCapture.original_stdout = None
67
68        # If we have an stderr backup, restore it.
69        if StandardOutputCapture.original_stderr is not None:
70            sys.stderr.close()
71            sys.stderr = StandardOutputCapture.original_stderr
72            StandardOutputCapture.original_stderr = None
73
74        # Restore our logging handlers
75        if StandardOutputCapture.original_logger_handlers is not None:
76            root_logger = logging.getLogger()
77            root_logger.handlers = StandardOutputCapture.original_logger_handlers
78            StandardOutputCapture.original_logger_handlers = None
79
80    @staticmethod
81    def get_stdout_output() -> str:
82        """
83        Obtains the output from the currently set stdout
84        :return: Returns stdout output as a string
85        """
86        sys.stdout.seek(0)
87        return sys.stdout.read()
88
89    @staticmethod
90    def get_stderr_output() -> str:
91        """
92        Obtains the output from the currently set stderr
93        :return: Returns stderr output as a string
94        """
95        sys.stderr.seek(0)
96        return sys.stderr.read()
class CapturingStringIO(_io.StringIO):
 7class CapturingStringIO(io.StringIO):
 8    """
 9    I/O implementation which captures output, and optionally mirrors it to the original I/O stream it replaces.
10    """
11
12    def __init__(self, original_io=None):
13        super().__init__()
14        self.original_io = original_io
15
16    def write(self, s):
17        super().write(s)
18        if self.original_io:
19            self.original_io.write(s)

I/O implementation which captures output, and optionally mirrors it to the original I/O stream it replaces.

CapturingStringIO(original_io=None)
12    def __init__(self, original_io=None):
13        super().__init__()
14        self.original_io = original_io
original_io
def write(self, s):
16    def write(self, s):
17        super().write(s)
18        if self.original_io:
19            self.original_io.write(s)

Write string to file.

Returns the number of characters written, which is always equal to the length of the string.

Inherited Members
_io.StringIO
close
getvalue
read
readline
tell
truncate
seek
seekable
readable
writable
closed
newlines
line_buffering
_io._TextIOBase
detach
encoding
errors
_io._IOBase
flush
fileno
isatty
readlines
writelines
class StandardOutputCapture:
22class StandardOutputCapture:
23    """
24    Redirects and captures standard output/errors.
25    """
26
27    original_stdout = None
28    original_stderr = None
29    original_logger_handlers = None
30
31    @staticmethod
32    def enable(block_original: bool = True) -> None:
33        """
34        Redirects stdout and stderr to a capturable StringIO.
35        :param block_original: If True, blocks all output to the original stream. If False, duplicates output.
36        :return: None
37        """
38        # Redirect stdout
39        if StandardOutputCapture.original_stdout is None:
40            StandardOutputCapture.original_stdout = sys.stdout
41            sys.stdout = CapturingStringIO(
42                None if block_original else StandardOutputCapture.original_stdout
43            )
44
45        # Redirect stderr
46        if StandardOutputCapture.original_stderr is None:
47            StandardOutputCapture.original_stderr = sys.stderr
48            sys.stderr = CapturingStringIO(
49                None if block_original else StandardOutputCapture.original_stderr
50            )
51
52            # Backup and swap root logger handlers
53            root_logger = logging.getLogger()
54            StandardOutputCapture.original_logger_handlers = root_logger.handlers
55            root_logger.handlers = [logging.StreamHandler(sys.stderr)]
56
57    @staticmethod
58    def disable() -> None:
59        """
60        Disables redirection of stdout/stderr, if previously enabled.
61        :return: None
62        """
63        # If we have a stdout backup, restore it.
64        if StandardOutputCapture.original_stdout is not None:
65            sys.stdout.close()
66            sys.stdout = StandardOutputCapture.original_stdout
67            StandardOutputCapture.original_stdout = None
68
69        # If we have an stderr backup, restore it.
70        if StandardOutputCapture.original_stderr is not None:
71            sys.stderr.close()
72            sys.stderr = StandardOutputCapture.original_stderr
73            StandardOutputCapture.original_stderr = None
74
75        # Restore our logging handlers
76        if StandardOutputCapture.original_logger_handlers is not None:
77            root_logger = logging.getLogger()
78            root_logger.handlers = StandardOutputCapture.original_logger_handlers
79            StandardOutputCapture.original_logger_handlers = None
80
81    @staticmethod
82    def get_stdout_output() -> str:
83        """
84        Obtains the output from the currently set stdout
85        :return: Returns stdout output as a string
86        """
87        sys.stdout.seek(0)
88        return sys.stdout.read()
89
90    @staticmethod
91    def get_stderr_output() -> str:
92        """
93        Obtains the output from the currently set stderr
94        :return: Returns stderr output as a string
95        """
96        sys.stderr.seek(0)
97        return sys.stderr.read()

Redirects and captures standard output/errors.

original_stdout = None
original_stderr = None
original_logger_handlers = None
@staticmethod
def enable(block_original: bool = True) -> None:
31    @staticmethod
32    def enable(block_original: bool = True) -> None:
33        """
34        Redirects stdout and stderr to a capturable StringIO.
35        :param block_original: If True, blocks all output to the original stream. If False, duplicates output.
36        :return: None
37        """
38        # Redirect stdout
39        if StandardOutputCapture.original_stdout is None:
40            StandardOutputCapture.original_stdout = sys.stdout
41            sys.stdout = CapturingStringIO(
42                None if block_original else StandardOutputCapture.original_stdout
43            )
44
45        # Redirect stderr
46        if StandardOutputCapture.original_stderr is None:
47            StandardOutputCapture.original_stderr = sys.stderr
48            sys.stderr = CapturingStringIO(
49                None if block_original else StandardOutputCapture.original_stderr
50            )
51
52            # Backup and swap root logger handlers
53            root_logger = logging.getLogger()
54            StandardOutputCapture.original_logger_handlers = root_logger.handlers
55            root_logger.handlers = [logging.StreamHandler(sys.stderr)]

Redirects stdout and stderr to a capturable StringIO.

Parameters
  • block_original: If True, blocks all output to the original stream. If False, duplicates output.
Returns

None

@staticmethod
def disable() -> None:
57    @staticmethod
58    def disable() -> None:
59        """
60        Disables redirection of stdout/stderr, if previously enabled.
61        :return: None
62        """
63        # If we have a stdout backup, restore it.
64        if StandardOutputCapture.original_stdout is not None:
65            sys.stdout.close()
66            sys.stdout = StandardOutputCapture.original_stdout
67            StandardOutputCapture.original_stdout = None
68
69        # If we have an stderr backup, restore it.
70        if StandardOutputCapture.original_stderr is not None:
71            sys.stderr.close()
72            sys.stderr = StandardOutputCapture.original_stderr
73            StandardOutputCapture.original_stderr = None
74
75        # Restore our logging handlers
76        if StandardOutputCapture.original_logger_handlers is not None:
77            root_logger = logging.getLogger()
78            root_logger.handlers = StandardOutputCapture.original_logger_handlers
79            StandardOutputCapture.original_logger_handlers = None

Disables redirection of stdout/stderr, if previously enabled.

Returns

None

@staticmethod
def get_stdout_output() -> str:
81    @staticmethod
82    def get_stdout_output() -> str:
83        """
84        Obtains the output from the currently set stdout
85        :return: Returns stdout output as a string
86        """
87        sys.stdout.seek(0)
88        return sys.stdout.read()

Obtains the output from the currently set stdout

Returns

Returns stdout output as a string

@staticmethod
def get_stderr_output() -> str:
90    @staticmethod
91    def get_stderr_output() -> str:
92        """
93        Obtains the output from the currently set stderr
94        :return: Returns stderr output as a string
95        """
96        sys.stderr.seek(0)
97        return sys.stderr.read()

Obtains the output from the currently set stderr

Returns

Returns stderr output as a string