import sys from typing import Optional, TextIO, cast from prompt_toolkit.patch_stdout import StdoutProxy from prompt_toolkit.utils import ( get_term_environment_variable, is_conemu_ansi, is_windows, ) from .base import Output from .color_depth import ColorDepth __all__ = [ "create_output", ] def create_output( stdout: Optional[TextIO] = None, always_prefer_tty: bool = True ) -> Output: """ Return an :class:`~prompt_toolkit.output.Output` instance for the command line. :param stdout: The stdout object :param always_prefer_tty: When set, look for `sys.stderr` if `sys.stdout` is not a TTY. (The prompt_toolkit render output is not meant to be consumed by something other then a terminal, so this is a reasonable default.) """ # Consider TERM and PROMPT_TOOLKIT_COLOR_DEPTH environment variables. # Notice that PROMPT_TOOLKIT_COLOR_DEPTH value is the default that's used # if the Application doesn't override it. term_from_env = get_term_environment_variable() color_depth_from_env = ColorDepth.from_env() if stdout is None: # By default, render to stdout. If the output is piped somewhere else, # render to stderr. stdout = sys.stdout if always_prefer_tty: for io in [sys.stdout, sys.stderr]: if io.isatty(): stdout = io break # If the patch_stdout context manager has been used, then sys.stdout is # replaced by this proxy. For prompt_toolkit applications, we want to use # the real stdout. while isinstance(stdout, StdoutProxy): stdout = stdout.original_stdout if is_windows(): from .conemu import ConEmuOutput from .win32 import Win32Output from .windows10 import Windows10_Output, is_win_vt100_enabled if is_win_vt100_enabled(): return cast( Output, Windows10_Output(stdout, default_color_depth=color_depth_from_env), ) if is_conemu_ansi(): return cast( Output, ConEmuOutput(stdout, default_color_depth=color_depth_from_env) ) else: return Win32Output(stdout, default_color_depth=color_depth_from_env) else: from .vt100 import Vt100_Output return Vt100_Output.from_pty( stdout, term=term_from_env, default_color_depth=color_depth_from_env )