Implementation:Iterative Dvc Utils Table
| Knowledge Sources | |
|---|---|
| Domains | User_Interface, Table_Rendering |
| Last Updated | 2026-02-10 10:00 GMT |
Overview
Extended Rich Table class with collapsible column support for graceful terminal width adaptation, provided by the DVC library.
Description
The Table class in dvc/utils/table.py extends Rich's rich.table.Table to add intelligent column collapsing when a table's content exceeds the available terminal width. This is essential for DVC commands like dvc metrics show, dvc params diff, and dvc experiments show that may produce tables with many columns that do not fit in narrow terminals.
The class overrides add_column to accept an additional collapse boolean parameter (defaulting to False). When a column is marked as collapsible, it becomes eligible for automatic removal when the table exceeds the terminal width. The collapse flag is stored as a custom attribute on the column object.
The core logic is split across two methods:
_collapse_widths(widths, wrapable, max_width) is the first pass. It iterates through columns right-to-left and sets the width of collapsible columns to zero until the total width fits within max_width. This means lower-priority columns (those added later / further to the right) are collapsed first. After zeroing out the necessary columns, it delegates to Rich's built-in _collapse_widths for any remaining overflow handling (text wrapping and truncation).
_calculate_column_widths(console, options) is the second pass that runs after Rich has calculated its initial column widths. It handles cleanup of adjacent collapsed columns: when multiple consecutive columns have been reduced to zero width, it removes all but the last one entirely from the column list (including from the internal widths array). This prevents rendering artifacts from multiple empty column separators. For the single remaining collapsed column, if it has overflow="ellipsis" set and there is enough remaining width, it assigns a width of 1 plus padding to display a single Unicode ellipsis character as a visual indicator that columns have been hidden.
Usage
Import Table as a drop-in replacement for rich.table.Table whenever you need tables that adapt gracefully to narrow terminals. Mark less important columns with collapse=True when calling add_column, and the table will automatically hide them right-to-left when space is insufficient.
Code Reference
Source Location
- Repository: DVC
- File:
dvc/utils/table.py - Lines: 71 total
- Class: Table (L9-70)
Signature
class Table(RichTable):
def add_column(self, *args: Any, collapse: bool = False, **kwargs: Any) -> None:
...
def _calculate_column_widths(
self, console: "Console", options: "ConsoleOptions"
) -> list[int]:
...
def _collapse_widths(
self,
widths: list[int],
wrapable: list[bool],
max_width: int,
) -> list[int]:
...
Import
from dvc.utils.table import Table
I/O Contract
Table.add_column
| Name | Type | Required | Description |
|---|---|---|---|
| *args | Any | No | Positional arguments passed through to Rich's Table.add_column (typically the column header string). |
| collapse | bool | No | If True, this column is eligible for automatic removal when the table exceeds the terminal width. Columns are collapsed right-to-left. Defaults to False. |
| **kwargs | Any | No | Keyword arguments passed through to Rich's Table.add_column (e.g., style, justify, overflow, no_wrap). |
Table._collapse_widths
| Name | Type | Required | Description |
|---|---|---|---|
| widths | list[int] | Yes | The calculated width for each column. |
| wrapable | list[bool] | Yes | Whether each column's content can be wrapped. |
| max_width | int | Yes | The maximum total width available for the table. |
| Name | Type | Description |
|---|---|---|
| return | list[int] | The adjusted column widths with collapsible columns set to zero width as needed, followed by Rich's standard overflow handling for any remaining excess. |
Table._calculate_column_widths
| Name | Type | Required | Description |
|---|---|---|---|
| console | Console | Yes | The Rich Console instance used for rendering. |
| options | ConsoleOptions | Yes | The rendering options containing max_width and other terminal constraints. |
| Name | Type | Description |
|---|---|---|
| return | list[int] | The final column widths after removing redundant collapsed columns and optionally allocating space for an ellipsis indicator. |
Usage Examples
Basic Table with Collapsible Columns
from dvc.utils.table import Table
from rich.console import Console
table = Table()
# Essential columns (always shown)
table.add_column("Experiment", no_wrap=True)
table.add_column("acc", justify="right")
table.add_column("loss", justify="right")
# Optional columns (collapsed when terminal is narrow)
table.add_column("lr", justify="right", collapse=True)
table.add_column("epochs", justify="right", collapse=True)
table.add_column("batch_size", justify="right", collapse=True)
table.add_row("exp-abc12", "0.91", "0.32", "0.01", "50", "32")
table.add_row("exp-def34", "0.87", "0.41", "0.001", "100", "64")
console = Console()
console.print(table)
# In a wide terminal: all 6 columns are shown
# In a narrow terminal: batch_size, epochs, lr are hidden right-to-left
Ellipsis Indicator for Collapsed Columns
from dvc.utils.table import Table
from rich.console import Console
table = Table()
table.add_column("Name")
table.add_column("Status")
table.add_column("Details", overflow="ellipsis", collapse=True)
table.add_row("model.pkl", "cached", "sha256:abc123...")
console = Console(width=40)
console.print(table)
# If too narrow for "Details", a single ellipsis character is shown
# instead of the full column, indicating hidden content
Internal Details
Collapse Order
Columns are collapsed in reverse order of their position (right-to-left). This means the rightmost collapsible column is hidden first, then the next one to the left, and so on until the table fits. This convention allows callers to place the most important columns on the left side of the table.
Adjacent Collapsed Column Cleanup
When multiple adjacent columns are collapsed to zero width, _calculate_column_widths removes all but the last one from the column list entirely. This prevents rendering multiple empty border separators (e.g., ||||||) which would waste horizontal space and appear visually broken. The remaining single collapsed column can display an ellipsis if configured with overflow="ellipsis". Column indices are adjusted after removal to maintain internal consistency.