-
Notifications
You must be signed in to change notification settings - Fork 35
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
Exit codes aren't being propogated. #114
Comments
I can confirm that. The
and the problem might come from the fact that And it looks like just rich-click/src/rich_click/rich_command.py Lines 59 to 74 in 12f52d2
|
In order to achieve full parity in behavior with Click, it looks like we will need to re-implement all of The reason why is because a return value from main() when So if we want rich-click to be a true drop-in replacement for Click, it seems the only real solution here is to just re-implement the entire method. This is not ideal due to forward compatibility concerns. But I think it may be the best I can do. We can possibly raise an issue in the future and see if the Pallets team would be amenable to some sort of abstraction that makes this easier to do. Anyway, I'm working on this in a test-driven way. We have 4 behaviors we want to make sure work across both groups and commands, so 8 tests total. Here's the test file so far: # tests/test_exit_code.py
import sys
from click.testing import CliRunner
from rich_click import command, group, RichContext, pass_context
# Don't use the 'invoke' fixture because we want control over the standalone_mode kwarg.
def test_command_exit_code_with_context():
for expected_exit_code in range(10):
@command("cli")
@pass_context
def cli(ctx: RichContext):
ctx.exit(expected_exit_code)
runner = CliRunner()
res = runner.invoke(cli, [])
assert res.exit_code == expected_exit_code
def test_group_exit_code_with_context():
for expected_exit_code in range(10):
@group("cli")
@pass_context
def cli(ctx: RichContext):
ctx.exit(expected_exit_code)
@cli.command("subcommand")
@pass_context
def subcommand(ctx: RichContext):
ctx.exit(999)
runner = CliRunner()
res = runner.invoke(cli, ["subcommand"])
assert res.exit_code == expected_exit_code
def test_command_exit_code_with_sys_exit():
for expected_exit_code in range(10):
@command("cli")
def cli():
sys.exit(expected_exit_code)
runner = CliRunner()
res = runner.invoke(cli, [])
assert res.exit_code == expected_exit_code
def test_group_exit_code_with_sys_exit():
for expected_exit_code in range(10):
@group("cli")
def cli():
sys.exit(expected_exit_code)
@cli.command("subcommand")
def subcommand():
sys.exit(999)
runner = CliRunner()
res = runner.invoke(cli, ["subcommand"])
assert res.exit_code == expected_exit_code
def test_command_return_value_does_not_raise_exit_code():
@command("cli")
def cli():
return 5
runner = CliRunner()
res = runner.invoke(cli, [])
assert res.exit_code == 0
def test_group_return_value_does_not_raise_exit_code():
@group("cli")
def cli():
return 5
@cli.command("subcommand")
def subcommand():
return 10
runner = CliRunner()
res = runner.invoke(cli, [])
assert res.exit_code == 0
def test_command_return_value_is_exit_code_when_not_standalone():
for expected_exit_code in range(10):
@command("cli")
@pass_context
def cli(ctx: RichContext):
ctx.exit(expected_exit_code)
runner = CliRunner()
res = runner.invoke(cli, [], standalone_mode=False)
assert res.return_value == expected_exit_code
def test_group_return_value_is_exit_code_when_not_standalone():
for expected_exit_code in range(10):
@group("cli")
@pass_context
def cli(ctx: RichContext):
ctx.exit(expected_exit_code)
@cli.command("subcommand")
@pass_context
def subcommand(ctx: RichContext):
# I should not run
ctx.exit(0)
runner = CliRunner()
res = runner.invoke(cli, ["subcommand"], standalone_mode=False)
assert res.return_value == expected_exit_code I should have something soon! |
Done. This will be fixed in 1.7.0. |
Oh yea this is a maintenence hell 😞
Thanks for implementing this anyway 😄 ! It is still bad in the meantime if exit code is wrong
Great, Well I also detected this issue, because my unit-tests fail when rich-click is installed, but succeed without it 😅 |
To reproduce run the following snippet of code:
Invoking as
python foo.py || echo $?
prints just "exiting", which means the command is not failing.After replacing the import with
import click
,python foo.py || echo $?
correctly prints "exiting" followed by "2".The text was updated successfully, but these errors were encountered: