Repository navigation
with_annotated --help bypasses app.stdout and output redirection #1776
Description
@with_annotated command help goes to process sys.stdout instead of the application's
configured output stream. greet --help > help.txt creates/truncates the file but leaves it
empty, so embedding applications cannot capture help and users cannot export it normally.
Environment
- cmd2 source: current
main, commit93cfe811c6a56015e3f0aec8d8e61c56faf9573c
(editable distribution metadata:4.3.1.dev3+g93cfe811c). - CPython 3.13.12; macOS 27.0, build 26A428.
- rich 15.0.0; rich-argparse 1.8.0; prompt-toolkit 3.0.53.
Reproduction
Run this against the source revision above:
import contextlib
import io
import pathlib
import tempfile
import cmd2
class App(cmd2.Cmd):
@cmd2.with_annotated
def do_greet(self, name: str) -> None:
self.poutput(name)
app_output = io.StringIO()
terminal_output = io.StringIO()
with contextlib.redirect_stdout(terminal_output):
app = App(stdout=app_output, auto_load_commands=False)
app.onecmd_plus_hooks('greet --help')
with tempfile.TemporaryDirectory() as directory:
path = pathlib.Path(directory) / 'help.txt'
app.onecmd_plus_hooks(f'greet --help > "{path}"')
file_output = path.read_text()
print('app output contains help:', 'Usage: greet' in app_output.getvalue())
print('redirected file contains help:', 'Usage: greet' in file_output)
print('process stdout contains help:', 'Usage: greet' in terminal_output.getvalue())
assert 'Usage: greet' in file_output, 'BUG: redirected --help is lost; help file is empty'Observed on unchanged source: False, False, True, followed by
AssertionError: BUG: redirected --help is lost; help file is empty.
Both the app stream and redirected file are empty.
Expected: True, True, False, with help delivered to app.stdout or the requested file
and the assertion passing. Append redirection (>>) should append the help as well.
Local validation and proposed work
An unpublished local regression matrix covers five command forms (ordinary parsing,
with_unknown_args=True, base commands and nested subcommands) with app output, > and >>.
Running the same tests against unchanged production source and the local prototype gives:
pytest tests/test_annotated.py -k test_help_respects_output_destination --no-cov -n 0
unchanged source + added tests: 15 failed, 672 deselected
local prototype + same tests: 15 passed, 672 deselected
The standalone reproduction also fails on unchanged source and passes with that prototype.
These are local macOS/Python results; hosted CI and other platforms have not been exercised.
The annotated wrapper appears to omit the parser's output_to(app.stdout) context around
parsing; @with_argparser already uses it. I'd like to propose a focused fix with these
regression tests after maintainer feedback. No PR has been opened for this report. Searches
of the current queue and relevant closed reports did not identify the same routing bug;
please point out any overlap or preferred approach.
AI assistance was used for the investigation, this report, and preparing/running the local
reproduction and tests.
Activity
KelvinChung2000 commentedon Oct 17, 2026
If you would like to propose a fix, I am happy to review it.
AryanRG commentedon Oct 17, 2026
Thanks for the invitation. I have a focused fix for the annotated help output stream, with red-before/green-after regression tests. I’ll open a PR linked to this issue.