rich
rich copied to clipboard
[BUG]
- [X] I've checked docs and closed issues for possible solutions.
- [X] I can't find my issue in the FAQ.
Classes that implement a __rich__
-method aren't rendered correctly in tables:
Example
from rich.console import Console
from rich.table import Table
class Employee:
name: str
def __init__(self, name: str) -> None:
self.name = name
def __rich__(self):
return self.name
console = Console()
table = Table()
table.add_column("Name", no_wrap=True)
table.add_column("Age")
table.add_row(Employee("John Doe"), "42")
console.print(table)
Yields this result:
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳┓
┃ Name ┃┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇┩
│ John Doe ││
└─────────────────────────────────────────────────────────┴┘
Removing no_wrap=True
renders at least the second column, but makes the Name
column to wide:
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━┓
┃ Name ┃ Age ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━┩
│ John Doe │ 42 │
└────────────────────────────────────────────────────┴─────┘
Calling Employee("John Doe").__rich__()
explicitly gives the expected result:
┏━━━━━━━━━━┳━━━━━┓
┃ Name ┃ Age ┃
┡━━━━━━━━━━╇━━━━━┩
│ John Doe │ 42 │
└──────────┴─────┘
Click to expand
rich==13.6.0
╭───────────────────────── <class 'rich.console.Console'> ─────────────────────────╮
│ A high level console interface. │
│ │
│ ╭──────────────────────────────────────────────────────────────────────────────╮ │
│ │ <console width=177 ColorSystem.TRUECOLOR> │ │
│ ╰──────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ color_system = 'truecolor' │
│ encoding = 'utf-8' │
│ file = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'> │
│ height = 49 │
│ is_alt_screen = False │
│ is_dumb_terminal = False │
│ is_interactive = True │
│ is_jupyter = False │
│ is_terminal = True │
│ legacy_windows = False │
│ no_color = False │
│ options = ConsoleOptions( │
│ size=ConsoleDimensions(width=177, height=49), │
│ legacy_windows=False, │
│ min_width=1, │
│ max_width=177, │
│ is_terminal=True, │
│ encoding='utf-8', │
│ max_height=49, │
│ justify=None, │
│ overflow=None, │
│ no_wrap=False, │
│ highlight=None, │
│ markup=None, │
│ height=None │
│ ) │
│ quiet = False │
│ record = False │
│ safe_box = True │
│ size = ConsoleDimensions(width=177, height=49) │
│ soft_wrap = False │
│ stderr = False │
│ style = None │
│ tab_size = 8 │
│ width = 177 │
╰──────────────────────────────────────────────────────────────────────────────────╯
╭─── <class 'rich._windows.WindowsConsoleFeatures'> ────╮
│ Windows features available. │
│ │
│ ╭───────────────────────────────────────────────────╮ │
│ │ WindowsConsoleFeatures(vt=False, truecolor=False) │ │
│ ╰───────────────────────────────────────────────────╯ │
│ │
│ truecolor = False │
│ vt = False │
╰───────────────────────────────────────────────────────╯
╭────── Environment Variables ───────╮
│ { │
│ 'TERM': 'xterm-256color', │
│ 'COLORTERM': 'truecolor', │
│ 'CLICOLOR': None, │
│ 'NO_COLOR': None, │
│ 'TERM_PROGRAM': 'iTerm.app', │
│ 'COLUMNS': None, │
│ 'LINES': None, │
│ 'JUPYTER_COLUMNS': None, │
│ 'JUPYTER_LINES': None, │
│ 'JPY_PARENT_PID': None, │
│ 'VSCODE_VERBOSE_LOGGING': None │
│ } │
╰────────────────────────────────────╯
platform="Darwin"
Thank you for your issue. Give us a little time to review it.
PS. You might want to check the FAQ if you haven't done so already.
This is an automated reply, generated by FAQtory
From https://rich.readthedocs.io/en/stable/protocol.html#measuring-renderables
Sometimes Rich needs to know how many characters an object will take up when rendering. The Table class, for instance, will use this information to calculate the optimal dimensions for the columns... you will need to supply a
__rich_measure__
method...
This doesn't seem to work with a simple __rich__
method so perhaps this should be clarified in the docs, but it does work with __rich__console__
.
from rich.console import Console, ConsoleOptions, RenderResult
from rich.measure import Measurement
from rich.table import Table
class Employee:
def __init__(self, name: str) -> None:
self.name = name
def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderResult:
yield self.name
def __rich_measure__(
self, console: Console, options: ConsoleOptions
) -> Measurement:
return Measurement(len(self.name), len(self.name))
console = Console()
table = Table()
table.add_column("Name", no_wrap=True)
table.add_column("Age")
table.add_row(Employee("John Doe"), "42")
console.print(table)