Skip to content

Commit 3d86709

Browse files
committed
Rework -t/--tuples-only: set table format only, no header/status suppression
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
1 parent a0c2ee4 commit 3d86709

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

changelog.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Upcoming (TBD)
44
Features:
55
---------
66
* Add support for `\\T` prompt escape sequence to display transaction status (similar to psql's `%x`).
7+
* Add ``-t``/``--tuples-only`` CLI option to set table format at startup.
8+
* Sets table format to ``csv-noheader`` (rows only, no headers)
9+
* CLI shortcut equivalent to ``\T csv-noheader``
10+
* Does not suppress timing or status messages (use ``\pset`` for that)
711

812
4.4.0 (2025-12-24)
913
==================

pgcli/main.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ def __init__(
179179
application_name="pgcli",
180180
single_connection=False,
181181
less_chatty=None,
182+
tuples_only=None,
182183
prompt=None,
183184
prompt_dsn=None,
184185
auto_vertical_output=False,
@@ -236,7 +237,10 @@ def __init__(
236237

237238
self.min_num_menu_lines = c["main"].as_int("min_num_menu_lines")
238239
self.multiline_continuation_char = c["main"]["multiline_continuation_char"]
239-
self.table_format = c["main"]["table_format"]
240+
if tuples_only:
241+
self.table_format = "csv-noheader"
242+
else:
243+
self.table_format = c["main"]["table_format"]
240244
self.syntax_style = c["main"]["syntax_style"]
241245
self.cli_style = c["colors"]
242246
self.wider_completion_menu = c["main"].as_bool("wider_completion_menu")
@@ -1430,6 +1434,14 @@ def echo_via_pager(self, text, color=None):
14301434
default=False,
14311435
help="Skip intro on startup and goodbye on exit.",
14321436
)
1437+
@click.option(
1438+
"-t",
1439+
"--tuples-only",
1440+
"tuples_only",
1441+
is_flag=True,
1442+
default=False,
1443+
help="Print rows only, using csv-noheader format. Same as \\T csv-noheader.",
1444+
)
14331445
@click.option("--prompt", help='Prompt format (Default: "\\u@\\h:\\d> ").')
14341446
@click.option(
14351447
"--prompt-dsn",
@@ -1493,6 +1505,7 @@ def cli(
14931505
row_limit,
14941506
application_name,
14951507
less_chatty,
1508+
tuples_only,
14961509
prompt,
14971510
prompt_dsn,
14981511
list_databases,
@@ -1555,6 +1568,7 @@ def cli(
15551568
application_name=application_name,
15561569
single_connection=single_connection,
15571570
less_chatty=less_chatty,
1571+
tuples_only=tuples_only,
15581572
prompt=prompt,
15591573
prompt_dsn=prompt_dsn,
15601574
auto_vertical_output=auto_vertical_output,

tests/test_tuples_only.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from unittest.mock import patch
2+
3+
from click.testing import CliRunner
4+
5+
from pgcli.main import cli, PGCli
6+
7+
8+
def test_tuples_only_flag_passed_to_pgcli():
9+
"""Test that -t passes tuples_only=True to PGCli."""
10+
runner = CliRunner()
11+
with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli:
12+
runner.invoke(cli, ["-t", "mydb"])
13+
call_kwargs = mock_pgcli.call_args[1]
14+
assert call_kwargs["tuples_only"] is True
15+
16+
17+
def test_tuples_only_long_form():
18+
"""Test that --tuples-only passes tuples_only=True to PGCli."""
19+
runner = CliRunner()
20+
with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli:
21+
runner.invoke(cli, ["--tuples-only", "mydb"])
22+
call_kwargs = mock_pgcli.call_args[1]
23+
assert call_kwargs["tuples_only"] is True
24+
25+
26+
def test_tuples_only_not_set_by_default():
27+
"""Test that tuples_only is False when -t is not used."""
28+
runner = CliRunner()
29+
with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli:
30+
runner.invoke(cli, ["mydb"])
31+
call_kwargs = mock_pgcli.call_args[1]
32+
assert call_kwargs["tuples_only"] is False
33+
34+
35+
def test_tuples_only_sets_csv_noheader_format():
36+
"""Test that tuples_only=True sets table_format to csv-noheader."""
37+
pgcli = PGCli(tuples_only=True)
38+
assert pgcli.table_format == "csv-noheader"
39+
40+
41+
def test_default_table_format_without_tuples_only():
42+
"""Test that table_format uses config default when tuples_only is False."""
43+
pgcli = PGCli()
44+
assert pgcli.table_format != "csv-noheader" # Uses config default

0 commit comments

Comments
 (0)