Buckets:
MisterAI/LocalAI_Demo_backends / cpu-diffusers.upgrade-tmp /venv /lib /python3.10 /site-packages /rich /pretty.py
| import builtins | |
| import collections | |
| import dataclasses | |
| import inspect | |
| import os | |
| import reprlib | |
| import sys | |
| from array import array | |
| from collections import Counter, UserDict, UserList, defaultdict, deque | |
| from dataclasses import dataclass, fields, is_dataclass | |
| from inspect import isclass | |
| from itertools import islice | |
| from types import MappingProxyType | |
| from typing import ( | |
| TYPE_CHECKING, | |
| Any, | |
| Callable, | |
| DefaultDict, | |
| Deque, | |
| Dict, | |
| Iterable, | |
| List, | |
| Optional, | |
| Sequence, | |
| Set, | |
| Tuple, | |
| Union, | |
| ) | |
| from rich.repr import RichReprResult | |
| try: | |
| import attr as _attr_module | |
| _has_attrs = hasattr(_attr_module, "ib") | |
| except ImportError: # pragma: no cover | |
| _has_attrs = False | |
| from . import get_console | |
| from ._loop import loop_last | |
| from ._pick import pick_bool | |
| from .abc import RichRenderable | |
| from .cells import cell_len | |
| from .highlighter import ReprHighlighter | |
| from .jupyter import JupyterMixin, JupyterRenderable | |
| from .measure import Measurement | |
| from .text import Text | |
| if TYPE_CHECKING: | |
| from .console import ( | |
| Console, | |
| ConsoleOptions, | |
| HighlighterType, | |
| JustifyMethod, | |
| OverflowMethod, | |
| RenderResult, | |
| ) | |
| def _is_attr_object(obj: Any) -> bool: | |
| """Check if an object was created with attrs module.""" | |
| return _has_attrs and _attr_module.has(type(obj)) | |
| def _get_attr_fields(obj: Any) -> Sequence["_attr_module.Attribute[Any]"]: | |
| """Get fields for an attrs object.""" | |
| return _attr_module.fields(type(obj)) if _has_attrs else [] | |
| def _is_dataclass_repr(obj: object) -> bool: | |
| """Check if an instance of a dataclass contains the default repr. | |
| Args: | |
| obj (object): A dataclass instance. | |
| Returns: | |
| bool: True if the default repr is used, False if there is a custom repr. | |
| """ | |
| # Digging in to a lot of internals here | |
| # Catching all exceptions in case something is missing on a non CPython implementation | |
| try: | |
| return obj.__repr__.__code__.co_filename in ( | |
| dataclasses.__file__, | |
| reprlib.__file__, | |
| ) | |
| except Exception: # pragma: no coverage | |
| return False | |
| _dummy_namedtuple = collections.namedtuple("_dummy_namedtuple", []) | |
| def _has_default_namedtuple_repr(obj: object) -> bool: | |
| """Check if an instance of namedtuple contains the default repr | |
| Args: | |
| obj (object): A namedtuple | |
| Returns: | |
| bool: True if the default repr is used, False if there's a custom repr. | |
| """ | |
| obj_file = None | |
| try: | |
| obj_file = inspect.getfile(obj.__repr__) | |
| except (OSError, TypeError): | |
| # OSError handles case where object is defined in __main__ scope, e.g. REPL - no filename available. | |
| # TypeError trapped defensively, in case of object without filename slips through. | |
| pass | |
| default_repr_file = inspect.getfile(_dummy_namedtuple.__repr__) | |
| return obj_file == default_repr_file | |
| def _ipy_display_hook( | |
| value: Any, | |
| console: Optional["Console"] = None, | |
| overflow: "OverflowMethod" = "ignore", | |
| crop: bool = False, | |
| indent_guides: bool = False, | |
| max_length: Optional[int] = None, | |
| max_string: Optional[int] = None, | |
| max_depth: Optional[int] = None, | |
| expand_all: bool = False, | |
| ) -> Union[str, None]: | |
| # needed here to prevent circular import: | |
| from .console import ConsoleRenderable | |
| # always skip rich generated jupyter renderables or None values | |
| if _safe_isinstance(value, JupyterRenderable) or value is None: | |
| return None | |
| console = console or get_console() | |
| with console.capture() as capture: | |
| # certain renderables should start on a new line | |
| if _safe_isinstance(value, ConsoleRenderable): | |
| console.line() | |
| console.print( | |
| ( | |
| value | |
| if _safe_isinstance(value, RichRenderable) | |
| else Pretty( | |
| value, | |
| overflow=overflow, | |
| indent_guides=indent_guides, | |
| max_length=max_length, | |
| max_string=max_string, | |
| max_depth=max_depth, | |
| expand_all=expand_all, | |
| margin=12, | |
| ) | |
| ), | |
| crop=crop, | |
| new_line_start=True, | |
| end="", | |
| ) | |
| # strip trailing newline, not usually part of a text repr | |
| # I'm not sure if this should be prevented at a lower level | |
| return capture.get().rstrip("\n") | |
| def _safe_isinstance( | |
| obj: object, class_or_tuple: Union[type, Tuple[type, ...]] | |
| ) -> bool: | |
| """isinstance can fail in rare cases, for example types with no __class__""" | |
| try: | |
| return isinstance(obj, class_or_tuple) | |
| except Exception: | |
| return False | |
| def install( | |
| console: Optional["Console"] = None, | |
| overflow: "OverflowMethod" = "ignore", | |
| crop: bool = False, | |
| indent_guides: bool = False, | |
| max_length: Optional[int] = None, | |
| max_string: Optional[int] = None, | |
| max_depth: Optional[int] = None, | |
| expand_all: bool = False, | |
| ) -> None: | |
| """Install automatic pretty printing in the Python REPL. | |
| Args: | |
| console (Console, optional): Console instance or ``None`` to use global console. Defaults to None. | |
| overflow (Optional[OverflowMethod], optional): Overflow method. Defaults to "ignore". | |
| crop (Optional[bool], optional): Enable cropping of long lines. Defaults to False. | |
| indent_guides (bool, optional): Enable indentation guides. Defaults to False. | |
| max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation. | |
| Defaults to None. | |
| max_string (int, optional): Maximum length of string before truncating, or None to disable. Defaults to None. | |
| max_depth (int, optional): Maximum depth of nested data structures, or None for no maximum. Defaults to None. | |
| expand_all (bool, optional): Expand all containers. Defaults to False. | |
| max_frames (int): Maximum number of frames to show in a traceback, 0 for no maximum. Defaults to 100. | |
| """ | |
| from rich import get_console | |
| console = console or get_console() | |
| assert console is not None | |
| def display_hook(value: Any) -> None: | |
| """Replacement sys.displayhook which prettifies objects with Rich.""" | |
| if value is not None: | |
| assert console is not None | |
| builtins._ = None # type: ignore[attr-defined] | |
| console.print( | |
| ( | |
| value | |
| if _safe_isinstance(value, RichRenderable) | |
| else Pretty( | |
| value, | |
| overflow=overflow, | |
| indent_guides=indent_guides, | |
| max_length=max_length, | |
| max_string=max_string, | |
| max_depth=max_depth, | |
| expand_all=expand_all, | |
| ) | |
| ), | |
| crop=crop, | |
| ) | |
| builtins._ = value # type: ignore[attr-defined] | |
| try: | |
| ip = get_ipython() # type: ignore[name-defined] | |
| except NameError: | |
| sys.displayhook = display_hook | |
| else: | |
| from IPython.core.formatters import BaseFormatter | |
| class RichFormatter(BaseFormatter): # type: ignore[misc] | |
| pprint: bool = True | |
| def __call__(self, value: Any) -> Any: | |
| if self.pprint: | |
| return _ipy_display_hook( | |
| value, | |
| console=console, | |
| overflow=overflow, | |
| indent_guides=indent_guides, | |
| max_length=max_length, | |
| max_string=max_string, | |
| max_depth=max_depth, | |
| expand_all=expand_all, | |
| ) | |
| else: | |
| return repr(value) | |
| # replace plain text formatter with rich formatter | |
| rich_formatter = RichFormatter() | |
| ip.display_formatter.formatters["text/plain"] = rich_formatter | |
| class Pretty(JupyterMixin): | |
| """A rich renderable that pretty prints an object. | |
| Args: | |
| _object (Any): An object to pretty print. | |
| highlighter (HighlighterType, optional): Highlighter object to apply to result, or None for ReprHighlighter. Defaults to None. | |
| indent_size (int, optional): Number of spaces in indent. Defaults to 4. | |
| justify (JustifyMethod, optional): Justify method, or None for default. Defaults to None. | |
| overflow (OverflowMethod, optional): Overflow method, or None for default. Defaults to None. | |
| no_wrap (Optional[bool], optional): Disable word wrapping. Defaults to False. | |
| indent_guides (bool, optional): Enable indentation guides. Defaults to False. | |
| max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation. | |
| Defaults to None. | |
| max_string (int, optional): Maximum length of string before truncating, or None to disable. Defaults to None. | |
| max_depth (int, optional): Maximum depth of nested data structures, or None for no maximum. Defaults to None. | |
| expand_all (bool, optional): Expand all containers. Defaults to False. | |
| margin (int, optional): Subtrace a margin from width to force containers to expand earlier. Defaults to 0. | |
| insert_line (bool, optional): Insert a new line if the output has multiple new lines. Defaults to False. | |
| """ | |
| def __init__( | |
| self, | |
| _object: Any, | |
| highlighter: Optional["HighlighterType"] = None, | |
| *, | |
| indent_size: int = 4, | |
| justify: Optional["JustifyMethod"] = None, | |
| overflow: Optional["OverflowMethod"] = None, | |
| no_wrap: Optional[bool] = False, | |
| indent_guides: bool = False, | |
| max_length: Optional[int] = None, | |
| max_string: Optional[int] = None, | |
| max_depth: Optional[int] = None, | |
| expand_all: bool = False, | |
| margin: int = 0, | |
| insert_line: bool = False, | |
| ) -> None: | |
| self._object = _object | |
| self.highlighter = highlighter or ReprHighlighter() | |
| self.indent_size = indent_size | |
| self.justify: Optional["JustifyMethod"] = justify | |
| self.overflow: Optional["OverflowMethod"] = overflow | |
| self.no_wrap = no_wrap | |
| self.indent_guides = indent_guides | |
| self.max_length = max_length | |
| self.max_string = max_string | |
| self.max_depth = max_depth | |
| self.expand_all = expand_all | |
| self.margin = margin | |
| self.insert_line = insert_line | |
| def __rich_console__( | |
| self, console: "Console", options: "ConsoleOptions" | |
| ) -> "RenderResult": | |
| pretty_str = pretty_repr( | |
| self._object, | |
| max_width=options.max_width - self.margin, | |
| indent_size=self.indent_size, | |
| max_length=self.max_length, | |
| max_string=self.max_string, | |
| max_depth=self.max_depth, | |
| expand_all=self.expand_all, | |
| ) | |
| pretty_text = Text.from_ansi( | |
| pretty_str, | |
| justify=self.justify or options.justify, | |
| overflow=self.overflow or options.overflow, | |
| no_wrap=pick_bool(self.no_wrap, options.no_wrap), | |
| style="pretty", | |
| ) | |
| pretty_text = ( | |
| self.highlighter(pretty_text) | |
| if pretty_text | |
| else Text( | |
| f"{type(self._object)}.__repr__ returned empty string", | |
| style="dim italic", | |
| ) | |
| ) | |
| if self.indent_guides and not options.ascii_only: | |
| pretty_text = pretty_text.with_indent_guides( | |
| self.indent_size, style="repr.indent" | |
| ) | |
| if self.insert_line and "\n" in pretty_text: | |
| yield "" | |
| yield pretty_text | |
| def __rich_measure__( | |
| self, console: "Console", options: "ConsoleOptions" | |
| ) -> "Measurement": | |
| pretty_str = pretty_repr( | |
| self._object, | |
| max_width=options.max_width, | |
| indent_size=self.indent_size, | |
| max_length=self.max_length, | |
| max_string=self.max_string, | |
| max_depth=self.max_depth, | |
| expand_all=self.expand_all, | |
| ) | |
| text_width = ( | |
| max(cell_len(line) for line in pretty_str.splitlines()) if pretty_str else 0 | |
| ) | |
| return Measurement(text_width, text_width) | |
| def _get_braces_for_defaultdict(_object: DefaultDict[Any, Any]) -> Tuple[str, str, str]: | |
| return ( | |
| f"defaultdict({_object.default_factory!r}, {{", | |
| "})", | |
| f"defaultdict({_object.default_factory!r}, {{}})", | |
| ) | |
| def _get_braces_for_deque(_object: Deque[Any]) -> Tuple[str, str, str]: | |
| if _object.maxlen is None: | |
| return ("deque([", "])", "deque()") | |
| return ( | |
| "deque([", | |
| f"], maxlen={_object.maxlen})", | |
| f"deque(maxlen={_object.maxlen})", | |
| ) | |
| def _get_braces_for_array(_object: "array[Any]") -> Tuple[str, str, str]: | |
| return (f"array({_object.typecode!r}, [", "])", f"array({_object.typecode!r})") | |
| _BRACES: Dict[type, Callable[[Any], Tuple[str, str, str]]] = { | |
| os._Environ: lambda _object: ("environ({", "})", "environ({})"), | |
| array: _get_braces_for_array, | |
| defaultdict: _get_braces_for_defaultdict, | |
| Counter: lambda _object: ("Counter({", "})", "Counter()"), | |
| deque: _get_braces_for_deque, | |
| dict: lambda _object: ("{", "}", "{}"), | |
| UserDict: lambda _object: ("{", "}", "{}"), | |
| frozenset: lambda _object: ("frozenset({", "})", "frozenset()"), | |
| list: lambda _object: ("[", "]", "[]"), | |
| UserList: lambda _object: ("[", "]", "[]"), | |
| set: lambda _object: ("{", "}", "set()"), | |
| tuple: lambda _object: ("(", ")", "()"), | |
| MappingProxyType: lambda _object: ("mappingproxy({", "})", "mappingproxy({})"), | |
| } | |
| _CONTAINERS = tuple(_BRACES.keys()) | |
| _MAPPING_CONTAINERS = (dict, os._Environ, MappingProxyType, UserDict) | |
| def is_expandable(obj: Any) -> bool: | |
| """Check if an object may be expanded by pretty print.""" | |
| return ( | |
| _safe_isinstance(obj, _CONTAINERS) | |
| or (is_dataclass(obj)) | |
| or (hasattr(obj, "__rich_repr__")) | |
| or _is_attr_object(obj) | |
| ) and not isclass(obj) | |
| class Node: | |
| """A node in a repr tree. May be atomic or a container.""" | |
| key_repr: str = "" | |
| value_repr: str = "" | |
| open_brace: str = "" | |
| close_brace: str = "" | |
| empty: str = "" | |
| last: bool = False | |
| is_tuple: bool = False | |
| is_namedtuple: bool = False | |
| children: Optional[List["Node"]] = None | |
| key_separator: str = ": " | |
| separator: str = ", " | |
| def iter_tokens(self) -> Iterable[str]: | |
| """Generate tokens for this node.""" | |
| if self.key_repr: | |
| yield self.key_repr | |
| yield self.key_separator | |
| if self.value_repr: | |
| yield self.value_repr | |
| elif self.children is not None: | |
| if self.children: | |
| yield self.open_brace | |
| if self.is_tuple and not self.is_namedtuple and len(self.children) == 1: | |
| yield from self.children[0].iter_tokens() | |
| yield "," | |
| else: | |
| for child in self.children: | |
| yield from child.iter_tokens() | |
| if not child.last: | |
| yield self.separator | |
| yield self.close_brace | |
| else: | |
| yield self.empty | |
| def check_length(self, start_length: int, max_length: int) -> bool: | |
| """Check the length fits within a limit. | |
| Args: | |
| start_length (int): Starting length of the line (indent, prefix, suffix). | |
| max_length (int): Maximum length. | |
| Returns: | |
| bool: True if the node can be rendered within max length, otherwise False. | |
| """ | |
| total_length = start_length | |
| for token in self.iter_tokens(): | |
| total_length += cell_len(token) | |
| if total_length > max_length: | |
| return False | |
| return True | |
| def __str__(self) -> str: | |
| repr_text = "".join(self.iter_tokens()) | |
| return repr_text | |
| def render( | |
| self, max_width: int = 80, indent_size: int = 4, expand_all: bool = False | |
| ) -> str: | |
| """Render the node to a pretty repr. | |
| Args: | |
| max_width (int, optional): Maximum width of the repr. Defaults to 80. | |
| indent_size (int, optional): Size of indents. Defaults to 4. | |
| expand_all (bool, optional): Expand all levels. Defaults to False. | |
| Returns: | |
| str: A repr string of the original object. | |
| """ | |
| lines = [_Line(node=self, is_root=True)] | |
| line_no = 0 | |
| while line_no < len(lines): | |
| line = lines[line_no] | |
| if line.expandable and not line.expanded: | |
| if expand_all or not line.check_length(max_width): | |
| lines[line_no : line_no + 1] = line.expand(indent_size) | |
| line_no += 1 | |
| repr_str = "\n".join(str(line) for line in lines) | |
| return repr_str | |
| class _Line: | |
| """A line in repr output.""" | |
| parent: Optional["_Line"] = None | |
| is_root: bool = False | |
| node: Optional[Node] = None | |
| text: str = "" | |
| suffix: str = "" | |
| whitespace: str = "" | |
| expanded: bool = False | |
| last: bool = False | |
| def expandable(self) -> bool: | |
| """Check if the line may be expanded.""" | |
| return bool(self.node is not None and self.node.children) | |
| def check_length(self, max_length: int) -> bool: | |
| """Check this line fits within a given number of cells.""" | |
| start_length = ( | |
| len(self.whitespace) + cell_len(self.text) + cell_len(self.suffix) | |
| ) | |
| assert self.node is not None | |
| return self.node.check_length(start_length, max_length) | |
| def expand(self, indent_size: int) -> Iterable["_Line"]: | |
| """Expand this line by adding children on their own line.""" | |
| node = self.node | |
| assert node is not None | |
| whitespace = self.whitespace | |
| assert node.children | |
| if node.key_repr: | |
| new_line = yield _Line( | |
| text=f"{node.key_repr}{node.key_separator}{node.open_brace}", | |
| whitespace=whitespace, | |
| ) | |
| else: | |
| new_line = yield _Line(text=node.open_brace, whitespace=whitespace) | |
| child_whitespace = self.whitespace + " " * indent_size | |
| tuple_of_one = node.is_tuple and len(node.children) == 1 | |
| for last, child in loop_last(node.children): | |
| separator = "," if tuple_of_one else node.separator | |
| line = _Line( | |
| parent=new_line, | |
| node=child, | |
| whitespace=child_whitespace, | |
| suffix=separator, | |
| last=last and not tuple_of_one, | |
| ) | |
| yield line | |
| yield _Line( | |
| text=node.close_brace, | |
| whitespace=whitespace, | |
| suffix=self.suffix, | |
| last=self.last, | |
| ) | |
| def __str__(self) -> str: | |
| if self.last: | |
| return f"{self.whitespace}{self.text}{self.node or ''}" | |
| else: | |
| return ( | |
| f"{self.whitespace}{self.text}{self.node or ''}{self.suffix.rstrip()}" | |
| ) | |
| def _is_namedtuple(obj: Any) -> bool: | |
| """Checks if an object is most likely a namedtuple. It is possible | |
| to craft an object that passes this check and isn't a namedtuple, but | |
| there is only a minuscule chance of this happening unintentionally. | |
| Args: | |
| obj (Any): The object to test | |
| Returns: | |
| bool: True if the object is a namedtuple. False otherwise. | |
| """ | |
| try: | |
| fields = getattr(obj, "_fields", None) | |
| except Exception: | |
| # Being very defensive - if we cannot get the attr then its not a namedtuple | |
| return False | |
| return isinstance(obj, tuple) and isinstance(fields, tuple) | |
| def traverse( | |
| _object: Any, | |
| max_length: Optional[int] = None, | |
| max_string: Optional[int] = None, | |
| max_depth: Optional[int] = None, | |
| ) -> Node: | |
| """Traverse object and generate a tree. | |
| Args: | |
| _object (Any): Object to be traversed. | |
| max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation. | |
| Defaults to None. | |
| max_string (int, optional): Maximum length of string before truncating, or None to disable truncating. | |
| Defaults to None. | |
| max_depth (int, optional): Maximum depth of data structures, or None for no maximum. | |
| Defaults to None. | |
| Returns: | |
| Node: The root of a tree structure which can be used to render a pretty repr. | |
| """ | |
| def to_repr(obj: Any) -> str: | |
| """Get repr string for an object, but catch errors.""" | |
| if ( | |
| max_string is not None | |
| and _safe_isinstance(obj, (bytes, str)) | |
| and len(obj) > max_string | |
| ): | |
| truncated = len(obj) - max_string | |
| obj_repr = f"{obj[:max_string]!r}+{truncated}" | |
| else: | |
| try: | |
| obj_repr = repr(obj) | |
| except Exception as error: | |
| obj_repr = f"<repr-error {str(error)!r}>" | |
| return obj_repr | |
| visited_ids: Set[int] = set() | |
| push_visited = visited_ids.add | |
| pop_visited = visited_ids.remove | |
| def _traverse(obj: Any, root: bool = False, depth: int = 0) -> Node: | |
| """Walk the object depth first.""" | |
| obj_id = id(obj) | |
| if obj_id in visited_ids: | |
| # Recursion detected | |
| return Node(value_repr="...") | |
| obj_type = type(obj) | |
| children: List[Node] | |
| reached_max_depth = max_depth is not None and depth >= max_depth | |
| def iter_rich_args(rich_args: Any) -> Iterable[Union[Any, Tuple[str, Any]]]: | |
| for arg in rich_args: | |
| if _safe_isinstance(arg, tuple): | |
| if len(arg) == 3: | |
| key, child, default = arg | |
| if default == child: | |
| continue | |
| yield key, child | |
| elif len(arg) == 2: | |
| key, child = arg | |
| yield key, child | |
| elif len(arg) == 1: | |
| yield arg[0] | |
| else: | |
| yield arg | |
| try: | |
| fake_attributes = hasattr( | |
| obj, "awehoi234_wdfjwljet234_234wdfoijsdfmmnxpi492" | |
| ) | |
| except Exception: | |
| fake_attributes = False | |
| rich_repr_result: Optional[RichReprResult] = None | |
| if not fake_attributes: | |
| try: | |
| if hasattr(obj, "__rich_repr__") and not isclass(obj): | |
| rich_repr_result = obj.__rich_repr__() | |
| except Exception: | |
| pass | |
| if rich_repr_result is not None: | |
| push_visited(obj_id) | |
| angular = getattr(obj.__rich_repr__, "angular", False) | |
| args = list(iter_rich_args(rich_repr_result)) | |
| class_name = obj.__class__.__name__ | |
| if args: | |
| children = [] | |
| append = children.append | |
| if reached_max_depth: | |
| if angular: | |
| node = Node(value_repr=f"<{class_name}...>") | |
| else: | |
| node = Node(value_repr=f"{class_name}(...)") | |
| else: | |
| if angular: | |
| node = Node( | |
| open_brace=f"<{class_name} ", | |
| close_brace=">", | |
| children=children, | |
| last=root, | |
| separator=" ", | |
| ) | |
| else: | |
| node = Node( | |
| open_brace=f"{class_name}(", | |
| close_brace=")", | |
| children=children, | |
| last=root, | |
| ) | |
| for last, arg in loop_last(args): | |
| if _safe_isinstance(arg, tuple): | |
| key, child = arg | |
| child_node = _traverse(child, depth=depth + 1) | |
| child_node.last = last | |
| child_node.key_repr = key | |
| child_node.key_separator = "=" | |
| append(child_node) | |
| else: | |
| child_node = _traverse(arg, depth=depth + 1) | |
| child_node.last = last | |
| append(child_node) | |
| else: | |
| node = Node( | |
| value_repr=f"<{class_name}>" if angular else f"{class_name}()", | |
| children=[], | |
| last=root, | |
| ) | |
| pop_visited(obj_id) | |
| elif _is_attr_object(obj) and not fake_attributes: | |
| push_visited(obj_id) | |
| children = [] | |
| append = children.append | |
| attr_fields = _get_attr_fields(obj) | |
| if attr_fields: | |
| if reached_max_depth: | |
| node = Node(value_repr=f"{obj.__class__.__name__}(...)") | |
| else: | |
| node = Node( | |
| open_brace=f"{obj.__class__.__name__}(", | |
| close_brace=")", | |
| children=children, | |
| last=root, | |
| ) | |
| def iter_attrs() -> ( | |
| Iterable[Tuple[str, Any, Optional[Callable[[Any], str]]]] | |
| ): | |
| """Iterate over attr fields and values.""" | |
| for attr in attr_fields: | |
| if attr.repr: | |
| try: | |
| value = getattr(obj, attr.name) | |
| except Exception as error: | |
| # Can happen, albeit rarely | |
| yield (attr.name, error, None) | |
| else: | |
| yield ( | |
| attr.name, | |
| value, | |
| attr.repr if callable(attr.repr) else None, | |
| ) | |
| for last, (name, value, repr_callable) in loop_last(iter_attrs()): | |
| if repr_callable: | |
| child_node = Node(value_repr=str(repr_callable(value))) | |
| else: | |
| child_node = _traverse(value, depth=depth + 1) | |
| child_node.last = last | |
| child_node.key_repr = name | |
| child_node.key_separator = "=" | |
| append(child_node) | |
| else: | |
| node = Node( | |
| value_repr=f"{obj.__class__.__name__}()", children=[], last=root | |
| ) | |
| pop_visited(obj_id) | |
| elif ( | |
| is_dataclass(obj) | |
| and not _safe_isinstance(obj, type) | |
| and not fake_attributes | |
| and _is_dataclass_repr(obj) | |
| ): | |
| push_visited(obj_id) | |
| children = [] | |
| append = children.append | |
| if reached_max_depth: | |
| node = Node(value_repr=f"{obj.__class__.__name__}(...)") | |
| else: | |
| node = Node( | |
| open_brace=f"{obj.__class__.__name__}(", | |
| close_brace=")", | |
| children=children, | |
| last=root, | |
| empty=f"{obj.__class__.__name__}()", | |
| ) | |
| for last, field in loop_last( | |
| field | |
| for field in fields(obj) | |
| if field.repr and hasattr(obj, field.name) | |
| ): | |
| child_node = _traverse(getattr(obj, field.name), depth=depth + 1) | |
| child_node.key_repr = field.name | |
| child_node.last = last | |
| child_node.key_separator = "=" | |
| append(child_node) | |
| pop_visited(obj_id) | |
| elif _is_namedtuple(obj) and _has_default_namedtuple_repr(obj): | |
| push_visited(obj_id) | |
| class_name = obj.__class__.__name__ | |
| if reached_max_depth: | |
| # If we've reached the max depth, we still show the class name, but not its contents | |
| node = Node( | |
| value_repr=f"{class_name}(...)", | |
| ) | |
| else: | |
| children = [] | |
| append = children.append | |
| node = Node( | |
| open_brace=f"{class_name}(", | |
| close_brace=")", | |
| children=children, | |
| empty=f"{class_name}()", | |
| ) | |
| for last, (key, value) in loop_last(obj._asdict().items()): | |
| child_node = _traverse(value, depth=depth + 1) | |
| child_node.key_repr = key | |
| child_node.last = last | |
| child_node.key_separator = "=" | |
| append(child_node) | |
| pop_visited(obj_id) | |
| elif _safe_isinstance(obj, _CONTAINERS): | |
| for container_type in _CONTAINERS: | |
| if _safe_isinstance(obj, container_type): | |
| obj_type = container_type | |
| break | |
| push_visited(obj_id) | |
| open_brace, close_brace, empty = _BRACES[obj_type](obj) | |
| if reached_max_depth: | |
| node = Node(value_repr=f"{open_brace}...{close_brace}") | |
| elif obj_type.__repr__ != type(obj).__repr__: | |
| node = Node(value_repr=to_repr(obj), last=root) | |
| elif obj: | |
| children = [] | |
| node = Node( | |
| open_brace=open_brace, | |
| close_brace=close_brace, | |
| children=children, | |
| last=root, | |
| ) | |
| append = children.append | |
| num_items = len(obj) | |
| last_item_index = num_items - 1 | |
| if _safe_isinstance(obj, _MAPPING_CONTAINERS): | |
| iter_items = iter(obj.items()) | |
| if max_length is not None: | |
| iter_items = islice(iter_items, max_length) | |
| for index, (key, child) in enumerate(iter_items): | |
| child_node = _traverse(child, depth=depth + 1) | |
| child_node.key_repr = to_repr(key) | |
| child_node.last = index == last_item_index | |
| append(child_node) | |
| else: | |
| iter_values = iter(obj) | |
| if max_length is not None: | |
| iter_values = islice(iter_values, max_length) | |
| for index, child in enumerate(iter_values): | |
| child_node = _traverse(child, depth=depth + 1) | |
| child_node.last = index == last_item_index | |
| append(child_node) | |
| if max_length is not None and num_items > max_length: | |
| append(Node(value_repr=f"... +{num_items - max_length}", last=True)) | |
| else: | |
| node = Node(empty=empty, children=[], last=root) | |
| pop_visited(obj_id) | |
| else: | |
| node = Node(value_repr=to_repr(obj), last=root) | |
| node.is_tuple = type(obj) == tuple | |
| node.is_namedtuple = _is_namedtuple(obj) | |
| return node | |
| node = _traverse(_object, root=True) | |
| return node | |
| def pretty_repr( | |
| _object: Any, | |
| *, | |
| max_width: int = 80, | |
| indent_size: int = 4, | |
| max_length: Optional[int] = None, | |
| max_string: Optional[int] = None, | |
| max_depth: Optional[int] = None, | |
| expand_all: bool = False, | |
| ) -> str: | |
| """Prettify repr string by expanding on to new lines to fit within a given width. | |
| Args: | |
| _object (Any): Object to repr. | |
| max_width (int, optional): Desired maximum width of repr string. Defaults to 80. | |
| indent_size (int, optional): Number of spaces to indent. Defaults to 4. | |
| max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation. | |
| Defaults to None. | |
| max_string (int, optional): Maximum length of string before truncating, or None to disable truncating. | |
| Defaults to None. | |
| max_depth (int, optional): Maximum depth of nested data structure, or None for no depth. | |
| Defaults to None. | |
| expand_all (bool, optional): Expand all containers regardless of available width. Defaults to False. | |
| Returns: | |
| str: A possibly multi-line representation of the object. | |
| """ | |
| if _safe_isinstance(_object, Node): | |
| node = _object | |
| else: | |
| node = traverse( | |
| _object, max_length=max_length, max_string=max_string, max_depth=max_depth | |
| ) | |
| repr_str: str = node.render( | |
| max_width=max_width, indent_size=indent_size, expand_all=expand_all | |
| ) | |
| return repr_str | |
| def pprint( | |
| _object: Any, | |
| *, | |
| console: Optional["Console"] = None, | |
| indent_guides: bool = True, | |
| max_length: Optional[int] = None, | |
| max_string: Optional[int] = None, | |
| max_depth: Optional[int] = None, | |
| expand_all: bool = False, | |
| ) -> None: | |
| """A convenience function for pretty printing. | |
| Args: | |
| _object (Any): Object to pretty print. | |
| console (Console, optional): Console instance, or None to use default. Defaults to None. | |
| max_length (int, optional): Maximum length of containers before abbreviating, or None for no abbreviation. | |
| Defaults to None. | |
| max_string (int, optional): Maximum length of strings before truncating, or None to disable. Defaults to None. | |
| max_depth (int, optional): Maximum depth for nested data structures, or None for unlimited depth. Defaults to None. | |
| indent_guides (bool, optional): Enable indentation guides. Defaults to True. | |
| expand_all (bool, optional): Expand all containers. Defaults to False. | |
| """ | |
| _console = get_console() if console is None else console | |
| _console.print( | |
| Pretty( | |
| _object, | |
| max_length=max_length, | |
| max_string=max_string, | |
| max_depth=max_depth, | |
| indent_guides=indent_guides, | |
| expand_all=expand_all, | |
| overflow="ignore", | |
| ), | |
| soft_wrap=True, | |
| ) | |
| if __name__ == "__main__": # pragma: no cover | |
| class BrokenRepr: | |
| def __repr__(self) -> str: | |
| 1 / 0 | |
| return "this will fail" | |
| from typing import NamedTuple | |
| class StockKeepingUnit(NamedTuple): | |
| name: str | |
| description: str | |
| price: float | |
| category: str | |
| reviews: List[str] | |
| d = defaultdict(int) | |
| d["foo"] = 5 | |
| data = { | |
| "foo": [ | |
| 1, | |
| "Hello World!", | |
| 100.123, | |
| 323.232, | |
| 432324.0, | |
| {5, 6, 7, (1, 2, 3, 4), 8}, | |
| ], | |
| "bar": frozenset({1, 2, 3}), | |
| "defaultdict": defaultdict( | |
| list, {"crumble": ["apple", "rhubarb", "butter", "sugar", "flour"]} | |
| ), | |
| "counter": Counter( | |
| [ | |
| "apple", | |
| "orange", | |
| "pear", | |
| "kumquat", | |
| "kumquat", | |
| "durian" * 100, | |
| ] | |
| ), | |
| "atomic": (False, True, None), | |
| "namedtuple": StockKeepingUnit( | |
| "Sparkling British Spring Water", | |
| "Carbonated spring water", | |
| 0.9, | |
| "water", | |
| ["its amazing!", "its terrible!"], | |
| ), | |
| "Broken": BrokenRepr(), | |
| } | |
| data["foo"].append(data) # type: ignore[attr-defined] | |
| from rich import print | |
| print(Pretty(data, indent_guides=True, max_string=20)) | |
| class Thing: | |
| def __repr__(self) -> str: | |
| return "Hello\x1b[38;5;239m World!" | |
| print(Pretty(Thing())) | |
Xet Storage Details
- Size:
- 36.3 kB
- Xet hash:
- 6129df522a633c6f2bcfec11250fe2bcfaa94b2e4256b77fa486de849ac19005
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.