From 59e25205951180f18de770999a116392dba9cd5e Mon Sep 17 00:00:00 2001 From: uttam12331 Date: Mon, 29 Jun 2026 20:49:37 +0530 Subject: [PATCH] Accept tuples for rowalign and other sequence arguments tabulate(..., rowalign=('top', 'bottom')) raised 'TypeError: can only concatenate tuple (not "list") to tuple' because _expand_iterable() concatenated the padding list directly onto the original iterable. Coerce the iterable to a list first, so non-list sequences (e.g. a tuple passed as rowalign or maxcolwidths) work the same as lists. Closes #434 --- tabulate/__init__.py | 3 +++ test/test_regression.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/tabulate/__init__.py b/tabulate/__init__.py index 12a2950..11b0650 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -2488,6 +2488,9 @@ def _expand_iterable(original, num_desired, default): length `num_desired` completely populated with `default will be returned """ if isinstance(original, Iterable) and not isinstance(original, str): + # Coerce to list so non-list iterables (e.g. a tuple passed as + # `rowalign`/`maxcolwidths`) can be concatenated with the padding list. + original = list(original) return original + [default] * (num_desired - len(original)) else: return [default] * num_desired diff --git a/test/test_regression.py b/test/test_regression.py index 9555676..0ce5df3 100644 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -598,3 +598,10 @@ def test_github_escape_pipe_character(): result = tabulate([["foo|bar"]], headers=("spam|eggs",), tablefmt="github") expected = "| spam\\|eggs |\n|:------------|\n| foo\\|bar |" assert_equal(expected, result) + + +def test_rowalign_tuple(): + "Regression: rowalign passed as a tuple must not raise (issue #434)." + expected = tabulate([[1, 2], [3, 4]], rowalign=["top", "bottom"]) + result = tabulate([[1, 2], [3, 4]], rowalign=("top", "bottom")) + assert_equal(expected, result)