CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
repr.py150 linesDownload Raw Back to rich
1import inspect2from functools import partial3from typing import (4    Any,5    Callable,6    Iterable,7    List,8    Optional,9    Tuple,10    Type,11    TypeVar,12    Union,13    overload,14)15 16T = TypeVar("T")17 18 19Result = Iterable[Union[Any, Tuple[Any], Tuple[str, Any], Tuple[str, Any, Any]]]20RichReprResult = Result21 22 23class ReprError(Exception):24    """An error occurred when attempting to build a repr."""25 26 27@overload28def auto(cls: Optional[Type[T]]) -> Type[T]:29    ...30 31 32@overload33def auto(*, angular: bool = False) -> Callable[[Type[T]], Type[T]]:34    ...35 36 37def auto(38    cls: Optional[Type[T]] = None, *, angular: Optional[bool] = None39) -> Union[Type[T], Callable[[Type[T]], Type[T]]]:40    """Class decorator to create __repr__ from __rich_repr__"""41 42    def do_replace(cls: Type[T], angular: Optional[bool] = None) -> Type[T]:43        def auto_repr(self: T) -> str:44            """Create repr string from __rich_repr__"""45            repr_str: List[str] = []46            append = repr_str.append47 48            angular: bool = getattr(self.__rich_repr__, "angular", False)  # type: ignore[attr-defined]49            for arg in self.__rich_repr__():  # type: ignore[attr-defined]50                if isinstance(arg, tuple):51                    if len(arg) == 1:52                        append(repr(arg[0]))53                    else:54                        key, value, *default = arg55                        if key is None:56                            append(repr(value))57                        else:58                            if default and default[0] == value:59                                continue60                            append(f"{key}={value!r}")61                else:62                    append(repr(arg))63            if angular:64                return f"<{self.__class__.__name__} {' '.join(repr_str)}>"65            else:66                return f"{self.__class__.__name__}({', '.join(repr_str)})"67 68        def auto_rich_repr(self: Type[T]) -> Result:69            """Auto generate __rich_rep__ from signature of __init__"""70            try:71                signature = inspect.signature(self.__init__)72                for name, param in signature.parameters.items():73                    if param.kind == param.POSITIONAL_ONLY:74                        yield getattr(self, name)75                    elif param.kind in (76                        param.POSITIONAL_OR_KEYWORD,77                        param.KEYWORD_ONLY,78                    ):79                        if param.default is param.empty:80                            yield getattr(self, param.name)81                        else:82                            yield param.name, getattr(self, param.name), param.default83            except Exception as error:84                raise ReprError(85                    f"Failed to auto generate __rich_repr__; {error}"86                ) from None87 88        if not hasattr(cls, "__rich_repr__"):89            auto_rich_repr.__doc__ = "Build a rich repr"90            cls.__rich_repr__ = auto_rich_repr  # type: ignore[attr-defined]91 92        auto_repr.__doc__ = "Return repr(self)"93        cls.__repr__ = auto_repr  # type: ignore[assignment]94        if angular is not None:95            cls.__rich_repr__.angular = angular  # type: ignore[attr-defined]96        return cls97 98    if cls is None:99        return partial(do_replace, angular=angular)100    else:101        return do_replace(cls, angular=angular)102 103 104@overload105def rich_repr(cls: Optional[Type[T]]) -> Type[T]:106    ...107 108 109@overload110def rich_repr(*, angular: bool = False) -> Callable[[Type[T]], Type[T]]:111    ...112 113 114def rich_repr(115    cls: Optional[Type[T]] = None, *, angular: bool = False116) -> Union[Type[T], Callable[[Type[T]], Type[T]]]:117    if cls is None:118        return auto(angular=angular)119    else:120        return auto(cls)121 122 123if __name__ == "__main__":124 125    @auto126    class Foo:127        def __rich_repr__(self) -> Result:128            yield "foo"129            yield "bar", {"shopping": ["eggs", "ham", "pineapple"]}130            yield "buy", "hand sanitizer"131 132    foo = Foo()133    from pip._vendor.rich.console import Console134 135    console = Console()136 137    console.rule("Standard repr")138    console.print(foo)139 140    console.print(foo, width=60)141    console.print(foo, width=30)142 143    console.rule("Angular repr")144    Foo.__rich_repr__.angular = True  # type: ignore[attr-defined]145 146    console.print(foo)147 148    console.print(foo, width=60)149    console.print(foo, width=30)150 
Aluode/PerceptionLabPortable · CoolFace