From 474fc1073029f2874fd731be3fadf53a951cb828 Mon Sep 17 00:00:00 2001 From: AlexXuz Date: Tue, 27 Oct 2026 09:31:07 -0700 Subject: [PATCH 1/2] Preserve boolean-looking text during wrapping --- tabulate/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tabulate/__init__.py b/tabulate/__init__.py index 12a2950..2b19a91 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -1646,12 +1646,13 @@ def _wrap_text_to_colwidths( # formatting of types (such as datetimes) may need to be more # explicit than just `str` of the object. Also doesn't work for # custom floatfmt/intfmt, nor with any missing/blank cells. + # Preserve boolean strings: bool("False") would change their value. casted_cell = ( missingval if cell is None else ( str(cell) - if cell == "" or _isnumber(cell) + if cell == "" or _isnumber(cell) or _isbool(cell) else str(_type(cell, numparse)(cell)) ) ) From 09fa175318930179f8978f0bbaffbeebbb775ccc Mon Sep 17 00:00:00 2001 From: AlexXuz Date: Tue, 27 Oct 2026 09:31:15 -0700 Subject: [PATCH 2/2] Cover wrapped boolean text in cells and headers --- test/test_textwrapper.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/test_textwrapper.py b/test/test_textwrapper.py index e6bab0f..073de04 100644 --- a/test/test_textwrapper.py +++ b/test/test_textwrapper.py @@ -3,6 +3,8 @@ import datetime from textwrap import TextWrapper as OTW +import pytest + from tabulate import _CustomTextWrap as CTW, _strip_ansi, tabulate from common import assert_equal, skip @@ -326,6 +328,29 @@ def test_wrap_optional_bool_strs(): assert_equal(expected, result) +@pytest.mark.parametrize("value", ["True", "False", True, False]) +@pytest.mark.parametrize("width", [3, 5, 10]) +@pytest.mark.parametrize("options", [{}, {"disable_numparse": True}]) +def test_wrap_bool_values_preserves_text(value, width, options): + """Wrapping must not interpret nonempty boolean strings as truthy.""" + expected = str(value) + if width == 3 and (isinstance(value, str) or options.get("disable_numparse")): + expected = expected[:3] + "\n" + expected[3:] + result = tabulate([[value]], tablefmt="plain", maxcolwidths=width, **options) + assert_equal(expected, result) + + +@pytest.mark.parametrize("value", ["True", "False"]) +@pytest.mark.parametrize("width", [3, 5, 10]) +@pytest.mark.parametrize("options", [{}, {"disable_numparse": True}]) +def test_wrap_bool_headers_preserves_text(value, width, options): + expected = value + if width == 3: + expected = expected[:3] + "\n" + expected[3:] + result = tabulate([], headers=[value], tablefmt="plain", maxheadercolwidths=width, **options) + assert_equal(expected, result) + + def test_wrap_wide_char_no_column_overflow(): "TextWrapper: wide chars must not overflow the requested column width." try: