-
-
Notifications
You must be signed in to change notification settings - Fork 736
fix(core): Ensure exit code 0 when no_args_is_help
shows help
#1240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
When `no_args_is_help` is True and no arguments are provided to a Typer application, the help message is displayed. However, an additional empty error panel also currently appears, and the application exits with status code 2. This issue affects applications using Click version 8.2.0 or later. The root cause is a change in Click (pallets/click@d8763b93) where `Command.parse_args` now raises `click.exceptions.NoArgsIsHelpError` when `no_args_is_help` is true and no arguments are given. Previously, Click would print help and call `ctx.exit()` directly within `parse_args`. Typer's generic `except click.ClickException as e:` block in `core.py._main` catches this `NoArgsIsHelpError`. The subsequent call to `rich_utils.rich_format_error(e)` (or `e.show()` if Rich is not used) results in the help message being displayed. This is because `NoArgsIsHelpError` is a subclass of `click.UsageError`, and `UsageError.show()` prints `ctx.get_help()`. However, this process also leads to an attempt to format a non-existent specific error message (as `NoArgsIsHelpError.format_message()` is empty), causing the blank error panel. Finally, `sys.exit(e.exit_code)` uses the `UsageError`'s exit code of 2. This commit addresses the issue by checking if the `click.ClickException` is of instance `NoArgsIsHelpError` and then raising `click.exceptions.Exit(0)` This ensures that after the help message is displayed, the application exits cleanly with status code 0 and without displaying the erroneous empty error panel, aligning with the intended behavior of `no_args_is_help`.
Should we also update the test that was changed here to add back the assert result.exit_code == 0 |
@DHUKK Thanks, I have restored the test. I also added commented code for dropping Click<8.2 support. |
I'd love this to be merged, I think what's breaking the pipeline is that this issue is missing a label? For now I'm just doing something akin to this! First remove @app.callback(invoke_without_command=True)
def main(ctx: typer.Context):
"""My awesome CLI tool"""
if ctx.invoked_subcommand is None:
print(ctx.get_help())
raise typer.Exit() |
@SeedyROM It doesn't let me put a label, I guess only maintainers can do so. |
except click.ClickException as e: | ||
# TODO: When deprecating Click < 8.2 remove this section [start] | ||
_no_args_is_help_error = getattr( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than probing attrs and instance, I suggest using the exception we want to catch.
Click's init.py doesn't pull in the NoArgsIsHelpError
exception into itself. So instead, we can easily do the same at the top of this file with;
from click.exceptions import NoArgsIsHelpError
and then here simply the code to be
...
except KeyboardInterrupt as e:
raise click.exceptions.Exit(130) from e
except NoArgsIsHelpError as e:
raise click.exceptions.Exit(0) from e
except click.ClickException as e:
...
When
no_args_is_help
is True and no arguments are provided to a Typer application, the help message is displayed. However, an additional empty error panel also currently appears, and the application exits with status code 2. This issue affects applications using Click version 8.2.0 or later.The root cause is a change in Click (pallets/click@d8763b93) where
Command.parse_args
now raisesclick.exceptions.NoArgsIsHelpError
whenno_args_is_help
is true and no arguments are given. Previously, Click would print help and callctx.exit()
directly withinparse_args
.Typer's generic
except click.ClickException as e:
block incore.py._main
catches thisNoArgsIsHelpError
. The subsequent call torich_utils.rich_format_error(e)
(ore.show()
if Rich is not used) results in the help message being displayed. This is becauseNoArgsIsHelpError
is a subclass ofclick.UsageError
, andUsageError.show()
printsctx.get_help()
. However, this process also leads to an attempt to format a non-existent specific error message (asNoArgsIsHelpError.format_message()
is empty), causing the blank error panel. Finally,sys.exit(e.exit_code)
uses theUsageError
's exit code of 2.This commit addresses the issue by checking if the
click.ClickException
is of instanceNoArgsIsHelpError
and then raisingclick.exceptions.Exit(0)
This ensures that after the help message is displayed, the application exits cleanly with status code 0 and without displaying the erroneous empty error panel, aligning with the intended behavior of
no_args_is_help
.