From dc897348f29bb462193f82cb585b1f68e1440b6f Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Thu, 5 Mar 2026 16:35:16 +0100 Subject: [PATCH 1/5] Apply ruff/pyupgrade rule UP007 Use `X | Y` for type annotations --- tabulate/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tabulate/__init__.py b/tabulate/__init__.py index 9ee72fe..1cb052b 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -14,7 +14,7 @@ import re import sys import textwrap -from typing import Callable, Union +from typing import Callable import warnings try: @@ -2529,7 +2529,7 @@ def _build_row( padded_cells: list[list], colwidths: list[int], colaligns: list[str], - rowfmt: Union[DataRow, Callable], + rowfmt: DataRow | Callable, ) -> str: "Return a string which represents a row of data cells." if not rowfmt: From 64b39766e0153e24b6806b99d41830514157e0f4 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Thu, 5 Mar 2026 09:05:34 +0100 Subject: [PATCH 2/5] Apply ruff/pyupgrade rule UP018 Unnecessary `int` call (rewrite as a literal) --- test/test_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_regression.py b/test/test_regression.py index 051bf03..98eefba 100644 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -341,7 +341,7 @@ def test_multiline_with_wide_characters(): def test_align_long_integers(): "Regression: long integers should be aligned as integers (issue #61)" - table = [[int(1)], [int(234)]] + table = [[1], [234]] result = tabulate(table, tablefmt="plain") expected = "\n".join([" 1", "234"]) assert_equal(expected, result) From b565dc4291301217aeb6207e27170a8c964e1e83 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Thu, 5 Mar 2026 09:11:28 +0100 Subject: [PATCH 3/5] Apply ruff/pyupgrade rule UP031 Use format specifiers instead of percent format --- benchmark/benchmark.py | 8 ++++---- tabulate/__init__.py | 10 +++++----- test/common.py | 8 ++++---- test/test_api.py | 2 +- test/test_input.py | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/benchmark/benchmark.py b/benchmark/benchmark.py index d405f5c..f632a04 100644 --- a/benchmark/benchmark.py +++ b/benchmark/benchmark.py @@ -55,13 +55,13 @@ def run_tabulate(table, widechars=False): methods = [ ("join with tabs and newlines", "join_table(table)"), ("csv to StringIO", "csv_table(table)"), - ("tabulate (%s)" % tabulate.__version__, "run_tabulate(table)"), + (f"tabulate ({tabulate.__version__})", "run_tabulate(table)"), ( - "tabulate (%s, WIDE_CHARS_MODE)" % tabulate.__version__, + f"tabulate ({tabulate.__version__}, WIDE_CHARS_MODE)", "run_tabulate(table, widechars=True)", ), - ("PrettyTable (%s)" % prettytable.__version__, "run_prettytable(table)"), - ("texttable (%s)" % texttable.__version__, "run_texttable(table)"), + (f"PrettyTable ({prettytable.__version__})", "run_prettytable(table)"), + (f"texttable ({texttable.__version__})", "run_texttable(table)"), ] diff --git a/tabulate/__init__.py b/tabulate/__init__.py index 1cb052b..13c06b2 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -1046,7 +1046,7 @@ def _padleft(width, s): True """ - fmt = "{0:>%ds}" % width + fmt = f"{{0:>{width}s}}" return fmt.format(s) @@ -1057,7 +1057,7 @@ def _padright(width, s): True """ - fmt = "{0:<%ds}" % width + fmt = f"{{0:<{width}s}}" return fmt.format(s) @@ -1068,7 +1068,7 @@ def _padboth(width, s): True """ - fmt = "{0:^%ds}" % width + fmt = f"{{0:^{width}s}}" return fmt.format(s) @@ -2805,7 +2805,7 @@ def _wrap_chunks(self, chunks): """ lines = [] if self.width <= 0: - raise ValueError("invalid width %r (must be > 0)" % self.width) + raise ValueError(f"invalid width {self.width!r} (must be > 0)") if self.max_lines is not None: if self.max_lines > 1: indent = self.subsequent_indent @@ -2962,7 +2962,7 @@ def _main(): colalign = value.split() elif opt in ["-f", "--format"]: if value not in tabulate_formats: - print("%s is not a supported table format" % value) + print(f"{value} is not a supported table format") print(usage) sys.exit(3) tablefmt = value diff --git a/test/common.py b/test/common.py index 6afb4be..fc99400 100644 --- a/test/common.py +++ b/test/common.py @@ -5,15 +5,15 @@ def assert_equal(expected, result): - print("Expected:\n%r\n" % expected) - print("Got:\n%r\n" % result) + print(f"Expected:\n{expected!r}\n") + print(f"Got:\n{result!r}\n") assert expected == result def assert_in(result, expected_set): for i, expected in enumerate(expected_set, start=1): - print("Expected %d:\n%s\n" % (i, expected)) - print("Got:\n%s\n" % result) + print(f"Expected {i}:\n{expected}\n") + print(f"Got:\n{result}\n") assert result in expected_set diff --git a/test/test_api.py b/test/test_api.py index 3e0963a..cb59836 100644 --- a/test/test_api.py +++ b/test/test_api.py @@ -14,7 +14,7 @@ def test_tabulate_formats(): "API: tabulate_formats is a list of strings" supported = tabulate_formats - print("tabulate_formats = %r" % supported) + print(f"tabulate_formats = {supported!r}") assert type(supported) is list for fmt in supported: assert type(fmt) is str diff --git a/test/test_input.py b/test/test_input.py index 908d8d7..3cc3237 100644 --- a/test/test_input.py +++ b/test/test_input.py @@ -96,7 +96,7 @@ def test_dict_like(): expected1 = "\n".join([" a b", "--- ---", " 0 101", " 1 102", " 2 103", " 104"]) expected2 = "\n".join([" b a", "--- ---", "101 0", "102 1", "103 2", "104"]) result = tabulate(dd, "keys") - print("Keys' order: %s" % dd.keys()) + print(f"Keys' order: {dd.keys()}") assert_in(result, [expected1, expected2]) From eeb4cb80caa8a97f36802b65192cb41f29c868b4 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Thu, 5 Mar 2026 16:36:13 +0100 Subject: [PATCH 4/5] Apply ruff/pyupgrade rule UP035 Import from `collections.abc` instead --- tabulate/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tabulate/__init__.py b/tabulate/__init__.py index 13c06b2..449f78c 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -1,7 +1,7 @@ """Pretty-print tabular data.""" from collections import namedtuple -from collections.abc import Iterable, Sized +from collections.abc import Callable, Iterable, Sized import dataclasses from dataclasses import dataclass from decimal import Decimal @@ -14,7 +14,6 @@ import re import sys import textwrap -from typing import Callable import warnings try: From b6242512b17b1b99ac9b3ea0b3e62d0e9db5c04e Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Thu, 5 Mar 2026 09:12:38 +0100 Subject: [PATCH 5/5] Enforce ruff/pyupgrade rules (UP) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fb782b8..6a56477 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ line-length = 99 exclude = ["tabulate/_version.py"] [tool.ruff.lint] -extend-select = ["W", "C4", "ISC", "I", "C90"] +extend-select = ["W", "C4", "ISC", "I", "C90", "UP"] ignore = ["E721", "C901"] [tool.ruff.lint.mccabe]