From 5ca0788524b705e25a073601497957e31c7ec395 Mon Sep 17 00:00:00 2001 From: DiegoDAF Date: Thu, 19 Feb 2026 16:43:48 -0300 Subject: [PATCH] Rework -t/--tuples-only: set table format only, no header/status suppression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplified per reviewer feedback (j-bennet): - `-t` is now a pure boolean flag (no format argument) - Sets table_format to csv-noheader at startup (like `\T csv-noheader`) - Does NOT suppress timing or status messages - Removed tuples_only from OutputSettings namedtuple - For custom formats, use `\T FORMAT` interactively Made with ❤️ and 🤖 Claude --- changelog.rst | 10 +++++++++ pgcli/main.py | 16 +++++++++++++- tests/test_tuples_only.py | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/test_tuples_only.py diff --git a/changelog.rst b/changelog.rst index 45ee4adfa..f70abb452 100644 --- a/changelog.rst +++ b/changelog.rst @@ -1,3 +1,13 @@ +Upcoming (TBD) +============== + +Features: +--------- +* Add ``-t``/``--tuples-only`` CLI option to set table format at startup. + * Sets table format to ``csv-noheader`` (rows only, no headers) + * CLI shortcut equivalent to ``\T csv-noheader`` + * Does not suppress timing or status messages (use ``\pset`` for that) + 4.4.0 (2025-12-24) ================== diff --git a/pgcli/main.py b/pgcli/main.py index de09cc1af..7bbb79a7f 100644 --- a/pgcli/main.py +++ b/pgcli/main.py @@ -179,6 +179,7 @@ def __init__( application_name="pgcli", single_connection=False, less_chatty=None, + tuples_only=None, prompt=None, prompt_dsn=None, auto_vertical_output=False, @@ -236,7 +237,10 @@ def __init__( self.min_num_menu_lines = c["main"].as_int("min_num_menu_lines") self.multiline_continuation_char = c["main"]["multiline_continuation_char"] - self.table_format = c["main"]["table_format"] + if tuples_only: + self.table_format = "csv-noheader" + else: + self.table_format = c["main"]["table_format"] self.syntax_style = c["main"]["syntax_style"] self.cli_style = c["colors"] self.wider_completion_menu = c["main"].as_bool("wider_completion_menu") @@ -1429,6 +1433,14 @@ def echo_via_pager(self, text, color=None): default=False, help="Skip intro on startup and goodbye on exit.", ) +@click.option( + "-t", + "--tuples-only", + "tuples_only", + is_flag=True, + default=False, + help="Print rows only, using csv-noheader format. Same as \\T csv-noheader.", +) @click.option("--prompt", help='Prompt format (Default: "\\u@\\h:\\d> ").') @click.option( "--prompt-dsn", @@ -1492,6 +1504,7 @@ def cli( row_limit, application_name, less_chatty, + tuples_only, prompt, prompt_dsn, list_databases, @@ -1554,6 +1567,7 @@ def cli( application_name=application_name, single_connection=single_connection, less_chatty=less_chatty, + tuples_only=tuples_only, prompt=prompt, prompt_dsn=prompt_dsn, auto_vertical_output=auto_vertical_output, diff --git a/tests/test_tuples_only.py b/tests/test_tuples_only.py new file mode 100644 index 000000000..24e6bfd32 --- /dev/null +++ b/tests/test_tuples_only.py @@ -0,0 +1,44 @@ +from unittest.mock import patch + +from click.testing import CliRunner + +from pgcli.main import cli, PGCli + + +def test_tuples_only_flag_passed_to_pgcli(): + """Test that -t passes tuples_only=True to PGCli.""" + runner = CliRunner() + with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli: + runner.invoke(cli, ["-t", "mydb"]) + call_kwargs = mock_pgcli.call_args[1] + assert call_kwargs["tuples_only"] is True + + +def test_tuples_only_long_form(): + """Test that --tuples-only passes tuples_only=True to PGCli.""" + runner = CliRunner() + with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli: + runner.invoke(cli, ["--tuples-only", "mydb"]) + call_kwargs = mock_pgcli.call_args[1] + assert call_kwargs["tuples_only"] is True + + +def test_tuples_only_not_set_by_default(): + """Test that tuples_only is False when -t is not used.""" + runner = CliRunner() + with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli: + runner.invoke(cli, ["mydb"]) + call_kwargs = mock_pgcli.call_args[1] + assert call_kwargs["tuples_only"] is False + + +def test_tuples_only_sets_csv_noheader_format(): + """Test that tuples_only=True sets table_format to csv-noheader.""" + pgcli = PGCli(tuples_only=True) + assert pgcli.table_format == "csv-noheader" + + +def test_default_table_format_without_tuples_only(): + """Test that table_format uses config default when tuples_only is False.""" + pgcli = PGCli() + assert pgcli.table_format != "csv-noheader" # Uses config default