Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
context.py218 linesDownload Raw Back to httpie
1import argparse2import sys3import os4import warnings5from contextlib import contextmanager6from pathlib import Path7from typing import Iterator, IO, Optional, TYPE_CHECKING8from enum import Enum9 10 11try:12    import curses13except ImportError:14    curses = None  # Compiled w/o curses15 16from .compat import is_windows, cached_property17from .config import DEFAULT_CONFIG_DIR, Config, ConfigFileError18from .encoding import UTF819 20from .utils import repr_dict21from .output.ui.palette import GenericColor22 23if TYPE_CHECKING:24    from rich.console import Console25 26 27class LogLevel(str, Enum):28    INFO = 'info'29    WARNING = 'warning'30    ERROR = 'error'31 32 33LOG_LEVEL_COLORS = {34    LogLevel.INFO: GenericColor.PINK,35    LogLevel.WARNING: GenericColor.ORANGE,36    LogLevel.ERROR: GenericColor.RED,37}38 39LOG_LEVEL_DISPLAY_THRESHOLDS = {40    LogLevel.INFO: 1,41    LogLevel.WARNING: 2,42    LogLevel.ERROR: float('inf'),  # Never hide errors.43}44 45 46class Environment:47    """48    Information about the execution context49    (standard streams, config directory, etc).50 51    By default, it represents the actual environment.52    All of the attributes can be overwritten though, which53    is used by the test suite to simulate various scenarios.54 55    """56    args = argparse.Namespace()57    is_windows: bool = is_windows58    config_dir: Path = DEFAULT_CONFIG_DIR59    stdin: Optional[IO] = sys.stdin  # `None` when closed fd (#791)60    stdin_isatty: bool = stdin.isatty() if stdin else False61    stdin_encoding: str = None62    stdout: IO = sys.stdout63    stdout_isatty: bool = stdout.isatty()64    stdout_encoding: str = None65    stderr: IO = sys.stderr66    stderr_isatty: bool = stderr.isatty()67    colors = 25668    program_name: str = 'http'69 70    # Whether to show progress bars / status spinners etc.71    show_displays: bool = True72 73    if not is_windows:74        if curses:75            try:76                curses.setupterm()77                colors = curses.tigetnum('colors')78            except curses.error:79                pass80    else:81        # noinspection PyUnresolvedReferences82        import colorama.initialise83        stdout = colorama.initialise.wrap_stream(84            stdout, convert=None, strip=None,85            autoreset=True, wrap=True86        )87        stderr = colorama.initialise.wrap_stream(88            stderr, convert=None, strip=None,89            autoreset=True, wrap=True90        )91        del colorama92 93    def __init__(self, devnull=None, **kwargs):94        """95        Use keyword arguments to overwrite96        any of the class attributes for this instance.97 98        """99        assert all(hasattr(type(self), attr) for attr in kwargs.keys())100        self.__dict__.update(**kwargs)101 102        # The original STDERR unaffected by --quiet’ing.103        self._orig_stderr = self.stderr104        self._devnull = devnull105 106        # Keyword arguments > stream.encoding > default UTF-8107        if self.stdin and self.stdin_encoding is None:108            self.stdin_encoding = getattr(109                self.stdin, 'encoding', None) or UTF8110        if self.stdout_encoding is None:111            actual_stdout = self.stdout112            if is_windows:113                # noinspection PyUnresolvedReferences114                from colorama import AnsiToWin32115                if isinstance(self.stdout, AnsiToWin32):116                    # noinspection PyUnresolvedReferences117                    actual_stdout = self.stdout.wrapped118            self.stdout_encoding = getattr(119                actual_stdout, 'encoding', None) or UTF8120 121        self.quiet = kwargs.pop('quiet', 0)122 123    def __str__(self):124        defaults = dict(type(self).__dict__)125        actual = dict(defaults)126        actual.update(self.__dict__)127        actual['config'] = self.config128        return repr_dict({129            key: value130            for key, value in actual.items()131            if not key.startswith('_')132        })133 134    def __repr__(self):135        return f'<{type(self).__name__} {self}>'136 137    _config: Config = None138 139    @property140    def config(self) -> Config:141        config = self._config142        if not config:143            self._config = config = Config(directory=self.config_dir)144            if not config.is_new():145                try:146                    config.load()147                except ConfigFileError as e:148                    self.log_error(e, level=LogLevel.WARNING)149        return config150 151    @property152    def devnull(self) -> IO:153        if self._devnull is None:154            self._devnull = open(os.devnull, 'w+')155        return self._devnull156 157    @contextmanager158    def as_silent(self) -> Iterator[None]:159        original_stdout = self.stdout160        original_stderr = self.stderr161 162        try:163            self.stdout = self.devnull164            self.stderr = self.devnull165            yield166        finally:167            self.stdout = original_stdout168            self.stderr = original_stderr169 170    def log_error(self, msg: str, level: LogLevel = LogLevel.ERROR) -> None:171        if self.stdout_isatty and self.quiet >= LOG_LEVEL_DISPLAY_THRESHOLDS[level]:172            stderr = self.stderr  # Not directly /dev/null, since stderr might be mocked173        else:174            stderr = self._orig_stderr175        rich_console = self._make_rich_console(file=stderr, force_terminal=stderr.isatty())176        rich_console.print(177            f'\n{self.program_name}: {level.value}: {msg}\n\n',178            style=LOG_LEVEL_COLORS[level],179            markup=False,180            highlight=False,181            soft_wrap=True182        )183 184    def apply_warnings_filter(self) -> None:185        if self.quiet >= LOG_LEVEL_DISPLAY_THRESHOLDS[LogLevel.WARNING]:186            warnings.simplefilter("ignore")187 188    def _make_rich_console(189        self,190        file: IO[str],191        force_terminal: bool192    ) -> 'Console':193        from rich.console import Console194        from httpie.output.ui.rich_palette import _make_rich_color_theme195 196        style = getattr(self.args, 'style', None)197        theme = _make_rich_color_theme(style)198        # Rich infers the rest of the knowledge (e.g encoding)199        # dynamically by looking at the file/stderr.200        return Console(201            file=file,202            force_terminal=force_terminal,203            no_color=(self.colors == 0),204            theme=theme205        )206 207    # Rich recommends separating the actual console (stdout) from208    # the error (stderr) console for better isolation between parts.209    # https://rich.readthedocs.io/en/stable/console.html#error-console210 211    @cached_property212    def rich_console(self):213        return self._make_rich_console(self.stdout, self.stdout_isatty)214 215    @cached_property216    def rich_error_console(self):217        return self._make_rich_console(self.stderr, self.stderr_isatty)218 
codekingpro/portable-devtools · Team Ai