Buckets:
MisterAI/LocalAI_Demo_backends / cpu-diffusers.upgrade-tmp /venv /lib /python3.10 /site-packages /rich /style.py
| import sys | |
| from functools import lru_cache | |
| from itertools import count | |
| from operator import attrgetter | |
| from pickle import dumps, loads | |
| from random import getrandbits | |
| from typing import Any, Dict, Iterable, List, Optional, Type, Union, cast | |
| from . import errors | |
| from .color import Color, ColorParseError, ColorSystem, blend_rgb | |
| from .repr import Result, rich_repr | |
| from .terminal_theme import DEFAULT_TERMINAL_THEME, TerminalTheme | |
| _hash_getter = attrgetter( | |
| "_color", "_bgcolor", "_attributes", "_set_attributes", "_link", "_meta" | |
| ) | |
| # Style instances and style definitions are often interchangeable | |
| StyleType = Union[str, "Style"] | |
| _id_generator = count(getrandbits(24)) | |
| class _Bit: | |
| """A descriptor to get/set a style attribute bit.""" | |
| __slots__ = ["bit"] | |
| def __init__(self, bit_no: int) -> None: | |
| self.bit = 1 << bit_no | |
| def __get__(self, obj: "Style", objtype: Type["Style"]) -> Optional[bool]: | |
| if obj._set_attributes & self.bit: | |
| return obj._attributes & self.bit != 0 | |
| return None | |
| class Style: | |
| """A terminal style. | |
| A terminal style consists of a color (`color`), a background color (`bgcolor`), and a number of attributes, such | |
| as bold, italic etc. The attributes have 3 states: they can either be on | |
| (``True``), off (``False``), or not set (``None``). | |
| Args: | |
| color (Union[Color, str], optional): Color of terminal text. Defaults to None. | |
| bgcolor (Union[Color, str], optional): Color of terminal background. Defaults to None. | |
| bold (bool, optional): Enable bold text. Defaults to None. | |
| dim (bool, optional): Enable dim text. Defaults to None. | |
| italic (bool, optional): Enable italic text. Defaults to None. | |
| underline (bool, optional): Enable underlined text. Defaults to None. | |
| blink (bool, optional): Enabled blinking text. Defaults to None. | |
| blink2 (bool, optional): Enable fast blinking text. Defaults to None. | |
| reverse (bool, optional): Enabled reverse text. Defaults to None. | |
| conceal (bool, optional): Enable concealed text. Defaults to None. | |
| strike (bool, optional): Enable strikethrough text. Defaults to None. | |
| underline2 (bool, optional): Enable doubly underlined text. Defaults to None. | |
| frame (bool, optional): Enable framed text. Defaults to None. | |
| encircle (bool, optional): Enable encircled text. Defaults to None. | |
| overline (bool, optional): Enable overlined text. Defaults to None. | |
| link (str, link): Link URL. Defaults to None. | |
| """ | |
| _color: Optional[Color] | |
| _bgcolor: Optional[Color] | |
| _attributes: int | |
| _set_attributes: int | |
| _hash: Optional[int] | |
| _null: bool | |
| _meta: Optional[bytes] | |
| __slots__ = [ | |
| "_color", | |
| "_bgcolor", | |
| "_attributes", | |
| "_set_attributes", | |
| "_link", | |
| "_link_id", | |
| "_ansi", | |
| "_style_definition", | |
| "_hash", | |
| "_null", | |
| "_meta", | |
| ] | |
| # maps bits on to SGR parameter | |
| _style_map = { | |
| 0: "1", | |
| 1: "2", | |
| 2: "3", | |
| 3: "4", | |
| 4: "5", | |
| 5: "6", | |
| 6: "7", | |
| 7: "8", | |
| 8: "9", | |
| 9: "21", | |
| 10: "51", | |
| 11: "52", | |
| 12: "53", | |
| } | |
| STYLE_ATTRIBUTES = { | |
| "dim": "dim", | |
| "d": "dim", | |
| "bold": "bold", | |
| "b": "bold", | |
| "italic": "italic", | |
| "i": "italic", | |
| "underline": "underline", | |
| "u": "underline", | |
| "blink": "blink", | |
| "blink2": "blink2", | |
| "reverse": "reverse", | |
| "r": "reverse", | |
| "conceal": "conceal", | |
| "c": "conceal", | |
| "strike": "strike", | |
| "s": "strike", | |
| "underline2": "underline2", | |
| "uu": "underline2", | |
| "frame": "frame", | |
| "encircle": "encircle", | |
| "overline": "overline", | |
| "o": "overline", | |
| } | |
| def __init__( | |
| self, | |
| *, | |
| color: Optional[Union[Color, str]] = None, | |
| bgcolor: Optional[Union[Color, str]] = None, | |
| bold: Optional[bool] = None, | |
| dim: Optional[bool] = None, | |
| italic: Optional[bool] = None, | |
| underline: Optional[bool] = None, | |
| blink: Optional[bool] = None, | |
| blink2: Optional[bool] = None, | |
| reverse: Optional[bool] = None, | |
| conceal: Optional[bool] = None, | |
| strike: Optional[bool] = None, | |
| underline2: Optional[bool] = None, | |
| frame: Optional[bool] = None, | |
| encircle: Optional[bool] = None, | |
| overline: Optional[bool] = None, | |
| link: Optional[str] = None, | |
| meta: Optional[Dict[str, Any]] = None, | |
| ): | |
| self._ansi: Optional[str] = None | |
| self._style_definition: Optional[str] = None | |
| def _make_color(color: Union[Color, str]) -> Color: | |
| return color if isinstance(color, Color) else Color.parse(color) | |
| self._color = None if color is None else _make_color(color) | |
| self._bgcolor = None if bgcolor is None else _make_color(bgcolor) | |
| self._set_attributes = sum( | |
| ( | |
| bold is not None, | |
| dim is not None and 2, | |
| italic is not None and 4, | |
| underline is not None and 8, | |
| blink is not None and 16, | |
| blink2 is not None and 32, | |
| reverse is not None and 64, | |
| conceal is not None and 128, | |
| strike is not None and 256, | |
| underline2 is not None and 512, | |
| frame is not None and 1024, | |
| encircle is not None and 2048, | |
| overline is not None and 4096, | |
| ) | |
| ) | |
| self._attributes = ( | |
| sum( | |
| ( | |
| bold and 1 or 0, | |
| dim and 2 or 0, | |
| italic and 4 or 0, | |
| underline and 8 or 0, | |
| blink and 16 or 0, | |
| blink2 and 32 or 0, | |
| reverse and 64 or 0, | |
| conceal and 128 or 0, | |
| strike and 256 or 0, | |
| underline2 and 512 or 0, | |
| frame and 1024 or 0, | |
| encircle and 2048 or 0, | |
| overline and 4096 or 0, | |
| ) | |
| ) | |
| if self._set_attributes | |
| else 0 | |
| ) | |
| self._link = link | |
| self._meta = None if meta is None else dumps(meta) | |
| self._link_id = ( | |
| f"{next(_id_generator)}{hash(self._meta)}" if (link or meta) else "" | |
| ) | |
| self._hash: Optional[int] = None | |
| self._null = not (self._set_attributes or color or bgcolor or link or meta) | |
| def null(cls) -> "Style": | |
| """Create an 'null' style, equivalent to Style(), but more performant.""" | |
| return NULL_STYLE | |
| def from_color( | |
| cls, color: Optional[Color] = None, bgcolor: Optional[Color] = None | |
| ) -> "Style": | |
| """Create a new style with colors and no attributes. | |
| Returns: | |
| color (Optional[Color]): A (foreground) color, or None for no color. Defaults to None. | |
| bgcolor (Optional[Color]): A (background) color, or None for no color. Defaults to None. | |
| """ | |
| style: Style = cls.__new__(Style) | |
| style._ansi = None | |
| style._style_definition = None | |
| style._color = color | |
| style._bgcolor = bgcolor | |
| style._set_attributes = 0 | |
| style._attributes = 0 | |
| style._link = None | |
| style._link_id = "" | |
| style._meta = None | |
| style._null = not (color or bgcolor) | |
| style._hash = None | |
| return style | |
| def from_meta(cls, meta: Optional[Dict[str, Any]]) -> "Style": | |
| """Create a new style with meta data. | |
| Returns: | |
| meta (Optional[Dict[str, Any]]): A dictionary of meta data. Defaults to None. | |
| """ | |
| style: Style = cls.__new__(Style) | |
| style._ansi = None | |
| style._style_definition = None | |
| style._color = None | |
| style._bgcolor = None | |
| style._set_attributes = 0 | |
| style._attributes = 0 | |
| style._link = None | |
| style._meta = dumps(meta) | |
| style._link_id = f"{next(_id_generator)}{hash(style._meta)}" | |
| style._hash = None | |
| style._null = not (meta) | |
| return style | |
| def on(cls, meta: Optional[Dict[str, Any]] = None, **handlers: Any) -> "Style": | |
| """Create a blank style with meta information. | |
| Example: | |
| style = Style.on(click=self.on_click) | |
| Args: | |
| meta (Optional[Dict[str, Any]], optional): An optional dict of meta information. | |
| **handlers (Any): Keyword arguments are translated in to handlers. | |
| Returns: | |
| Style: A Style with meta information attached. | |
| """ | |
| meta = {} if meta is None else meta | |
| meta.update({f"@{key}": value for key, value in handlers.items()}) | |
| return cls.from_meta(meta) | |
| bold = _Bit(0) | |
| dim = _Bit(1) | |
| italic = _Bit(2) | |
| underline = _Bit(3) | |
| blink = _Bit(4) | |
| blink2 = _Bit(5) | |
| reverse = _Bit(6) | |
| conceal = _Bit(7) | |
| strike = _Bit(8) | |
| underline2 = _Bit(9) | |
| frame = _Bit(10) | |
| encircle = _Bit(11) | |
| overline = _Bit(12) | |
| def link_id(self) -> str: | |
| """Get a link id, used in ansi code for links.""" | |
| return self._link_id | |
| def __str__(self) -> str: | |
| """Re-generate style definition from attributes.""" | |
| if self._style_definition is None: | |
| attributes: List[str] = [] | |
| append = attributes.append | |
| bits = self._set_attributes | |
| if bits & 0b0000000001111: | |
| if bits & 1: | |
| append("bold" if self.bold else "not bold") | |
| if bits & (1 << 1): | |
| append("dim" if self.dim else "not dim") | |
| if bits & (1 << 2): | |
| append("italic" if self.italic else "not italic") | |
| if bits & (1 << 3): | |
| append("underline" if self.underline else "not underline") | |
| if bits & 0b0000111110000: | |
| if bits & (1 << 4): | |
| append("blink" if self.blink else "not blink") | |
| if bits & (1 << 5): | |
| append("blink2" if self.blink2 else "not blink2") | |
| if bits & (1 << 6): | |
| append("reverse" if self.reverse else "not reverse") | |
| if bits & (1 << 7): | |
| append("conceal" if self.conceal else "not conceal") | |
| if bits & (1 << 8): | |
| append("strike" if self.strike else "not strike") | |
| if bits & 0b1111000000000: | |
| if bits & (1 << 9): | |
| append("underline2" if self.underline2 else "not underline2") | |
| if bits & (1 << 10): | |
| append("frame" if self.frame else "not frame") | |
| if bits & (1 << 11): | |
| append("encircle" if self.encircle else "not encircle") | |
| if bits & (1 << 12): | |
| append("overline" if self.overline else "not overline") | |
| if self._color is not None: | |
| append(self._color.name) | |
| if self._bgcolor is not None: | |
| append("on") | |
| append(self._bgcolor.name) | |
| if self._link: | |
| append("link") | |
| append(self._link) | |
| self._style_definition = " ".join(attributes) or "none" | |
| return self._style_definition | |
| def __bool__(self) -> bool: | |
| """A Style is false if it has no attributes, colors, or links.""" | |
| return not self._null | |
| def _make_ansi_codes(self, color_system: ColorSystem) -> str: | |
| """Generate ANSI codes for this style. | |
| Args: | |
| color_system (ColorSystem): Color system. | |
| Returns: | |
| str: String containing codes. | |
| """ | |
| if self._ansi is None: | |
| sgr: List[str] = [] | |
| append = sgr.append | |
| _style_map = self._style_map | |
| attributes = self._attributes & self._set_attributes | |
| if attributes: | |
| if attributes & 1: | |
| append(_style_map[0]) | |
| if attributes & 2: | |
| append(_style_map[1]) | |
| if attributes & 4: | |
| append(_style_map[2]) | |
| if attributes & 8: | |
| append(_style_map[3]) | |
| if attributes & 0b0000111110000: | |
| for bit in range(4, 9): | |
| if attributes & (1 << bit): | |
| append(_style_map[bit]) | |
| if attributes & 0b1111000000000: | |
| for bit in range(9, 13): | |
| if attributes & (1 << bit): | |
| append(_style_map[bit]) | |
| if self._color is not None: | |
| sgr.extend(self._color.downgrade(color_system).get_ansi_codes()) | |
| if self._bgcolor is not None: | |
| sgr.extend( | |
| self._bgcolor.downgrade(color_system).get_ansi_codes( | |
| foreground=False | |
| ) | |
| ) | |
| self._ansi = ";".join(sgr) | |
| return self._ansi | |
| def normalize(cls, style: str) -> str: | |
| """Normalize a style definition so that styles with the same effect have the same string | |
| representation. | |
| Args: | |
| style (str): A style definition. | |
| Returns: | |
| str: Normal form of style definition. | |
| """ | |
| try: | |
| return str(cls.parse(style)) | |
| except errors.StyleSyntaxError: | |
| return style.strip().lower() | |
| def pick_first(cls, *values: Optional[StyleType]) -> StyleType: | |
| """Pick first non-None style.""" | |
| for value in values: | |
| if value is not None: | |
| return value | |
| raise ValueError("expected at least one non-None style") | |
| def __rich_repr__(self) -> Result: | |
| yield "color", self.color, None | |
| yield "bgcolor", self.bgcolor, None | |
| yield "bold", self.bold, None, | |
| yield "dim", self.dim, None, | |
| yield "italic", self.italic, None | |
| yield "underline", self.underline, None, | |
| yield "blink", self.blink, None | |
| yield "blink2", self.blink2, None | |
| yield "reverse", self.reverse, None | |
| yield "conceal", self.conceal, None | |
| yield "strike", self.strike, None | |
| yield "underline2", self.underline2, None | |
| yield "frame", self.frame, None | |
| yield "encircle", self.encircle, None | |
| yield "link", self.link, None | |
| if self._meta: | |
| yield "meta", self.meta | |
| def __eq__(self, other: Any) -> bool: | |
| if not isinstance(other, Style): | |
| return NotImplemented | |
| return self.__hash__() == other.__hash__() | |
| def __ne__(self, other: Any) -> bool: | |
| if not isinstance(other, Style): | |
| return NotImplemented | |
| return self.__hash__() != other.__hash__() | |
| def __hash__(self) -> int: | |
| if self._hash is not None: | |
| return self._hash | |
| self._hash = hash(_hash_getter(self)) | |
| return self._hash | |
| def color(self) -> Optional[Color]: | |
| """The foreground color or None if it is not set.""" | |
| return self._color | |
| def bgcolor(self) -> Optional[Color]: | |
| """The background color or None if it is not set.""" | |
| return self._bgcolor | |
| def link(self) -> Optional[str]: | |
| """Link text, if set.""" | |
| return self._link | |
| def transparent_background(self) -> bool: | |
| """Check if the style specified a transparent background.""" | |
| return self.bgcolor is None or self.bgcolor.is_default | |
| def background_style(self) -> "Style": | |
| """A Style with background only.""" | |
| return Style(bgcolor=self.bgcolor) | |
| def meta(self) -> Dict[str, Any]: | |
| """Get meta information (can not be changed after construction).""" | |
| return {} if self._meta is None else cast(Dict[str, Any], loads(self._meta)) | |
| def without_color(self) -> "Style": | |
| """Get a copy of the style with color removed.""" | |
| if self._null: | |
| return NULL_STYLE | |
| style: Style = self.__new__(Style) | |
| style._ansi = None | |
| style._style_definition = None | |
| style._color = None | |
| style._bgcolor = None | |
| style._attributes = self._attributes | |
| style._set_attributes = self._set_attributes | |
| style._link = self._link | |
| style._link_id = f"{next(_id_generator)}" if self._link else "" | |
| style._null = False | |
| style._meta = None | |
| style._hash = None | |
| return style | |
| def parse(cls, style_definition: str) -> "Style": | |
| """Parse a style definition. | |
| Args: | |
| style_definition (str): A string containing a style. | |
| Raises: | |
| errors.StyleSyntaxError: If the style definition syntax is invalid. | |
| Returns: | |
| `Style`: A Style instance. | |
| """ | |
| if style_definition.strip() == "none" or not style_definition: | |
| return cls.null() | |
| STYLE_ATTRIBUTES = cls.STYLE_ATTRIBUTES | |
| color: Optional[str] = None | |
| bgcolor: Optional[str] = None | |
| attributes: Dict[str, Optional[Any]] = {} | |
| link: Optional[str] = None | |
| words = iter(style_definition.split()) | |
| for original_word in words: | |
| word = original_word.lower() | |
| if word == "on": | |
| word = next(words, "") | |
| if not word: | |
| raise errors.StyleSyntaxError("color expected after 'on'") | |
| try: | |
| Color.parse(word) | |
| except ColorParseError as error: | |
| raise errors.StyleSyntaxError( | |
| f"unable to parse {word!r} as background color; {error}" | |
| ) from None | |
| bgcolor = word | |
| elif word == "not": | |
| word = next(words, "") | |
| attribute = STYLE_ATTRIBUTES.get(word) | |
| if attribute is None: | |
| raise errors.StyleSyntaxError( | |
| f"expected style attribute after 'not', found {word!r}" | |
| ) | |
| attributes[attribute] = False | |
| elif word == "link": | |
| word = next(words, "") | |
| if not word: | |
| raise errors.StyleSyntaxError("URL expected after 'link'") | |
| link = word | |
| elif word in STYLE_ATTRIBUTES: | |
| attributes[STYLE_ATTRIBUTES[word]] = True | |
| else: | |
| try: | |
| Color.parse(word) | |
| except ColorParseError as error: | |
| raise errors.StyleSyntaxError( | |
| f"unable to parse {word!r} as color; {error}" | |
| ) from None | |
| color = word | |
| style = Style(color=color, bgcolor=bgcolor, link=link, **attributes) | |
| return style | |
| def get_html_style(self, theme: Optional[TerminalTheme] = None) -> str: | |
| """Get a CSS style rule.""" | |
| theme = theme or DEFAULT_TERMINAL_THEME | |
| css: List[str] = [] | |
| append = css.append | |
| color = self.color | |
| bgcolor = self.bgcolor | |
| if self.reverse: | |
| color, bgcolor = bgcolor, color | |
| if self.dim: | |
| foreground_color = ( | |
| theme.foreground_color if color is None else color.get_truecolor(theme) | |
| ) | |
| color = Color.from_triplet( | |
| blend_rgb(foreground_color, theme.background_color, 0.5) | |
| ) | |
| if color is not None: | |
| theme_color = color.get_truecolor(theme) | |
| append(f"color: {theme_color.hex}") | |
| append(f"text-decoration-color: {theme_color.hex}") | |
| if bgcolor is not None: | |
| theme_color = bgcolor.get_truecolor(theme, foreground=False) | |
| append(f"background-color: {theme_color.hex}") | |
| if self.bold: | |
| append("font-weight: bold") | |
| if self.italic: | |
| append("font-style: italic") | |
| if self.underline: | |
| append("text-decoration: underline") | |
| if self.strike: | |
| append("text-decoration: line-through") | |
| if self.overline: | |
| append("text-decoration: overline") | |
| return "; ".join(css) | |
| def combine(cls, styles: Iterable["Style"]) -> "Style": | |
| """Combine styles and get result. | |
| Args: | |
| styles (Iterable[Style]): Styles to combine. | |
| Returns: | |
| Style: A new style instance. | |
| """ | |
| iter_styles = iter(styles) | |
| return sum(iter_styles, next(iter_styles)) | |
| def chain(cls, *styles: "Style") -> "Style": | |
| """Combine styles from positional argument in to a single style. | |
| Args: | |
| *styles (Iterable[Style]): Styles to combine. | |
| Returns: | |
| Style: A new style instance. | |
| """ | |
| iter_styles = iter(styles) | |
| return sum(iter_styles, next(iter_styles)) | |
| def copy(self) -> "Style": | |
| """Get a copy of this style. | |
| Returns: | |
| Style: A new Style instance with identical attributes. | |
| """ | |
| if self._null: | |
| return NULL_STYLE | |
| style: Style = self.__new__(Style) | |
| style._ansi = self._ansi | |
| style._style_definition = self._style_definition | |
| style._color = self._color | |
| style._bgcolor = self._bgcolor | |
| style._attributes = self._attributes | |
| style._set_attributes = self._set_attributes | |
| style._link = self._link | |
| style._link_id = f"{next(_id_generator)}" if self._link else "" | |
| style._hash = self._hash | |
| style._null = False | |
| style._meta = self._meta | |
| return style | |
| def clear_meta_and_links(self) -> "Style": | |
| """Get a copy of this style with link and meta information removed. | |
| Returns: | |
| Style: New style object. | |
| """ | |
| if self._null: | |
| return NULL_STYLE | |
| style: Style = self.__new__(Style) | |
| style._ansi = self._ansi | |
| style._style_definition = self._style_definition | |
| style._color = self._color | |
| style._bgcolor = self._bgcolor | |
| style._attributes = self._attributes | |
| style._set_attributes = self._set_attributes | |
| style._link = None | |
| style._link_id = "" | |
| style._hash = None | |
| style._null = False | |
| style._meta = None | |
| return style | |
| def update_link(self, link: Optional[str] = None) -> "Style": | |
| """Get a copy with a different value for link. | |
| Args: | |
| link (str, optional): New value for link. Defaults to None. | |
| Returns: | |
| Style: A new Style instance. | |
| """ | |
| style: Style = self.__new__(Style) | |
| style._ansi = self._ansi | |
| style._style_definition = self._style_definition | |
| style._color = self._color | |
| style._bgcolor = self._bgcolor | |
| style._attributes = self._attributes | |
| style._set_attributes = self._set_attributes | |
| style._link = link | |
| style._link_id = f"{next(_id_generator)}" if link else "" | |
| style._hash = None | |
| style._null = False | |
| style._meta = self._meta | |
| return style | |
| def render( | |
| self, | |
| text: str = "", | |
| *, | |
| color_system: Optional[ColorSystem] = ColorSystem.TRUECOLOR, | |
| legacy_windows: bool = False, | |
| ) -> str: | |
| """Render the ANSI codes for the style. | |
| Args: | |
| text (str, optional): A string to style. Defaults to "". | |
| color_system (Optional[ColorSystem], optional): Color system to render to. Defaults to ColorSystem.TRUECOLOR. | |
| Returns: | |
| str: A string containing ANSI style codes. | |
| """ | |
| if not text or color_system is None: | |
| return text | |
| attrs = self._ansi or self._make_ansi_codes(color_system) | |
| rendered = f"\x1b[{attrs}m{text}\x1b[0m" if attrs else text | |
| if self._link and not legacy_windows: | |
| rendered = ( | |
| f"\x1b]8;id={self._link_id};{self._link}\x1b\\{rendered}\x1b]8;;\x1b\\" | |
| ) | |
| return rendered | |
| def test(self, text: Optional[str] = None) -> None: | |
| """Write text with style directly to terminal. | |
| This method is for testing purposes only. | |
| Args: | |
| text (Optional[str], optional): Text to style or None for style name. | |
| """ | |
| text = text or str(self) | |
| sys.stdout.write(f"{self.render(text)}\n") | |
| def _add(self, style: Optional["Style"]) -> "Style": | |
| if style is None or style._null: | |
| return self | |
| if self._null: | |
| return style | |
| new_style: Style = self.__new__(Style) | |
| new_style._ansi = None | |
| new_style._style_definition = None | |
| new_style._color = style._color or self._color | |
| new_style._bgcolor = style._bgcolor or self._bgcolor | |
| new_style._attributes = (self._attributes & ~style._set_attributes) | ( | |
| style._attributes & style._set_attributes | |
| ) | |
| new_style._set_attributes = self._set_attributes | style._set_attributes | |
| new_style._link = style._link or self._link | |
| new_style._link_id = style._link_id or self._link_id | |
| new_style._null = style._null | |
| if self._meta and style._meta: | |
| new_style._meta = dumps({**self.meta, **style.meta}) | |
| else: | |
| new_style._meta = self._meta or style._meta | |
| new_style._hash = None | |
| return new_style | |
| def __add__(self, style: Optional["Style"]) -> "Style": | |
| combined_style = self._add(style) | |
| return combined_style.copy() if combined_style.link else combined_style | |
| NULL_STYLE = Style() | |
| class StyleStack: | |
| """A stack of styles.""" | |
| __slots__ = ["_stack"] | |
| def __init__(self, default_style: "Style") -> None: | |
| self._stack: List[Style] = [default_style] | |
| def __repr__(self) -> str: | |
| return f"<stylestack {self._stack!r}>" | |
| def current(self) -> Style: | |
| """Get the Style at the top of the stack.""" | |
| return self._stack[-1] | |
| def push(self, style: Style) -> None: | |
| """Push a new style on to the stack. | |
| Args: | |
| style (Style): New style to combine with current style. | |
| """ | |
| self._stack.append(self._stack[-1] + style) | |
| def pop(self) -> Style: | |
| """Pop last style and discard. | |
| Returns: | |
| Style: New current style (also available as stack.current) | |
| """ | |
| self._stack.pop() | |
| return self._stack[-1] | |
Xet Storage Details
- Size:
- 27.1 kB
- Xet hash:
- 0b24a211e7b7b6f641a5d40bc0f57aa207d876e82097e761103ad0f073a504b1
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.