From 1c5e03eb32020011f5b13174e186c588d09d749c Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 23 Jan 2026 11:20:32 +0000 Subject: [PATCH 1/2] fix for padding width --- rich/table.py | 16 +++++++++++++--- tests/test_columns.py | 7 ++++++- tests/test_table.py | 24 ++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/rich/table.py b/rich/table.py index 942175dc3a..bfcb8c3f4e 100644 --- a/rich/table.py +++ b/rich/table.py @@ -485,6 +485,7 @@ def __rich_console__( max_width = self.width extra_width = self._extra_width + widths = self._calculate_column_widths( console, options.update_width(max_width - extra_width) ) @@ -530,6 +531,7 @@ def _calculate_column_widths( self._measure_column(console, options, column) for column in columns ] widths = [_range.maximum or 1 for _range in width_ranges] + get_padding_width = self._get_padding_width extra_width = self._extra_width if self.expand: @@ -699,9 +701,17 @@ def get_padding(first_row: bool, last_row: bool) -> Tuple[int, int, int, int]: def _get_padding_width(self, column_index: int) -> int: """Get extra width from padding.""" _, pad_right, _, pad_left = self.padding + if self.collapse_padding: - if column_index > 0: - pad_left = max(0, pad_left - pad_right) + pad_left = 0 + pad_right = abs(pad_left - pad_right) + + if not self.pad_edge: + if column_index == 0: + pad_left = 0 + if column_index == len(self.columns) - 1: + pad_right = 0 + return pad_left + pad_right def _measure_column( @@ -717,7 +727,6 @@ def _measure_column( return Measurement(0, 0) padding_width = self._get_padding_width(column._index) - if column.width is not None: # Fixed width column return Measurement( @@ -754,6 +763,7 @@ def _render( self._get_cells(console, column_index, column) for column_index, column in enumerate(self.columns) ) + row_cells: List[Tuple[_Cell, ...]] = list(zip(*_column_cells)) _box = ( self.box.substitute( diff --git a/tests/test_columns.py b/tests/test_columns.py index 1b167f4acb..d4c1113d34 100644 --- a/tests/test_columns.py +++ b/tests/test_columns.py @@ -58,11 +58,16 @@ def render(): console.print(columns) console.print() render_result = console.file.getvalue() + print(render_result) + print(repr(render_result)) return render_result def test_render(): - expected = "────────────────────────────────────────────── empty ───────────────────────────────────────────────\n───────────────────────────────────────────── optimal ──────────────────────────────────────────────\nUrsus americanus American buffalo Bison bison American crow \nCorvus brachyrhynchos American marten Martes americana American racer \nColuber constrictor American woodcock Scolopax minor Anaconda (unidentified)\nEunectes sp. Andean goose Chloephaga melanoptera Ant \nAnteater, australian spiny Tachyglossus aculeatus Anteater, giant Myrmecophaga tridactyla\n───────────────────────────────────────── optimal, expand ──────────────────────────────────────────\nUrsus americanus American buffalo Bison bison American crow \nCorvus brachyrhynchos American marten Martes americana American racer \nColuber constrictor American woodcock Scolopax minor Anaconda (unidentified)\nEunectes sp. Andean goose Chloephaga melanoptera Ant \nAnteater, australian spiny Tachyglossus aculeatus Anteater, giant Myrmecophaga tridactyla\n────────────────────────────────────── column first, optimal ───────────────────────────────────────\nUrsus americanus American marten Scolopax minor Ant \nAmerican buffalo Martes americana Anaconda (unidentified) Anteater, australian spiny\nBison bison American racer Eunectes sp. Tachyglossus aculeatus \nAmerican crow Coluber constrictor Andean goose Anteater, giant \nCorvus brachyrhynchos American woodcock Chloephaga melanoptera Myrmecophaga tridactyla \n─────────────────────────────────── column first, right to left ────────────────────────────────────\nAnt Scolopax minor American marten Ursus americanus \nAnteater, australian spiny Anaconda (unidentified) Martes americana American buffalo \nTachyglossus aculeatus Eunectes sp. American racer Bison bison \nAnteater, giant Andean goose Coluber constrictor American crow \nMyrmecophaga tridactyla Chloephaga melanoptera American woodcock Corvus brachyrhynchos\n────────────────────────────────────── equal columns, expand ───────────────────────────────────────\nChloephaga melanoptera American racer Ursus americanus \nAnt Coluber constrictor American buffalo \nAnteater, australian spiny American woodcock Bison bison \nTachyglossus aculeatus Scolopax minor American crow \nAnteater, giant Anaconda (unidentified) Corvus brachyrhynchos \nMyrmecophaga tridactyla Eunectes sp. American marten \n Andean goose Martes americana \n─────────────────────────────────────────── fixed width ────────────────────────────────────────────\nAnteater, Eunectes sp. Coluber Corvus Ursus americanus \naustralian spiny constrictor brachyrhynchos \nTachyglossus Andean goose American American marten American buffalo \naculeatus woodcock \nAnteater, giant Chloephaga Scolopax minor Martes americana Bison bison \n melanoptera \nMyrmecophaga Ant Anaconda American racer American crow \ntridactyla (unidentified) \n\n" + expected = "────────────────────────────────────────────── empty ───────────────────────────────────────────────\n───────────────────────────────────────────── optimal ──────────────────────────────────────────────\nUrsus americanus American buffalo Bison bison American crow \nCorvus brachyrhynchos American marten Martes americana American racer \nColuber constrictor American woodcock Scolopax minor Anaconda (unidentified)\nEunectes sp. Andean goose Chloephaga melanoptera Ant \nAnteater, australian spiny Tachyglossus aculeatus Anteater, giant Myrmecophaga tridactyla\n───────────────────────────────────────── optimal, expand ──────────────────────────────────────────\nUrsus americanus American buffalo Bison bison American crow \nCorvus brachyrhynchos American marten Martes americana American racer \nColuber constrictor American woodcock Scolopax minor Anaconda (unidentified)\nEunectes sp. Andean goose Chloephaga melanoptera Ant \nAnteater, australian spiny Tachyglossus aculeatus Anteater, giant Myrmecophaga tridactyla\n────────────────────────────────────── column first, optimal ───────────────────────────────────────\nUrsus americanus American marten Scolopax minor Ant \nAmerican buffalo Martes americana Anaconda (unidentified) Anteater, australian spiny\nBison bison American racer Eunectes sp. Tachyglossus aculeatus \nAmerican crow Coluber constrictor Andean goose Anteater, giant \nCorvus brachyrhynchos American woodcock Chloephaga melanoptera Myrmecophaga tridactyla \n─────────────────────────────────── column first, right to left ────────────────────────────────────\nAnt Scolopax minor American marten Ursus americanus \nAnteater, australian spiny Anaconda (unidentified) Martes americana American buffalo \nTachyglossus aculeatus Eunectes sp. American racer Bison bison \nAnteater, giant Andean goose Coluber constrictor American crow \nMyrmecophaga tridactyla Chloephaga melanoptera American woodcock Corvus brachyrhynchos\n────────────────────────────────────── equal columns, expand ───────────────────────────────────────\nChloephaga melanoptera American racer Ursus americanus \nAnt Coluber constrictor American buffalo \nAnteater, australian spiny American woodcock Bison bison \nTachyglossus aculeatus Scolopax minor American crow \nAnteater, giant Anaconda (unidentified) Corvus brachyrhynchos \nMyrmecophaga tridactyla Eunectes sp. American marten \n Andean goose Martes americana \n─────────────────────────────────────────── fixed width ────────────────────────────────────────────\nAnteater, Eunectes sp. Coluber Corvus Ursus americanus\naustralian spiny constrictor brachyrhynchos \nTachyglossus Andean goose American American marten American buffalo\naculeatus woodcock \nAnteater, giant Chloephaga Scolopax minor Martes americana Bison bison \n melanoptera \nMyrmecophaga Ant Anaconda American racer American crow \ntridactyla (unidentified) \n\n" + print("--") + print(expected) + print("--") assert render() == expected diff --git a/tests/test_table.py b/tests/test_table.py index 8767283c56..77a7533835 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -382,6 +382,30 @@ def test_columns_highlight_added_by_add_row() -> None: assert output == expected +def test_padding_width(): + """Regression test for https://github.com/Textualize/rich/issues/3871 + + Padding should be even between cells/ + + """ + + table = Table.grid(padding=(0, 1)) + + for _ in range(3): + table.add_column(width=3) + + for row in range(1): + table.add_row(*["a" * 3 for _ in range(3)]) + + console = Console(record=True) + console.print(table) + output = console.export_text(styles=True) + + print(repr(output)) + expected = "aaa aaa aaa\n" + assert output == expected + + if __name__ == "__main__": render = render_tables() print(render) From 624664f00bb2b8b7c19f352f0a7a284af4a85412 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 23 Jan 2026 11:27:44 +0000 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28a43eb873..0405f2c876 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - IPython now respects when a `Console` instance is passed to `pretty.install` https://github.com/Textualize/rich/pull/3915 - Fixed extraneous blank line on non-interactive disabled `Progress` https://github.com/Textualize/rich/pull/3905 +- Fixed extra padding on first cell in columns https://github.com/Textualize/rich/pull/3935 ### Added