From 92cb7096adaf162de9cbf7da6b432bc72cf68819 Mon Sep 17 00:00:00 2001 From: Israel Roldan Date: Sat, 13 Apr 2024 00:24:13 -0600 Subject: [PATCH 1/3] Fixed the problem with the intfmt argument. --- tabulate/__init__.py | 2 ++ test/test_output.py | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/tabulate/__init__.py b/tabulate/__init__.py index 11bb865..03880ee 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -1229,6 +1229,8 @@ def _format(val, valtype, floatfmt, intfmt, missingval="", has_invisible=True): if valtype is str: return f"{val}" elif valtype is int: + if isinstance(val, str): + intfmt = "" return format(val, intfmt) elif valtype is bytes: try: diff --git a/test/test_output.py b/test/test_output.py index d572498..872e274 100644 --- a/test/test_output.py +++ b/test/test_output.py @@ -1,4 +1,5 @@ """Test output of the various forms of tabular data.""" +import pytest import tabulate as tabulate_module from common import assert_equal, raises, skip, check_warnings @@ -2638,6 +2639,44 @@ def test_intfmt(): assert_equal(expected, result) +def test_intfmt_with_string_as_integer(): + "Output: integer format" + result = tabulate([[82642], ["1500"], [2463]], intfmt=",", tablefmt="plain") + expected = "82,642\n 1500\n 2,463" + assert_equal(expected, result) + + +@pytest.mark.skip(reason="It detects all values as floats but there are strings and integers.") +def test_intfmt_with_string_with_floats(): + "Output: integer format" + result = tabulate([[82000.38], ["1500.47"], ["2463"], [92165]], intfmt=",", tablefmt="plain") + expected = "82000.4\n 1500.47\n 2463\n92,165" + assert_equal(expected, result) + + +def test_intfmt_with_colors(): + "Regression: Align ANSI-colored values as if they were colorless." + colortable = [ + ("abcd", 42, "\x1b[31m42\x1b[0m"), + ("elfy", 1010, "\x1b[32m1010\x1b[0m"), + ] + colorheaders = ("test", "\x1b[34mtest\x1b[0m", "test") + formatted = tabulate(colortable, colorheaders, "grid", intfmt=",") + expected = "\n".join( + [ + "+--------+--------+--------+", + "| test | \x1b[34mtest\x1b[0m | test |", + "+========+========+========+", + "| abcd | 42 | \x1b[31m42\x1b[0m |", + "+--------+--------+--------+", + "| elfy | 1,010 | \x1b[32m1010\x1b[0m |", + "+--------+--------+--------+", + ] + ) + print(f"expected: {expected!r}\n\ngot: {formatted!r}\n") + assert_equal(expected, formatted) + + def test_empty_data_with_headers(): "Output: table with empty data and headers as firstrow" expected = "" From e45cac16676f0955b2fd05389d97b3e6f71fd66c Mon Sep 17 00:00:00 2001 From: Israel Roldan Date: Sat, 13 Apr 2024 16:09:47 -0600 Subject: [PATCH 2/3] Added validation for integer numbers format when the number is colored. --- tabulate/__init__.py | 9 +++++++++ test/test_output.py | 18 +++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/tabulate/__init__.py b/tabulate/__init__.py index 03880ee..9e96606 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -1230,6 +1230,15 @@ def _format(val, valtype, floatfmt, intfmt, missingval="", has_invisible=True): return f"{val}" elif valtype is int: if isinstance(val, str): + val_striped = val.encode('unicode_escape').decode('utf-8') + colored = re.search(r'(\\[xX]+[0-9a-fA-F]+\[\d+[mM]+)([0-9.]+)(\\.*)$', val_striped) + if colored: + total_groups = len(colored.groups()) + if total_groups == 3: + digits = colored.group(2) + if digits.isdigit(): + val_new = colored.group(1) + format(int(digits), intfmt) + colored.group(3) + val = val_new.encode('utf-8').decode('unicode_escape') intfmt = "" return format(val, intfmt) elif valtype is bytes: diff --git a/test/test_output.py b/test/test_output.py index 872e274..8d80d95 100644 --- a/test/test_output.py +++ b/test/test_output.py @@ -2657,20 +2657,20 @@ def test_intfmt_with_string_with_floats(): def test_intfmt_with_colors(): "Regression: Align ANSI-colored values as if they were colorless." colortable = [ - ("abcd", 42, "\x1b[31m42\x1b[0m"), - ("elfy", 1010, "\x1b[32m1010\x1b[0m"), + ("\x1b[33mabc\x1b[0m", 42, "\x1b[31m42\x1b[0m"), + ("\x1b[35mdef\x1b[0m", 987654321, "\x1b[32m987654321\x1b[0m"), ] colorheaders = ("test", "\x1b[34mtest\x1b[0m", "test") formatted = tabulate(colortable, colorheaders, "grid", intfmt=",") expected = "\n".join( [ - "+--------+--------+--------+", - "| test | \x1b[34mtest\x1b[0m | test |", - "+========+========+========+", - "| abcd | 42 | \x1b[31m42\x1b[0m |", - "+--------+--------+--------+", - "| elfy | 1,010 | \x1b[32m1010\x1b[0m |", - "+--------+--------+--------+", + "+--------+-------------+-------------+", + "| test | \x1b[34mtest\x1b[0m | test |", + "+========+=============+=============+", + "| \x1b[33mabc\x1b[0m | 42 | \x1b[31m42\x1b[0m |", + "+--------+-------------+-------------+", + "| \x1b[35mdef\x1b[0m | 987,654,321 | \x1b[32m987,654,321\x1b[0m |", + "+--------+-------------+-------------+", ] ) print(f"expected: {expected!r}\n\ngot: {formatted!r}\n") From 23b3cc6537d2ca5cabad662a6ebf9dc371873d6c Mon Sep 17 00:00:00 2001 From: Israel Roldan Date: Sun, 14 Apr 2024 09:54:46 -0600 Subject: [PATCH 3/3] Updated the import of the PyTest jump decorator. --- test/test_output.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_output.py b/test/test_output.py index 8d80d95..8d0207c 100644 --- a/test/test_output.py +++ b/test/test_output.py @@ -1,5 +1,5 @@ """Test output of the various forms of tabular data.""" -import pytest +from pytest import mark import tabulate as tabulate_module from common import assert_equal, raises, skip, check_warnings @@ -2646,7 +2646,7 @@ def test_intfmt_with_string_as_integer(): assert_equal(expected, result) -@pytest.mark.skip(reason="It detects all values as floats but there are strings and integers.") +@mark.skip(reason="It detects all values as floats but there are strings and integers.") def test_intfmt_with_string_with_floats(): "Output: integer format" result = tabulate([[82000.38], ["1500.47"], ["2463"], [92165]], intfmt=",", tablefmt="plain")