Source code for modelly.viz.console.interpreter
"""An interactive Python interpreter whose stdout and stderr are captured."""
import code
import io
import sys
[docs]
class CaptureOutput:
"""A context manager for capturing stdout and stderr output.
This class provides a way to capture output that would normally be printed
to stdout and stderr during the execution of code within its context.
"""
def __init__(self):
"""Initialize the CaptureOutput context manager with empty string buffers."""
self.stdout = io.StringIO()
self.stderr = io.StringIO()
self._old_stdout = None
self._old_stderr = None
def __enter__(self):
"""Set up the context manager by redirecting stdout and stderr.
Returns:
self: The context manager instance
"""
self._old_stdout = sys.stdout
self._old_stderr = sys.stderr
sys.stdout = self.stdout
sys.stderr = self.stderr
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Restore the original stdout and stderr when exiting the context."""
sys.stdout = self._old_stdout
sys.stderr = self._old_stderr
[docs]
def get_output(self):
"""Retrieve and clear the captured output.
Returns:
tuple: A pair of strings (stdout_output, stderr_output)
"""
output = self.stdout.getvalue()
error = self.stderr.getvalue()
self.stdout.seek(0)
self.stdout.truncate(0)
self.stderr.seek(0)
self.stderr.truncate(0)
return output, error
[docs]
class InteractiveConsole(code.InteractiveConsole):
"""A custom interactive Python console with output capturing capabilities.
This class extends code.InteractiveConsole to provide output capturing functionality
when executing Python code interactively.
Args:
locals_dict (dict, optional): Dictionary of local variables. Defaults to None.
"""
def __init__(self, locals_dict=None):
"""Initialize the InteractiveConsole with the provided locals dictionary."""
super().__init__(locals=locals_dict or {})
self.capturer = CaptureOutput()
[docs]
def push(self, line):
"""Push a line to the command interpreter and execute it.
This method captures the output of the executed command and returns both
the 'more' flag and the captured output.
Args:
line (str): The line of code to be executed.
Returns:
tuple: A tuple containing:
- more (bool): Flag indicating if more input is needed
- str: The captured output from executing the command
"""
with self.capturer:
more = super().push(line)
return more, self.capturer.get_output()