from __future__ import annotations from collections.abc import Iterable def _display_width(value: str) -> int: return len(value) def _cell(value: object) -> str: return '' if value is None else str(value) def format_table(headers: list[str], rows: Iterable[Iterable[object]]) -> str: string_rows = [[_cell(value) for value in row] for row in rows] widths = [_display_width(header) for header in headers] for row in string_rows: for index, value in enumerate(row): if index < len(widths): widths[index] = max(widths[index], _display_width(value)) def render_row(values: list[str]) -> str: padded = [value.ljust(widths[index]) for index, value in enumerate(values)] return ' '.join(padded).rstrip() separator = ' '.join('-' * width for width in widths).rstrip() lines = [render_row(headers), separator] lines.extend(render_row(row) for row in string_rows) return '\n'.join(lines)