def get_pretty_failure_for_in(self, err: TestFailure) -> RenderableType: lhs_msg = Text.assemble( ("The ", "default"), ("item ", "pass.textonly"), *self.of_type(err.lhs), ) lhs = Panel( Pretty(err.lhs), title=lhs_msg, title_align="left", border_style="pass.textonly", padding=1, ) rhs_msg = Text.assemble( ("was not " if err.operator is Comparison.In else "was ", "bold default"), ("found in the ", "default"), ("container ", "fail.textonly"), *self.of_type(err.rhs), ) rhs = Panel( Pretty(err.rhs), title=rhs_msg, title_align="left", border_style="fail.textonly", padding=1, ) return Padding(RenderGroup(lhs, rhs), pad=(0, 0, 1, 2))
def _print_object(obj): """ Returns a coincise and pretty print of any object """ highlighter = ReprHighlighter() if isinstance(obj, dict): # deal with dicts newobj = {k: _class_name(v) for k, v in obj.items()} return Pretty( newobj, highlighter=highlighter, no_wrap=True, overflow=None, justify="left", ) elif isinstance(obj, (list, tuple, str)): # deal with lists and tuples return textify(obj) elif isinstance(obj, np.ndarray): # deal with numpy arrays return textify(obj) else: # deal with everything else return Pretty(obj, highlighter=highlighter, justify="left", overflow="ellipsis")
def inv(nornir, filter_str, vars): """inv FILTER FILTER should be a Nornir Advanced filter\n Example: \"F(platform__any=['linux', 'windows'] & F(testbed='tb100')\" """ filtered = get_inventory(nornir, filter_str) inv_table = Table() inv_table.add_column('Host') inv_table.add_column('Attrs') inv_table.add_column('Data') for host, host_data in filtered.inventory.hosts.items(): host_attrs = { 'hostname': host_data.hostname, 'platform': host_data.platform, 'password': host_data.password } inv_table.add_row(host, Pretty(host_attrs), Pretty(host_data.data)) Console().print(inv_table)
def delete_cart() -> None: """ GUI helper to delete a cart. """ global selected_cart if selected_cart is None: layout["footer"].update(gui.Status(Text("Must create a cart first! ", style="warning"))) return None resp = api_client.remove_cart(cart_ids[selected_cart]) if resp.status_code != 204: # Error processing the request. layout["content"].update(Pretty(resp.json())) layout["footer"].update(gui.Status(Text("[ERROR] Cannot delete the cart", style="error"))) return None cart_ids.pop(selected_cart) if len(cart_ids): selected_cart = 0 else: selected_cart = None refresh_cart() # Update GUI panels layout["footer"].update(gui.Status(Text("Cart deleted!", style="info")))
def _update(self): wall = (f" in {readable_duration(self._walltime)}" if self._walltime else "") footer = [ f"#{self.num} ({self._status}{wall})", "[bold](c)[/bold]ontinue", "[bold](r)[/bold]erun", (not self._has_result and not self._has_error) and "[bold](a)[/bold]bort", "[bold](q)[/bold]uit", ] self.dash.header = markup(f"Looping on: [bold]{self.signature()}") self.dash.footer = markup(" | ".join(x for x in footer if x)) if self._gvn: self.dash.stack["given"].clear() table = Table.grid(padding=(0, 3, 0, 0)) table.add_column("key", style="bold green") table.add_column("value") for k, v in self._gvn.items(): table.add_row(k, Pretty(v)) with TEMP_CONSOLE.capture() as cap: TEMP_CONSOLE.print(table) self.dash.stack["given"].add(cap.get()) self.dash.update()
def test_newline(): console = Console(color_system=None) console.begin_capture() console.print(Pretty((1, ), insert_line=True, expand_all=True)) result = console.end_capture() expected = "\n(\n 1,\n)\n" assert result == expected
def V(**values): table = Table( show_header=False, title=None, # box=box.MINIMAL, box=None, # border_style="blue", ) highlighter = ReprHighlighter() # for key, value in values.items(): # table.add_row( # key, "=", Pretty(value, highlighter=highlighter) # ) for key, value in values.items(): # key_text = Text.assemble( # (key, "scope.key.special" if key.startswith("__") else "scope.key"), # (" =", "scope.equals"), # ) table.add_row( Text(key, "scope.key.special" if key.startswith("__") else "scope.key"), Text(" =", "scope.equals"), Pretty(value, highlighter=highlighter), ) return table
def _rich_atlas_metadata(atlas_name, metadata): orange = "#f59e42" dimorange = "#b56510" gray = "#A9A9A9" mocassin = "#FFE4B5" cit_name, cit_link = metadata["citation"].split(", ") # Create a rich table tb = Table( box=None, show_lines=False, title=atlas_name.replace("_", " ").capitalize(), title_style=f"bold {orange}", ) # Add entries to table tb.add_column( style=f"bold {mocassin}", justify="right", min_width=8, max_width=40, ) tb.add_column(min_width=20, max_width=48) tb.add_row( "name:", Text.from_markup( metadata["name"] + f' [{gray}](v{metadata["version"]})' ), ) tb.add_row("species:", Text.from_markup(f'[i]{metadata["species"]}')) tb.add_row("citation:", Text.from_markup(f"{cit_name} [{gray}]{cit_link}")) tb.add_row("link:", Text.from_markup(metadata["atlas_link"])) tb.add_row("") tb.add_row( "orientation:", Text.from_markup(f"[bold]{metadata['orientation']}"), ) tb.add_row("symmetric:", Pretty(metadata["symmetric"])) tb.add_row("resolution:", Pretty(metadata["resolution"])) tb.add_row("shape:", Pretty(metadata["shape"])) # Fit into panel and yield panel = Panel.fit(tb, border_style=dimorange) return panel
def test_measure_pretty(): """Test measure respects expand_all""" # https://github.com/Textualize/rich/issues/1998 console = Console() pretty = Pretty(["alpha", "beta", "delta", "gamma"], expand_all=True) measurement = console.measure(pretty) assert measurement == Measurement(12, 12)
def __rich_console__(self, *args): base = f"[{mocassin}]pyinspect.builtins.[green]Tuple[/green] with [{orange}]{len(self._keys)}[/{orange}] keys:" keys = ( f"{self._keys}" if len(self._keys) < 5 else f': {str([k for n,k in enumerate(self._keys) if n<5])[:-1] + ", ..."}' ) yield base yield Pretty(keys)
def render(self) -> RenderableType: """Get renderable for widget. Returns: RenderableType: Any renderable """ return Panel(Align.center(Pretty(self), vertical="middle"), title=self.__class__.__name__)
def sms(token, to, text, sender): """ Send a test message """ with console.status(""): sms = SMS(token, to, text, sender).send() pretty = Pretty(sms, expand_all=True) console.print(Panel(pretty, title="SMS", expand=False))
def render(self) -> RenderableType: return Panel( Align.center(Pretty(self, no_wrap=True, overflow="ellipsis"), vertical="middle"), title="Department", border_style="green" if self.mouse_over else "blue", box=box.HEAVY if self.has_focus else box.ROUNDED, style=self.style, height=self.height, )
def test_indent_lines(): console = Console(width=100, color_system=None) console.begin_capture() console.print(Pretty([100, 200], indent_guides=True), width=8) expected = """\ [ │ 100, │ 200 ] """ result = console.end_capture() print(repr(result)) print(result) assert result == expected
def log(log_level: LogLevel, message: str, debug_object: any = None): if LogLevel(log_level) == LogLevel.DEBUG: console.log(f'[bold green]DEBUG[/] {message}') if debug_object: console.log(Panel(Pretty(debug_object), expand=False)) elif LogLevel(log_level) == LogLevel.INFO: console.log(f'[bold blue]INFO[/] {message}') elif LogLevel(log_level) == LogLevel.WARN: console.log(f'[bold yellow]WARN[/] {message}') elif LogLevel(log_level) == LogLevel.ERROR: console.log(f'[bold red]ERROR[/] {message}') console.print_exception() elif LogLevel(log_level) == LogLevel.FATAL: console.log(f'[bold white on red]FATAL[/] {message}') console.print_exception()
def list_venvs(self, pattern, venv_pattern, pythons=None, out=sys.stdout, pipe_mode=False): table = None if not pipe_mode: table = Table( "No.", "Hash", "Name", "Interpreter", "Environment", "Packages", box=None, ) for n, inst in enumerate(self.venv.instances()): if not inst.name or not inst.matches_pattern(pattern): continue if pythons and inst.py not in pythons: continue if not inst.match_venv_pattern(venv_pattern): continue pkgs_str = inst.full_pkg_str env_str = env_to_str(inst.env) if pipe_mode: print( f"[#{n}] {inst.short_hash} {inst.name:12} {env_str} {inst.py} Packages({pkgs_str})" ) else: table.add_row( f"[cyan]#{n}[/cyan]", f"[bold cyan]{hex(hash(inst))[2:9]}[/bold cyan]", f"[bold]{inst.name}[/bold]", Pretty(inst.py), env_str or "--", f"[italic]{pkgs_str}[/italic]", ) if table: rich_print(table)
def value_type(value: Any, *, split_min: int = DEFAULT_VALUE_TYPE_SPLIT_MIN): typ = type(value) if hasattr(typ, "__name__"): # Just omit the module name for now, it gets to take up too much # space... # if ( # hasattr(typ, "__module__") # and typ.__module__ != "builtins" # ): # if len(typ.__module__) + len(typ.__name__) < split_min: # return f"{typ.__module__}.{typ.__name__}" # else: # return f"{typ.__module__}\n.{typ.__name__}" # else: # return typ.__name__ return typ.__name__ else: return Pretty(typ)
def __rich__(self) -> "Pretty": # External from rich.pretty import Pretty return Pretty({ "users": len(self.users_timeline), "clock": self.clock, "iteration": self.iteration, "timeline": self.timeline_type.name, "topology": self.topology.name, "rate": { "internal": { "fake": self.internal_fake_transmission_rate, "genuine": self.internal_genuine_transmission_rate, }, "external": { "fake": self.external_fake_transmission_rate, "genuine": self.external_genuine_transmission_rate, }, }, })
def refresh_cart() -> bool: """ GUI helper to display carts content. *Note:* Before calling this method make sure that `selected_cart != None`. :return: `True` if cart data could be fetched, `False` otherwise. """ resp = api_client.get_cart(cart_ids[selected_cart]) # type: ignore if resp.status_code != 200: # Error processing the request. layout["content"].update(Pretty(resp.json())) layout["footer"].update(gui.Status(Text("[ERROR] Cannot get cart content", style="danger"))) return False cart_data = resp.json() # Update GUI panels layout["content"].update(gui.CartDetail(cart_data["products"], cart_data["total"])) return True
def create_cart() -> None: """ GUI helper to create a new cart. """ global selected_cart resp = api_client.create_cart() if resp.status_code != 201: # Error processing the request. layout["content"].update(Pretty(resp.json())) layout["footer"].update(gui.Status(Text("[ERROR] Cannot create cart", style="danger"))) return None cart_data = resp.json() cart_ids.append(cart_data["id"]) selected_cart = len(cart_ids) - 1 # Update GUI panels layout["carts"].update(gui.CartList(cart_ids, selected_cart)) layout["content"].update(gui.CartDetail(cart_data["products"])) layout["footer"].update(gui.Status(Text("New cart created!", style="info")))
def report() -> None: # pragma: no cover """Print a report to the terminal with debugging information""" console = Console() inspect(console) features = get_windows_console_features() inspect(features) env_names = ( "TERM", "COLORTERM", "CLICOLOR", "NO_COLOR", "TERM_PROGRAM", "COLUMNS", "LINES", "JPY_PARENT_PID", "VSCODE_VERBOSE_LOGGING", ) env = {name: os.getenv(name) for name in env_names} console.print(Panel.fit((Pretty(env)), title="[b]Environment Variables")) console.print(f'platform="{platform.system()}"')
def add_product(product_index: int) -> None: """ GUI helper to add a product to a cart. :param product_index: Product index. """ if selected_cart is None: layout["footer"].update(gui.Status(Text("Must create a cart first! ", style="warning"))) return None product = settings.CLIENT_PRODUCT_CODES[product_index - 1] resp = api_client.add_product(cart_ids[selected_cart], product) if resp.status_code != 200: # Error processing the request. layout["content"].update(Pretty(resp.json())) layout["footer"].update(gui.Status(Text("[ERROR] Cannot add product", style="error"))) return None if refresh_cart(): # Update GUI panels layout["footer"].update(gui.Status(Text("Product added!", style="info")))
def table(mapping: Mapping) -> Table: tbl = Table.grid(padding=(0, 1)) tbl.expand = True tbl.add_column(style=Style(color="blue", italic=True)) tbl.add_column(style=Style(color="#4ec9b0", italic=True)) tbl.add_column() for key in sorted(mapping.keys()): value = mapping[key] if is_rich(value): rich_value_type = None rich_value = value else: rich_value_type = value_type(value) if isinstance(value, str): rich_value = value elif (inspect.isfunction(value) and hasattr(value, "__module__") and hasattr(value, "__name__")): rich_value = ReprHighlighter()( f"<function {value.__module__}.{value.__name__}>") else: rich_value = Pretty(value) tbl.add_row(key, rich_value_type, rich_value) return tbl
from rich.console import Console from rich.panel import Panel from rich.pretty import Pretty DATA = { "foo": [1, 2, 3, (), {}, (1, 2, 3), {4, 5, 6, (7, 8, 9)}, "Hello, World"], "bar": [None, (False, True)] * 2, "Dune": { "names": { "Paul Atriedies", "Vladimir Harkonnen", "Thufir Haway", "Duncan Idaho", } }, } console = Console() for w in range(130): console.print(Panel(Pretty(DATA, indent_guides=True), width=w))
from rich.console import Console from rich.panel import Panel from rich.pretty import Pretty DATA = { "foo": [1, 2, 3, (), {}, (1, 2, 3), {4, 5, 6, (7, 8, 9)}, "Hello, World"], "bar": [None, (False, True)] * 2, } console = Console() for w in range(130): console.print(Panel(Pretty(DATA), width=w))
def get_operands(self, err: TestAssertionFailure) -> Optional[RenderableType]: if err.operator in EQUALITY_COMPARISONS | INEQUALITY_COMPARISONS: description = { Comparison.Equals: "not equal to", Comparison.NotEquals: "equal to", Comparison.LessThan: "not less than", Comparison.LessThanEqualTo: "not less than or equal to", Comparison.GreaterThan: "not greater than", Comparison.GreaterThanEqualTo: "not greater than or equal to", }[err.operator] lhs_msg = Text.assemble( ("The ", "default"), ("LHS ", "pass.textonly"), *self.of_type(err.lhs), ) rhs_msg = Text.assemble( (f"was {description} ", "bold default"), ("the ", "default"), ("RHS ", "fail.textonly"), *self.of_type(err.rhs), ) elif err.operator in IN_COMPARISONS: lhs_msg = Text.assemble( ("The ", "default"), ("item ", "pass.textonly"), *self.of_type(err.lhs), ) rhs_msg = Text.assemble( ( "was not " if err.operator is Comparison.In else "was ", "bold default", ), ("found in the ", "default"), ("container ", "fail.textonly"), *self.of_type(err.rhs), ) elif err.operator in IS_COMPARISONS: lhs_msg = Text.assemble( ("The ", "default"), ("LHS ", "pass.textonly"), *self.of_type(err.lhs), (" with ", "default"), ("id ", "default"), (f"{id(err.lhs)}", "bold default"), ) rhs_msg = Text.assemble( ( "was not " if err.operator is Comparison.Is else "was ", "bold default", ), ("the ", "default"), ("RHS ", "fail.textonly"), *self.of_type(err.rhs), (" with ", "default"), ("id ", "default"), (f"{id(err.rhs)}", "bold default"), ) else: # pragma: unreachable raise Exception(f"Unknown operator: {err.operator!r}") lhs = Panel( Pretty(err.lhs), title=lhs_msg, title_align="left", border_style="pass.textonly", padding=1, expand=True, ) rhs = Panel( Pretty(err.rhs), title=rhs_msg, title_align="left", border_style="fail.textonly", padding=1, expand=True, ) return Columns( [lhs, rhs], expand=True, padding=0, )
try: res = qrz.get_bio(bio) if args.pretty: c.print( Panel.fit(Syntax(res, "html", theme="inkpot", background_color="default"), title=f"Bio: {bio}", border_style=Style(color="green"))) else: print(res) except QrzError as e: if args.pretty: ec.print( Panel.fit(Pretty(e), title=f"Bio: {bio}", border_style=Style(color="red"))) else: print(e) print() if args.dxcc: for dxcc in args.dxcc: try: results = qrz.get_dxcc(dxcc) if isinstance(results, list): resses = { res.name: tabulate(asdict(res), args.pretty) for res in results }
@attr.define class Model: name: str triangles: List[Triangle] = attr.Factory(list) if __name__ == "__main__": model = Model( name="Alien#1", triangles=[ Triangle( Point3D(x=20, y=50), Point3D(x=50, y=15, z=-45.34), Point3D(3.1426, 83.2323, -16), ) ], ) from rich.console import Console from rich.pretty import Pretty from rich.table import Column, Table from rich.text import Text console = Console() table = Table("attrs *with* Rich", Column(Text.from_markup("attrs *without* Rich"))) table.add_row(Pretty(model), repr(model)) console.print(table)
def make_test_card() -> Table: """Get a renderable that demonstrates a number of features.""" table = Table.grid(padding=1, pad_edge=True) table.title = "Rich features" table.add_column("Feature", no_wrap=True, justify="center", style="bold red") table.add_column("Demonstration") color_table = Table( box=None, expand=False, show_header=False, show_edge=False, pad_edge=False, ) color_table.add_row( # "[bold yellow]256[/] colors or [bold green]16.7 million[/] colors [blue](if supported by your terminal)[/].", ("✓ [bold green]4-bit color[/]\n" "✓ [bold blue]8-bit color[/]\n" "✓ [bold magenta]Truecolor (16.7 million)[/]\n" "✓ [bold yellow]Dumb terminals[/]\n" "✓ [bold cyan]Automatic color conversion"), ColorBox(), ) table.add_row("Colors", color_table) table.add_row( "Styles", "All ansi styles: [bold]bold[/], [dim]dim[/], [italic]italic[/italic], [underline]underline[/], [strike]strikethrough[/], [reverse]reverse[/], and even [blink]blink[/].", ) lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque in metus sed sapien ultricies pretium a at justo. Maecenas luctus velit et auctor maximus." lorem_table = Table.grid(padding=1, collapse_padding=True) lorem_table.pad_edge = False lorem_table.add_row( Text(lorem, justify="left", style="green"), Text(lorem, justify="center", style="yellow"), Text(lorem, justify="right", style="blue"), Text(lorem, justify="full", style="red"), ) table.add_row( "Text", RenderGroup( Text.from_markup( """Word wrap text. Justify [green]left[/], [yellow]center[/], [blue]right[/] or [red]full[/].\n""" ), lorem_table, ), ) def comparison(renderable1, renderable2) -> Table: table = Table(show_header=False, pad_edge=False, box=None, expand=True) table.add_column("1", ratio=1) table.add_column("2", ratio=1) table.add_row(renderable1, renderable2) return table table.add_row( "Asian languages", ":flag_for_china: 该库支持中文,日文和韩文文本!\n:flag_for_japan: ライブラリは中国語、日本語、韓国語のテキストをサポートしています\n:flag_for_south_korea: 이 라이브러리는 중국어, 일본어 및 한국어 텍스트를 지원합니다", ) markup_example = ( "[bold magenta]Rich[/] supports a simple [i]bbcode[/i] like [b]markup[/b] for [yellow]color[/], [underline]style[/], and emoji! " ":+1: :apple: :ant: :bear: :baguette_bread: :bus: ") table.add_row("Console markup", markup_example) example_table = Table( show_edge=False, show_header=True, expand=False, row_styles=["none", "dim"], box=box.SIMPLE, ) example_table.add_column("[green]Date", style="green", no_wrap=True) example_table.add_column("[blue]Title", style="blue") example_table.add_column( "[cyan]Production Budget", style="cyan", justify="right", no_wrap=True, ) example_table.add_column( "[magenta]Box Office", style="magenta", justify="right", no_wrap=True, ) example_table.add_row( "Dec 20, 2019", "Star Wars: The Rise of Skywalker", "$275,000,000", "$375,126,118", ) example_table.add_row( "May 25, 2018", "[b]Solo[/]: A Star Wars Story", "$275,000,000", "$393,151,347", ) example_table.add_row( "Dec 15, 2017", "Star Wars Ep. VIII: The Last Jedi", "$262,000,000", "[bold]$1,332,539,889[/bold]", ) example_table.add_row( "May 19, 1999", "Star Wars Ep. [b]I[/b]: [i]The phantom Menace", "$115,000,000", "$1,027,044,677", ) table.add_row("Tables", example_table) code = '''\ def iter_last(values: Iterable[T]) -> Iterable[Tuple[bool, T]]: """Iterate and generate a tuple with a flag for last value.""" iter_values = iter(values) try: previous_value = next(iter_values) except StopIteration: return for value in iter_values: yield False, previous_value previous_value = value yield True, previous_value''' pretty_data = { "foo": [ 3.1427, ( "Paul Atriedies", "Vladimir Harkonnen", "Thufir Haway", ), ], "atomic": (False, True, None), } table.add_row( "Syntax\nhighlighting\n&\npretty\nprinting", comparison( Syntax(code, "python3", line_numbers=True, indent_guides=True), Pretty(pretty_data, indent_guides=True), ), ) markdown_example = """\ # Markdown Supports much of the *markdown*, __syntax__! - Headers - Basic formatting: **bold**, *italic*, `code` - Block quotes - Lists, and more... """ table.add_row( "Markdown", comparison("[cyan]" + markdown_example, Markdown(markdown_example))) table.add_row( "And more", """Progress bars, columns, styled logging handler, tracebacks, etc...""", ) return table
def time_pretty_justify_center(self): pretty = Pretty(snippets.PYTHON_DICT, justify="center") self.console.print(pretty)