Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ Features:
* Add a ``\service`` prompt token for connections made using ``service=...``
or ``PGSERVICE``. For example, set ``prompt = '\service> '``.

Bug fixes:
----------
* ``--auto-vertical-output``, ``\x auto`` and ``auto_expand`` in the config work
in ``-c``/``-f`` mode. The terminal width was read from the prompt, which
those modes never build, so every statement failed with ``'NoneType' object
has no attribute 'output'``. Without a prompt the terminal is asked directly,
and only when the output is one: a pipe or a file gets the plain table, as
with psql's ``\x auto``.

4.7.1 (2026-09-20)
==================

Expand Down
15 changes: 14 additions & 1 deletion pgcli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,19 @@ def _limit_output(self, cur):

return new_cur, new_status

def _output_width(self):
"""Columns available to auto-expand into, or None when it must not apply.

In -c/-f mode no prompt is ever built, so the terminal is asked
directly. psql's \\x auto only expands when the output is a terminal:
a pipe or a file gets the plain table whatever its width.
"""
if self.prompt_app:
return self.prompt_app.output.get_size().columns
if sys.stdout.isatty():
return shutil.get_terminal_size().columns
return None

def _evaluate_command(self, text):
"""Used to run a command entered by the user during CLI operation
(Puts the E in REPL)
Expand Down Expand Up @@ -1356,7 +1369,7 @@ def _evaluate_command(self, text):
cur, status = self._limit_output(cur)

if self.pgspecial.auto_expand or self.auto_expand:
max_width = self.prompt_app.output.get_size().columns
max_width = self._output_width()
else:
max_width = None

Expand Down
26 changes: 26 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1087,3 +1087,29 @@ def test_connect_timeout_config_value_must_be_a_number(tmpdir):
f.write("[main]\nconnect_timeout = soon\n")
with pytest.raises(ValueError):
PGCli(pgclirc_file=rc)


@dbtest
def test_auto_expand_works_without_a_prompt(executor):
# -c/-f mode never builds the prompt, and --auto-vertical-output (or
# \x auto, or auto_expand in the config) then failed every statement
# with "'NoneType' object has no attribute 'output'". Output that is not
# a terminal gets the plain table, as psql's \x auto does.
cli = PGCli(pgexecute=executor, auto_vertical_output=True)
assert cli.prompt_app is None
with mock.patch("pgcli.main.sys.stdout.isatty", return_value=False):
output, query = cli._evaluate_command("select 1 as a, 2 as b")
assert query.successful
assert not any("RECORD 1" in line for line in output)


@dbtest
def test_auto_expand_without_a_prompt_asks_the_terminal(executor):
cli = PGCli(pgexecute=executor, auto_vertical_output=True)
with (
mock.patch("pgcli.main.sys.stdout.isatty", return_value=True),
mock.patch("pgcli.main.shutil.get_terminal_size", return_value=os.terminal_size((5, 24))),
):
output, query = cli._evaluate_command("select 1 as a, 2 as b")
assert query.successful
assert any("RECORD 1" in line for line in output)
Loading