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
4 changes: 3 additions & 1 deletion b2/_internal/arg_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ def _get_short_description(self) -> str:
return ''

def error(self, message):
self.print_help()
# Help printed because of a command line syntax error is part of the error
# report, not of the command output, hence it goes to stderr.
self.print_help(sys.stderr)

self.exit(2, f'\n{self.prog}: error: {message}\n')

Expand Down
1 change: 1 addition & 0 deletions changelog.d/493.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Print help triggered by a command line syntax error on stderr instead of stdout, so that a mistyped command no longer pollutes redirected or piped output.
26 changes: 26 additions & 0 deletions test/unit/console_tool/test_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,29 @@ def test_help(b2_cli, flag, included, excluded, capsys):
found.add(e)
assert found.issuperset(included), f'expected {included!r} in {out!r}'
assert found.isdisjoint(excluded), f'expected {excluded!r} not in {out!r}'


@pytest.mark.parametrize(
'argv',
[
pytest.param(['--nonexistent-flag'], id='unrecognized-argument'),
pytest.param(['sync'], id='missing-required-arguments'),
pytest.param(['sync', '--nonexistent-flag'], id='unrecognized-subcommand-argument'),
],
)
def test_help_on_command_line_error_goes_to_stderr(b2_cli, argv, capsys):
"""Help printed because of a command line error belongs on stderr, not stdout."""
b2_cli.run(argv, expected_status=2, expected_stdout=None)

captured = capsys.readouterr()
assert captured.out == ''
assert 'error:' in captured.err
assert '-h, --help' in captured.err


def test_help_on_request_goes_to_stdout(b2_cli, capsys):
b2_cli.run(['--help'], expected_stdout=None)

captured = capsys.readouterr()
assert '-h, --help' in captured.out
assert captured.err == ''