Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
console.py2634 linesDownload Raw Back to rich
1import inspect2import os3import platform4import sys5import threading6import zlib7from abc import ABC, abstractmethod8from dataclasses import dataclass, field9from datetime import datetime10from functools import wraps11from getpass import getpass12from html import escape13from inspect import isclass14from itertools import islice15from math import ceil16from time import monotonic17from types import FrameType, ModuleType, TracebackType18from typing import (19    IO,20    TYPE_CHECKING,21    Any,22    Callable,23    Dict,24    Iterable,25    List,26    Mapping,27    NamedTuple,28    Optional,29    TextIO,30    Tuple,31    Type,32    Union,33    cast,34)35 36from rich._null_file import NULL_FILE37 38if sys.version_info >= (3, 8):39    from typing import Literal, Protocol, runtime_checkable40else:41    from typing_extensions import (42        Literal,43        Protocol,44        runtime_checkable,45    )  # pragma: no cover46 47from . import errors, themes48from ._emoji_replace import _emoji_replace49from ._export_format import CONSOLE_HTML_FORMAT, CONSOLE_SVG_FORMAT50from ._fileno import get_fileno51from ._log_render import FormatTimeCallable, LogRender52from .align import Align, AlignMethod53from .color import ColorSystem, blend_rgb54from .control import Control55from .emoji import EmojiVariant56from .highlighter import NullHighlighter, ReprHighlighter57from .markup import render as render_markup58from .measure import Measurement, measure_renderables59from .pager import Pager, SystemPager60from .pretty import Pretty, is_expandable61from .protocol import rich_cast62from .region import Region63from .scope import render_scope64from .screen import Screen65from .segment import Segment66from .style import Style, StyleType67from .styled import Styled68from .terminal_theme import DEFAULT_TERMINAL_THEME, SVG_EXPORT_THEME, TerminalTheme69from .text import Text, TextType70from .theme import Theme, ThemeStack71 72if TYPE_CHECKING:73    from ._windows import WindowsConsoleFeatures74    from .live import Live75    from .status import Status76 77JUPYTER_DEFAULT_COLUMNS = 11578JUPYTER_DEFAULT_LINES = 10079WINDOWS = platform.system() == "Windows"80 81HighlighterType = Callable[[Union[str, "Text"]], "Text"]82JustifyMethod = Literal["default", "left", "center", "right", "full"]83OverflowMethod = Literal["fold", "crop", "ellipsis", "ignore"]84 85 86class NoChange:87    pass88 89 90NO_CHANGE = NoChange()91 92try:93    _STDIN_FILENO = sys.__stdin__.fileno()94except Exception:95    _STDIN_FILENO = 096try:97    _STDOUT_FILENO = sys.__stdout__.fileno()98except Exception:99    _STDOUT_FILENO = 1100try:101    _STDERR_FILENO = sys.__stderr__.fileno()102except Exception:103    _STDERR_FILENO = 2104 105_STD_STREAMS = (_STDIN_FILENO, _STDOUT_FILENO, _STDERR_FILENO)106_STD_STREAMS_OUTPUT = (_STDOUT_FILENO, _STDERR_FILENO)107 108 109_TERM_COLORS = {110    "kitty": ColorSystem.EIGHT_BIT,111    "256color": ColorSystem.EIGHT_BIT,112    "16color": ColorSystem.STANDARD,113}114 115 116class ConsoleDimensions(NamedTuple):117    """Size of the terminal."""118 119    width: int120    """The width of the console in 'cells'."""121    height: int122    """The height of the console in lines."""123 124 125@dataclass126class ConsoleOptions:127    """Options for __rich_console__ method."""128 129    size: ConsoleDimensions130    """Size of console."""131    legacy_windows: bool132    """legacy_windows: flag for legacy windows."""133    min_width: int134    """Minimum width of renderable."""135    max_width: int136    """Maximum width of renderable."""137    is_terminal: bool138    """True if the target is a terminal, otherwise False."""139    encoding: str140    """Encoding of terminal."""141    max_height: int142    """Height of container (starts as terminal)"""143    justify: Optional[JustifyMethod] = None144    """Justify value override for renderable."""145    overflow: Optional[OverflowMethod] = None146    """Overflow value override for renderable."""147    no_wrap: Optional[bool] = False148    """Disable wrapping for text."""149    highlight: Optional[bool] = None150    """Highlight override for render_str."""151    markup: Optional[bool] = None152    """Enable markup when rendering strings."""153    height: Optional[int] = None154 155    @property156    def ascii_only(self) -> bool:157        """Check if renderables should use ascii only."""158        return not self.encoding.startswith("utf")159 160    def copy(self) -> "ConsoleOptions":161        """Return a copy of the options.162 163        Returns:164            ConsoleOptions: a copy of self.165        """166        options: ConsoleOptions = ConsoleOptions.__new__(ConsoleOptions)167        options.__dict__ = self.__dict__.copy()168        return options169 170    def update(171        self,172        *,173        width: Union[int, NoChange] = NO_CHANGE,174        min_width: Union[int, NoChange] = NO_CHANGE,175        max_width: Union[int, NoChange] = NO_CHANGE,176        justify: Union[Optional[JustifyMethod], NoChange] = NO_CHANGE,177        overflow: Union[Optional[OverflowMethod], NoChange] = NO_CHANGE,178        no_wrap: Union[Optional[bool], NoChange] = NO_CHANGE,179        highlight: Union[Optional[bool], NoChange] = NO_CHANGE,180        markup: Union[Optional[bool], NoChange] = NO_CHANGE,181        height: Union[Optional[int], NoChange] = NO_CHANGE,182    ) -> "ConsoleOptions":183        """Update values, return a copy."""184        options = self.copy()185        if not isinstance(width, NoChange):186            options.min_width = options.max_width = max(0, width)187        if not isinstance(min_width, NoChange):188            options.min_width = min_width189        if not isinstance(max_width, NoChange):190            options.max_width = max_width191        if not isinstance(justify, NoChange):192            options.justify = justify193        if not isinstance(overflow, NoChange):194            options.overflow = overflow195        if not isinstance(no_wrap, NoChange):196            options.no_wrap = no_wrap197        if not isinstance(highlight, NoChange):198            options.highlight = highlight199        if not isinstance(markup, NoChange):200            options.markup = markup201        if not isinstance(height, NoChange):202            if height is not None:203                options.max_height = height204            options.height = None if height is None else max(0, height)205        return options206 207    def update_width(self, width: int) -> "ConsoleOptions":208        """Update just the width, return a copy.209 210        Args:211            width (int): New width (sets both min_width and max_width)212 213        Returns:214            ~ConsoleOptions: New console options instance.215        """216        options = self.copy()217        options.min_width = options.max_width = max(0, width)218        return options219 220    def update_height(self, height: int) -> "ConsoleOptions":221        """Update the height, and return a copy.222 223        Args:224            height (int): New height225 226        Returns:227            ~ConsoleOptions: New Console options instance.228        """229        options = self.copy()230        options.max_height = options.height = height231        return options232 233    def reset_height(self) -> "ConsoleOptions":234        """Return a copy of the options with height set to ``None``.235 236        Returns:237            ~ConsoleOptions: New console options instance.238        """239        options = self.copy()240        options.height = None241        return options242 243    def update_dimensions(self, width: int, height: int) -> "ConsoleOptions":244        """Update the width and height, and return a copy.245 246        Args:247            width (int): New width (sets both min_width and max_width).248            height (int): New height.249 250        Returns:251            ~ConsoleOptions: New console options instance.252        """253        options = self.copy()254        options.min_width = options.max_width = max(0, width)255        options.height = options.max_height = height256        return options257 258 259@runtime_checkable260class RichCast(Protocol):261    """An object that may be 'cast' to a console renderable."""262 263    def __rich__(264        self,265    ) -> Union["ConsoleRenderable", "RichCast", str]:  # pragma: no cover266        ...267 268 269@runtime_checkable270class ConsoleRenderable(Protocol):271    """An object that supports the console protocol."""272 273    def __rich_console__(274        self, console: "Console", options: "ConsoleOptions"275    ) -> "RenderResult":  # pragma: no cover276        ...277 278 279# A type that may be rendered by Console.280RenderableType = Union[ConsoleRenderable, RichCast, str]281"""A string or any object that may be rendered by Rich."""282 283# The result of calling a __rich_console__ method.284RenderResult = Iterable[Union[RenderableType, Segment]]285 286_null_highlighter = NullHighlighter()287 288 289class CaptureError(Exception):290    """An error in the Capture context manager."""291 292 293class NewLine:294    """A renderable to generate new line(s)"""295 296    def __init__(self, count: int = 1) -> None:297        self.count = count298 299    def __rich_console__(300        self, console: "Console", options: "ConsoleOptions"301    ) -> Iterable[Segment]:302        yield Segment("\n" * self.count)303 304 305class ScreenUpdate:306    """Render a list of lines at a given offset."""307 308    def __init__(self, lines: List[List[Segment]], x: int, y: int) -> None:309        self._lines = lines310        self.x = x311        self.y = y312 313    def __rich_console__(314        self, console: "Console", options: ConsoleOptions315    ) -> RenderResult:316        x = self.x317        move_to = Control.move_to318        for offset, line in enumerate(self._lines, self.y):319            yield move_to(x, offset)320            yield from line321 322 323class Capture:324    """Context manager to capture the result of printing to the console.325    See :meth:`~rich.console.Console.capture` for how to use.326 327    Args:328        console (Console): A console instance to capture output.329    """330 331    def __init__(self, console: "Console") -> None:332        self._console = console333        self._result: Optional[str] = None334 335    def __enter__(self) -> "Capture":336        self._console.begin_capture()337        return self338 339    def __exit__(340        self,341        exc_type: Optional[Type[BaseException]],342        exc_val: Optional[BaseException],343        exc_tb: Optional[TracebackType],344    ) -> None:345        self._result = self._console.end_capture()346 347    def get(self) -> str:348        """Get the result of the capture."""349        if self._result is None:350            raise CaptureError(351                "Capture result is not available until context manager exits."352            )353        return self._result354 355 356class ThemeContext:357    """A context manager to use a temporary theme. See :meth:`~rich.console.Console.use_theme` for usage."""358 359    def __init__(self, console: "Console", theme: Theme, inherit: bool = True) -> None:360        self.console = console361        self.theme = theme362        self.inherit = inherit363 364    def __enter__(self) -> "ThemeContext":365        self.console.push_theme(self.theme)366        return self367 368    def __exit__(369        self,370        exc_type: Optional[Type[BaseException]],371        exc_val: Optional[BaseException],372        exc_tb: Optional[TracebackType],373    ) -> None:374        self.console.pop_theme()375 376 377class PagerContext:378    """A context manager that 'pages' content. See :meth:`~rich.console.Console.pager` for usage."""379 380    def __init__(381        self,382        console: "Console",383        pager: Optional[Pager] = None,384        styles: bool = False,385        links: bool = False,386    ) -> None:387        self._console = console388        self.pager = SystemPager() if pager is None else pager389        self.styles = styles390        self.links = links391 392    def __enter__(self) -> "PagerContext":393        self._console._enter_buffer()394        return self395 396    def __exit__(397        self,398        exc_type: Optional[Type[BaseException]],399        exc_val: Optional[BaseException],400        exc_tb: Optional[TracebackType],401    ) -> None:402        if exc_type is None:403            with self._console._lock:404                buffer: List[Segment] = self._console._buffer[:]405                del self._console._buffer[:]406                segments: Iterable[Segment] = buffer407                if not self.styles:408                    segments = Segment.strip_styles(segments)409                elif not self.links:410                    segments = Segment.strip_links(segments)411                content = self._console._render_buffer(segments)412            self.pager.show(content)413        self._console._exit_buffer()414 415 416class ScreenContext:417    """A context manager that enables an alternative screen. See :meth:`~rich.console.Console.screen` for usage."""418 419    def __init__(420        self, console: "Console", hide_cursor: bool, style: StyleType = ""421    ) -> None:422        self.console = console423        self.hide_cursor = hide_cursor424        self.screen = Screen(style=style)425        self._changed = False426 427    def update(428        self, *renderables: RenderableType, style: Optional[StyleType] = None429    ) -> None:430        """Update the screen.431 432        Args:433            renderable (RenderableType, optional): Optional renderable to replace current renderable,434                or None for no change. Defaults to None.435            style: (Style, optional): Replacement style, or None for no change. Defaults to None.436        """437        if renderables:438            self.screen.renderable = (439                Group(*renderables) if len(renderables) > 1 else renderables[0]440            )441        if style is not None:442            self.screen.style = style443        self.console.print(self.screen, end="")444 445    def __enter__(self) -> "ScreenContext":446        self._changed = self.console.set_alt_screen(True)447        if self._changed and self.hide_cursor:448            self.console.show_cursor(False)449        return self450 451    def __exit__(452        self,453        exc_type: Optional[Type[BaseException]],454        exc_val: Optional[BaseException],455        exc_tb: Optional[TracebackType],456    ) -> None:457        if self._changed:458            self.console.set_alt_screen(False)459            if self.hide_cursor:460                self.console.show_cursor(True)461 462 463class Group:464    """Takes a group of renderables and returns a renderable object that renders the group.465 466    Args:467        renderables (Iterable[RenderableType]): An iterable of renderable objects.468        fit (bool, optional): Fit dimension of group to contents, or fill available space. Defaults to True.469    """470 471    def __init__(self, *renderables: "RenderableType", fit: bool = True) -> None:472        self._renderables = renderables473        self.fit = fit474        self._render: Optional[List[RenderableType]] = None475 476    @property477    def renderables(self) -> List["RenderableType"]:478        if self._render is None:479            self._render = list(self._renderables)480        return self._render481 482    def __rich_measure__(483        self, console: "Console", options: "ConsoleOptions"484    ) -> "Measurement":485        if self.fit:486            return measure_renderables(console, options, self.renderables)487        else:488            return Measurement(options.max_width, options.max_width)489 490    def __rich_console__(491        self, console: "Console", options: "ConsoleOptions"492    ) -> RenderResult:493        yield from self.renderables494 495 496def group(fit: bool = True) -> Callable[..., Callable[..., Group]]:497    """A decorator that turns an iterable of renderables in to a group.498 499    Args:500        fit (bool, optional): Fit dimension of group to contents, or fill available space. Defaults to True.501    """502 503    def decorator(504        method: Callable[..., Iterable[RenderableType]]505    ) -> Callable[..., Group]:506        """Convert a method that returns an iterable of renderables in to a Group."""507 508        @wraps(method)509        def _replace(*args: Any, **kwargs: Any) -> Group:510            renderables = method(*args, **kwargs)511            return Group(*renderables, fit=fit)512 513        return _replace514 515    return decorator516 517 518def _is_jupyter() -> bool:  # pragma: no cover519    """Check if we're running in a Jupyter notebook."""520    try:521        get_ipython  # type: ignore[name-defined]522    except NameError:523        return False524    ipython = get_ipython()  # type: ignore[name-defined]525    shell = ipython.__class__.__name__526    if (527        "google.colab" in str(ipython.__class__)528        or os.getenv("DATABRICKS_RUNTIME_VERSION")529        or shell == "ZMQInteractiveShell"530    ):531        return True  # Jupyter notebook or qtconsole532    elif shell == "TerminalInteractiveShell":533        return False  # Terminal running IPython534    else:535        return False  # Other type (?)536 537 538COLOR_SYSTEMS = {539    "standard": ColorSystem.STANDARD,540    "256": ColorSystem.EIGHT_BIT,541    "truecolor": ColorSystem.TRUECOLOR,542    "windows": ColorSystem.WINDOWS,543}544 545_COLOR_SYSTEMS_NAMES = {system: name for name, system in COLOR_SYSTEMS.items()}546 547 548@dataclass549class ConsoleThreadLocals(threading.local):550    """Thread local values for Console context."""551 552    theme_stack: ThemeStack553    buffer: List[Segment] = field(default_factory=list)554    buffer_index: int = 0555 556 557class RenderHook(ABC):558    """Provides hooks in to the render process."""559 560    @abstractmethod561    def process_renderables(562        self, renderables: List[ConsoleRenderable]563    ) -> List[ConsoleRenderable]:564        """Called with a list of objects to render.565 566        This method can return a new list of renderables, or modify and return the same list.567 568        Args:569            renderables (List[ConsoleRenderable]): A number of renderable objects.570 571        Returns:572            List[ConsoleRenderable]: A replacement list of renderables.573        """574 575 576_windows_console_features: Optional["WindowsConsoleFeatures"] = None577 578 579def get_windows_console_features() -> "WindowsConsoleFeatures":  # pragma: no cover580    global _windows_console_features581    if _windows_console_features is not None:582        return _windows_console_features583    from ._windows import get_windows_console_features584 585    _windows_console_features = get_windows_console_features()586    return _windows_console_features587 588 589def detect_legacy_windows() -> bool:590    """Detect legacy Windows."""591    return WINDOWS and not get_windows_console_features().vt592 593 594class Console:595    """A high level console interface.596 597    Args:598        color_system (str, optional): The color system supported by your terminal,599            either ``"standard"``, ``"256"`` or ``"truecolor"``. Leave as ``"auto"`` to autodetect.600        force_terminal (Optional[bool], optional): Enable/disable terminal control codes, or None to auto-detect terminal. Defaults to None.601        force_jupyter (Optional[bool], optional): Enable/disable Jupyter rendering, or None to auto-detect Jupyter. Defaults to None.602        force_interactive (Optional[bool], optional): Enable/disable interactive mode, or None to auto detect. Defaults to None.603        soft_wrap (Optional[bool], optional): Set soft wrap default on print method. Defaults to False.604        theme (Theme, optional): An optional style theme object, or ``None`` for default theme.605        stderr (bool, optional): Use stderr rather than stdout if ``file`` is not specified. Defaults to False.606        file (IO, optional): A file object where the console should write to. Defaults to stdout.607        quiet (bool, Optional): Boolean to suppress all output. Defaults to False.608        width (int, optional): The width of the terminal. Leave as default to auto-detect width.609        height (int, optional): The height of the terminal. Leave as default to auto-detect height.610        style (StyleType, optional): Style to apply to all output, or None for no style. Defaults to None.611        no_color (Optional[bool], optional): Enabled no color mode, or None to auto detect. Defaults to None.612        tab_size (int, optional): Number of spaces used to replace a tab character. Defaults to 8.613        record (bool, optional): Boolean to enable recording of terminal output,614            required to call :meth:`export_html`, :meth:`export_svg`, and :meth:`export_text`. Defaults to False.615        markup (bool, optional): Boolean to enable :ref:`console_markup`. Defaults to True.616        emoji (bool, optional): Enable emoji code. Defaults to True.617        emoji_variant (str, optional): Optional emoji variant, either "text" or "emoji". Defaults to None.618        highlight (bool, optional): Enable automatic highlighting. Defaults to True.619        log_time (bool, optional): Boolean to enable logging of time by :meth:`log` methods. Defaults to True.620        log_path (bool, optional): Boolean to enable the logging of the caller by :meth:`log`. Defaults to True.621        log_time_format (Union[str, TimeFormatterCallable], optional): If ``log_time`` is enabled, either string for strftime or callable that formats the time. Defaults to "[%X] ".622        highlighter (HighlighterType, optional): Default highlighter.623        legacy_windows (bool, optional): Enable legacy Windows mode, or ``None`` to auto detect. Defaults to ``None``.624        safe_box (bool, optional): Restrict box options that don't render on legacy Windows.625        get_datetime (Callable[[], datetime], optional): Callable that gets the current time as a datetime.datetime object (used by Console.log),626            or None for datetime.now.627        get_time (Callable[[], time], optional): Callable that gets the current time in seconds, default uses time.monotonic.628    """629 630    _environ: Mapping[str, str] = os.environ631 632    def __init__(633        self,634        *,635        color_system: Optional[636            Literal["auto", "standard", "256", "truecolor", "windows"]637        ] = "auto",638        force_terminal: Optional[bool] = None,639        force_jupyter: Optional[bool] = None,640        force_interactive: Optional[bool] = None,641        soft_wrap: bool = False,642        theme: Optional[Theme] = None,643        stderr: bool = False,644        file: Optional[IO[str]] = None,645        quiet: bool = False,646        width: Optional[int] = None,647        height: Optional[int] = None,648        style: Optional[StyleType] = None,649        no_color: Optional[bool] = None,650        tab_size: int = 8,651        record: bool = False,652        markup: bool = True,653        emoji: bool = True,654        emoji_variant: Optional[EmojiVariant] = None,655        highlight: bool = True,656        log_time: bool = True,657        log_path: bool = True,658        log_time_format: Union[str, FormatTimeCallable] = "[%X]",659        highlighter: Optional["HighlighterType"] = ReprHighlighter(),660        legacy_windows: Optional[bool] = None,661        safe_box: bool = True,662        get_datetime: Optional[Callable[[], datetime]] = None,663        get_time: Optional[Callable[[], float]] = None,664        _environ: Optional[Mapping[str, str]] = None,665    ):666        # Copy of os.environ allows us to replace it for testing667        if _environ is not None:668            self._environ = _environ669 670        self.is_jupyter = _is_jupyter() if force_jupyter is None else force_jupyter671        if self.is_jupyter:672            if width is None:673                jupyter_columns = self._environ.get("JUPYTER_COLUMNS")674                if jupyter_columns is not None and jupyter_columns.isdigit():675                    width = int(jupyter_columns)676                else:677                    width = JUPYTER_DEFAULT_COLUMNS678            if height is None:679                jupyter_lines = self._environ.get("JUPYTER_LINES")680                if jupyter_lines is not None and jupyter_lines.isdigit():681                    height = int(jupyter_lines)682                else:683                    height = JUPYTER_DEFAULT_LINES684 685        self.tab_size = tab_size686        self.record = record687        self._markup = markup688        self._emoji = emoji689        self._emoji_variant: Optional[EmojiVariant] = emoji_variant690        self._highlight = highlight691        self.legacy_windows: bool = (692            (detect_legacy_windows() and not self.is_jupyter)693            if legacy_windows is None694            else legacy_windows695        )696 697        if width is None:698            columns = self._environ.get("COLUMNS")699            if columns is not None and columns.isdigit():700                width = int(columns) - self.legacy_windows701        if height is None:702            lines = self._environ.get("LINES")703            if lines is not None and lines.isdigit():704                height = int(lines)705 706        self.soft_wrap = soft_wrap707        self._width = width708        self._height = height709 710        self._color_system: Optional[ColorSystem]711 712        self._force_terminal = None713        if force_terminal is not None:714            self._force_terminal = force_terminal715 716        self._file = file717        self.quiet = quiet718        self.stderr = stderr719 720        if color_system is None:721            self._color_system = None722        elif color_system == "auto":723            self._color_system = self._detect_color_system()724        else:725            self._color_system = COLOR_SYSTEMS[color_system]726 727        self._lock = threading.RLock()728        self._log_render = LogRender(729            show_time=log_time,730            show_path=log_path,731            time_format=log_time_format,732        )733        self.highlighter: HighlighterType = highlighter or _null_highlighter734        self.safe_box = safe_box735        self.get_datetime = get_datetime or datetime.now736        self.get_time = get_time or monotonic737        self.style = style738        self.no_color = (739            no_color if no_color is not None else "NO_COLOR" in self._environ740        )741        self.is_interactive = (742            (self.is_terminal and not self.is_dumb_terminal)743            if force_interactive is None744            else force_interactive745        )746 747        self._record_buffer_lock = threading.RLock()748        self._thread_locals = ConsoleThreadLocals(749            theme_stack=ThemeStack(themes.DEFAULT if theme is None else theme)750        )751        self._record_buffer: List[Segment] = []752        self._render_hooks: List[RenderHook] = []753        self._live: Optional["Live"] = None754        self._is_alt_screen = False755 756    def __repr__(self) -> str:757        return f"<console width={self.width} {self._color_system!s}>"758 759    @property760    def file(self) -> IO[str]:761        """Get the file object to write to."""762        file = self._file or (sys.stderr if self.stderr else sys.stdout)763        file = getattr(file, "rich_proxied_file", file)764        if file is None:765            file = NULL_FILE766        return file767 768    @file.setter769    def file(self, new_file: IO[str]) -> None:770        """Set a new file object."""771        self._file = new_file772 773    @property774    def _buffer(self) -> List[Segment]:775        """Get a thread local buffer."""776        return self._thread_locals.buffer777 778    @property779    def _buffer_index(self) -> int:780        """Get a thread local buffer."""781        return self._thread_locals.buffer_index782 783    @_buffer_index.setter784    def _buffer_index(self, value: int) -> None:785        self._thread_locals.buffer_index = value786 787    @property788    def _theme_stack(self) -> ThemeStack:789        """Get the thread local theme stack."""790        return self._thread_locals.theme_stack791 792    def _detect_color_system(self) -> Optional[ColorSystem]:793        """Detect color system from env vars."""794        if self.is_jupyter:795            return ColorSystem.TRUECOLOR796        if not self.is_terminal or self.is_dumb_terminal:797            return None798        if WINDOWS:  # pragma: no cover799            if self.legacy_windows:  # pragma: no cover800                return ColorSystem.WINDOWS801            windows_console_features = get_windows_console_features()802            return (803                ColorSystem.TRUECOLOR804                if windows_console_features.truecolor805                else ColorSystem.EIGHT_BIT806            )807        else:808            color_term = self._environ.get("COLORTERM", "").strip().lower()809            if color_term in ("truecolor", "24bit"):810                return ColorSystem.TRUECOLOR811            term = self._environ.get("TERM", "").strip().lower()812            _term_name, _hyphen, colors = term.rpartition("-")813            color_system = _TERM_COLORS.get(colors, ColorSystem.STANDARD)814            return color_system815 816    def _enter_buffer(self) -> None:817        """Enter in to a buffer context, and buffer all output."""818        self._buffer_index += 1819 820    def _exit_buffer(self) -> None:821        """Leave buffer context, and render content if required."""822        self._buffer_index -= 1823        self._check_buffer()824 825    def set_live(self, live: "Live") -> None:826        """Set Live instance. Used by Live context manager.827 828        Args:829            live (Live): Live instance using this Console.830 831        Raises:832            errors.LiveError: If this Console has a Live context currently active.833        """834        with self._lock:835            if self._live is not None:836                raise errors.LiveError("Only one live display may be active at once")837            self._live = live838 839    def clear_live(self) -> None:840        """Clear the Live instance."""841        with self._lock:842            self._live = None843 844    def push_render_hook(self, hook: RenderHook) -> None:845        """Add a new render hook to the stack.846 847        Args:848            hook (RenderHook): Render hook instance.849        """850        with self._lock:851            self._render_hooks.append(hook)852 853    def pop_render_hook(self) -> None:854        """Pop the last renderhook from the stack."""855        with self._lock:856            self._render_hooks.pop()857 858    def __enter__(self) -> "Console":859        """Own context manager to enter buffer context."""860        self._enter_buffer()861        return self862 863    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:864        """Exit buffer context."""865        self._exit_buffer()866 867    def begin_capture(self) -> None:868        """Begin capturing console output. Call :meth:`end_capture` to exit capture mode and return output."""869        self._enter_buffer()870 871    def end_capture(self) -> str:872        """End capture mode and return captured string.873 874        Returns:875            str: Console output.876        """877        render_result = self._render_buffer(self._buffer)878        del self._buffer[:]879        self._exit_buffer()880        return render_result881 882    def push_theme(self, theme: Theme, *, inherit: bool = True) -> None:883        """Push a new theme on to the top of the stack, replacing the styles from the previous theme.884        Generally speaking, you should call :meth:`~rich.console.Console.use_theme` to get a context manager, rather885        than calling this method directly.886 887        Args:888            theme (Theme): A theme instance.889            inherit (bool, optional): Inherit existing styles. Defaults to True.890        """891        self._theme_stack.push_theme(theme, inherit=inherit)892 893    def pop_theme(self) -> None:894        """Remove theme from top of stack, restoring previous theme."""895        self._theme_stack.pop_theme()896 897    def use_theme(self, theme: Theme, *, inherit: bool = True) -> ThemeContext:898        """Use a different theme for the duration of the context manager.899 900        Args:901            theme (Theme): Theme instance to user.902            inherit (bool, optional): Inherit existing console styles. Defaults to True.903 904        Returns:905            ThemeContext: [description]906        """907        return ThemeContext(self, theme, inherit)908 909    @property910    def color_system(self) -> Optional[str]:911        """Get color system string.912 913        Returns:914            Optional[str]: "standard", "256" or "truecolor".915        """916 917        if self._color_system is not None:918            return _COLOR_SYSTEMS_NAMES[self._color_system]919        else:920            return None921 922    @property923    def encoding(self) -> str:924        """Get the encoding of the console file, e.g. ``"utf-8"``.925 926        Returns:927            str: A standard encoding string.928        """929        return (getattr(self.file, "encoding", "utf-8") or "utf-8").lower()930 931    @property932    def is_terminal(self) -> bool:933        """Check if the console is writing to a terminal.934 935        Returns:936            bool: True if the console writing to a device capable of937            understanding terminal codes, otherwise False.938        """939        if self._force_terminal is not None:940            return self._force_terminal941 942        if hasattr(sys.stdin, "__module__") and sys.stdin.__module__.startswith(943            "idlelib"944        ):945            # Return False for Idle which claims to be a tty but can't handle ansi codes946            return False947 948        if self.is_jupyter:949            # return False for Jupyter, which may have FORCE_COLOR set950            return False951 952        # If FORCE_COLOR env var has any value at all, we assume a terminal.953        force_color = self._environ.get("FORCE_COLOR")954        if force_color is not None:955            self._force_terminal = True956            return True957 958        isatty: Optional[Callable[[], bool]] = getattr(self.file, "isatty", None)959        try:960            return False if isatty is None else isatty()961        except ValueError:962            # in some situation (at the end of a pytest run for example) isatty() can raise963            # ValueError: I/O operation on closed file964            # return False because we aren't in a terminal anymore965            return False966 967    @property968    def is_dumb_terminal(self) -> bool:969        """Detect dumb terminal.970 971        Returns:972            bool: True if writing to a dumb terminal, otherwise False.973 974        """975        _term = self._environ.get("TERM", "")976        is_dumb = _term.lower() in ("dumb", "unknown")977        return self.is_terminal and is_dumb978 979    @property980    def options(self) -> ConsoleOptions:981        """Get default console options."""982        return ConsoleOptions(983            max_height=self.size.height,984            size=self.size,985            legacy_windows=self.legacy_windows,986            min_width=1,987            max_width=self.width,988            encoding=self.encoding,989            is_terminal=self.is_terminal,990        )991 992    @property993    def size(self) -> ConsoleDimensions:994        """Get the size of the console.995 996        Returns:997            ConsoleDimensions: A named tuple containing the dimensions.998        """999 1000        if self._width is not None and self._height is not None:1001            return ConsoleDimensions(self._width - self.legacy_windows, self._height)1002 1003        if self.is_dumb_terminal:1004            return ConsoleDimensions(80, 25)1005 1006        width: Optional[int] = None1007        height: Optional[int] = None1008 1009        if WINDOWS:  # pragma: no cover1010            try:1011                width, height = os.get_terminal_size()1012            except (AttributeError, ValueError, OSError):  # Probably not a terminal1013                pass1014        else:1015            for file_descriptor in _STD_STREAMS:1016                try:1017                    width, height = os.get_terminal_size(file_descriptor)1018                except (AttributeError, ValueError, OSError):1019                    pass1020                else:1021                    break1022 1023        columns = self._environ.get("COLUMNS")1024        if columns is not None and columns.isdigit():1025            width = int(columns)1026        lines = self._environ.get("LINES")1027        if lines is not None and lines.isdigit():1028            height = int(lines)1029 1030        # get_terminal_size can report 0, 0 if run from pseudo-terminal1031        width = width or 801032        height = height or 251033        return ConsoleDimensions(1034            width - self.legacy_windows if self._width is None else self._width,1035            height if self._height is None else self._height,1036        )1037 1038    @size.setter1039    def size(self, new_size: Tuple[int, int]) -> None:1040        """Set a new size for the terminal.1041 1042        Args:1043            new_size (Tuple[int, int]): New width and height.1044        """1045        width, height = new_size1046        self._width = width1047        self._height = height1048 1049    @property1050    def width(self) -> int:1051        """Get the width of the console.1052 1053        Returns:1054            int: The width (in characters) of the console.1055        """1056        return self.size.width1057 1058    @width.setter1059    def width(self, width: int) -> None:1060        """Set width.1061 1062        Args:1063            width (int): New width.1064        """1065        self._width = width1066 1067    @property1068    def height(self) -> int:1069        """Get the height of the console.1070 1071        Returns:1072            int: The height (in lines) of the console.1073        """1074        return self.size.height1075 1076    @height.setter1077    def height(self, height: int) -> None:1078        """Set height.1079 1080        Args:1081            height (int): new height.1082        """1083        self._height = height1084 1085    def bell(self) -> None:1086        """Play a 'bell' sound (if supported by the terminal)."""1087        self.control(Control.bell())1088 1089    def capture(self) -> Capture:1090        """A context manager to *capture* the result of print() or log() in a string,1091        rather than writing it to the console.1092 1093        Example:1094            >>> from rich.console import Console1095            >>> console = Console()1096            >>> with console.capture() as capture:1097            ...     console.print("[bold magenta]Hello World[/]")1098            >>> print(capture.get())1099 1100        Returns:1101            Capture: Context manager with disables writing to the terminal.1102        """1103        capture = Capture(self)1104        return capture1105 1106    def pager(1107        self, pager: Optional[Pager] = None, styles: bool = False, links: bool = False1108    ) -> PagerContext:1109        """A context manager to display anything printed within a "pager". The pager application1110        is defined by the system and will typically support at least pressing a key to scroll.1111 1112        Args:1113            pager (Pager, optional): A pager object, or None to use :class:`~rich.pager.SystemPager`. Defaults to None.1114            styles (bool, optional): Show styles in pager. Defaults to False.1115            links (bool, optional): Show links in pager. Defaults to False.1116 1117        Example:1118            >>> from rich.console import Console1119            >>> from rich.__main__ import make_test_card1120            >>> console = Console()1121            >>> with console.pager():1122                    console.print(make_test_card())1123 1124        Returns:1125            PagerContext: A context manager.1126        """1127        return PagerContext(self, pager=pager, styles=styles, links=links)1128 1129    def line(self, count: int = 1) -> None:1130        """Write new line(s).1131 1132        Args:1133            count (int, optional): Number of new lines. Defaults to 1.1134        """1135 1136        assert count >= 0, "count must be >= 0"1137        self.print(NewLine(count))1138 1139    def clear(self, home: bool = True) -> None:1140        """Clear the screen.1141 1142        Args:1143            home (bool, optional): Also move the cursor to 'home' position. Defaults to True.1144        """1145        if home:1146            self.control(Control.clear(), Control.home())1147        else:1148            self.control(Control.clear())1149 1150    def status(1151        self,1152        status: RenderableType,1153        *,1154        spinner: str = "dots",1155        spinner_style: StyleType = "status.spinner",1156        speed: float = 1.0,1157        refresh_per_second: float = 12.5,1158    ) -> "Status":1159        """Display a status and spinner.1160 1161        Args:1162            status (RenderableType): A status renderable (str or Text typically).1163            spinner (str, optional): Name of spinner animation (see python -m rich.spinner). Defaults to "dots".1164            spinner_style (StyleType, optional): Style of spinner. Defaults to "status.spinner".1165            speed (float, optional): Speed factor for spinner animation. Defaults to 1.0.1166            refresh_per_second (float, optional): Number of refreshes per second. Defaults to 12.5.1167 1168        Returns:1169            Status: A Status object that may be used as a context manager.1170        """1171        from .status import Status1172 1173        status_renderable = Status(1174            status,1175            console=self,1176            spinner=spinner,1177            spinner_style=spinner_style,1178            speed=speed,1179            refresh_per_second=refresh_per_second,1180        )1181        return status_renderable1182 1183    def show_cursor(self, show: bool = True) -> bool:1184        """Show or hide the cursor.1185 1186        Args:1187            show (bool, optional): Set visibility of the cursor.1188        """1189        if self.is_terminal:1190            self.control(Control.show_cursor(show))1191            return True1192        return False1193 1194    def set_alt_screen(self, enable: bool = True) -> bool:1195        """Enables alternative screen mode.1196 1197        Note, if you enable this mode, you should ensure that is disabled before1198        the application exits. See :meth:`~rich.Console.screen` for a context manager1199        that handles this for you.1200 

Showing the first 1,200 of 2634 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai