From a5d06f5d6677c089579a67a4541087b210ec0101 Mon Sep 17 00:00:00 2001 From: Brian Kohan Date: Wed, 24 Jan 2024 15:48:38 -0800 Subject: [PATCH 1/8] Use shell_complete when supplied on Arguments - fixes #334 --- tests/assets/compat_arg_complete_click7_8.py | 28 +++++++++++++++++++ tests/test_compat/test_arg_completion.py | 29 ++++++++++++++++++++ typer/main.py | 1 + 3 files changed, 58 insertions(+) create mode 100644 tests/assets/compat_arg_complete_click7_8.py create mode 100644 tests/test_compat/test_arg_completion.py diff --git a/tests/assets/compat_arg_complete_click7_8.py b/tests/assets/compat_arg_complete_click7_8.py new file mode 100644 index 0000000000..3ccbf4f3b2 --- /dev/null +++ b/tests/assets/compat_arg_complete_click7_8.py @@ -0,0 +1,28 @@ +import click +import typer +from typer._compat_utils import _get_click_major + +app = typer.Typer() + + +def shell_complete(ctx: click.Context, param: click.Parameter, incomplete: str): + typer.echo(f"ctx: {ctx.info_name}", err=True) + typer.echo(f"arg is: {param.name}", err=True) + typer.echo(f"incomplete is: {incomplete}", err=True) + if _get_click_major() > 7: + from click.shell_completion import CompletionItem + + return [CompletionItem("Emma", help="Emma is awesome.")] + return ["Emma"] + + +@app.command(context_settings={"auto_envvar_prefix": "TEST"}) +def main(name: str = typer.Argument(shell_complete=shell_complete)): + """ + Say hello. + """ + print(f"Hello {name}") + + +if __name__ == "__main__": + app() diff --git a/tests/test_compat/test_arg_completion.py b/tests/test_compat/test_arg_completion.py new file mode 100644 index 0000000000..9892cf2cbd --- /dev/null +++ b/tests/test_compat/test_arg_completion.py @@ -0,0 +1,29 @@ +import os +import subprocess +import sys + +from typer._compat_utils import _get_click_major + +from tests.assets import compat_arg_complete_click7_8 as mod + + +def test_arg_completion(): + result = subprocess.run( + [sys.executable, "-m", "coverage", "run", mod.__file__, "E"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding="utf-8", + env={ + **os.environ, + "_COMPAT_ARG_COMPLETE_CLICK7_8.PY_COMPLETE": "complete_zsh", + "_TYPER_COMPLETE_ARGS": "compat_arg_complete_click7_8.py E", + "_TYPER_COMPLETE_TESTING": "True", + }, + ) + assert "Emma" in result.stdout + if _get_click_major() > 7: + assert "Emma is awesome." in result.stdout + + assert "ctx: compat_arg_complete_click7_8" in result.stderr + assert "arg is: name" in result.stderr + assert "incomplete is: E" in result.stderr diff --git a/typer/main.py b/typer/main.py index 9de5f5960d..ab87abe47a 100644 --- a/typer/main.py +++ b/typer/main.py @@ -936,6 +936,7 @@ def get_click_param( expose_value=parameter_info.expose_value, is_eager=parameter_info.is_eager, envvar=parameter_info.envvar, + shell_complete=parameter_info.shell_complete, autocompletion=get_param_completion(parameter_info.autocompletion), # Rich settings rich_help_panel=parameter_info.rich_help_panel, From ccffc524cb89a4db34fd4931d91ccefce0e4bd8c Mon Sep 17 00:00:00 2001 From: Brian Kohan Date: Wed, 24 Jan 2024 15:54:15 -0800 Subject: [PATCH 2/8] simplify test to account for click < 7 --- tests/assets/compat_arg_complete_click7_8.py | 5 ----- tests/test_compat/test_arg_completion.py | 11 +++++------ 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/tests/assets/compat_arg_complete_click7_8.py b/tests/assets/compat_arg_complete_click7_8.py index 3ccbf4f3b2..48e7a75fff 100644 --- a/tests/assets/compat_arg_complete_click7_8.py +++ b/tests/assets/compat_arg_complete_click7_8.py @@ -1,6 +1,5 @@ import click import typer -from typer._compat_utils import _get_click_major app = typer.Typer() @@ -9,10 +8,6 @@ def shell_complete(ctx: click.Context, param: click.Parameter, incomplete: str): typer.echo(f"ctx: {ctx.info_name}", err=True) typer.echo(f"arg is: {param.name}", err=True) typer.echo(f"incomplete is: {incomplete}", err=True) - if _get_click_major() > 7: - from click.shell_completion import CompletionItem - - return [CompletionItem("Emma", help="Emma is awesome.")] return ["Emma"] diff --git a/tests/test_compat/test_arg_completion.py b/tests/test_compat/test_arg_completion.py index 9892cf2cbd..ff7d7747fc 100644 --- a/tests/test_compat/test_arg_completion.py +++ b/tests/test_compat/test_arg_completion.py @@ -20,10 +20,9 @@ def test_arg_completion(): "_TYPER_COMPLETE_TESTING": "True", }, ) - assert "Emma" in result.stdout + # TODO: when deprecating Click 7, remove second option + assert "Emma" in result.stdout or "_files" in result.stdout if _get_click_major() > 7: - assert "Emma is awesome." in result.stdout - - assert "ctx: compat_arg_complete_click7_8" in result.stderr - assert "arg is: name" in result.stderr - assert "incomplete is: E" in result.stderr + assert "ctx: compat_arg_complete_click7_8" in result.stderr + assert "arg is: name" in result.stderr + assert "incomplete is: E" in result.stderr From eaa69d1c0ed98b7e4642af87a7c2221383e3eff8 Mon Sep 17 00:00:00 2001 From: Brian Kohan Date: Wed, 24 Jan 2024 16:10:42 -0800 Subject: [PATCH 3/8] remove unnecessary test line for coverage --- tests/assets/compat_arg_complete_click7_8.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/assets/compat_arg_complete_click7_8.py b/tests/assets/compat_arg_complete_click7_8.py index 48e7a75fff..f91e2b7cfb 100644 --- a/tests/assets/compat_arg_complete_click7_8.py +++ b/tests/assets/compat_arg_complete_click7_8.py @@ -16,7 +16,6 @@ def main(name: str = typer.Argument(shell_complete=shell_complete)): """ Say hello. """ - print(f"Hello {name}") if __name__ == "__main__": From caba011929bf873ebccd6c45cdad30bc0c4a39c4 Mon Sep 17 00:00:00 2001 From: Brian Kohan Date: Wed, 3 Apr 2024 20:21:42 -0700 Subject: [PATCH 4/8] remove click 7 code from arg completion test --- tests/test_compat/test_arg_completion.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/test_compat/test_arg_completion.py b/tests/test_compat/test_arg_completion.py index ff7d7747fc..ff1c462ded 100644 --- a/tests/test_compat/test_arg_completion.py +++ b/tests/test_compat/test_arg_completion.py @@ -2,8 +2,6 @@ import subprocess import sys -from typer._compat_utils import _get_click_major - from tests.assets import compat_arg_complete_click7_8 as mod @@ -22,7 +20,6 @@ def test_arg_completion(): ) # TODO: when deprecating Click 7, remove second option assert "Emma" in result.stdout or "_files" in result.stdout - if _get_click_major() > 7: - assert "ctx: compat_arg_complete_click7_8" in result.stderr - assert "arg is: name" in result.stderr - assert "incomplete is: E" in result.stderr + assert "ctx: compat_arg_complete_click7_8" in result.stderr + assert "arg is: name" in result.stderr + assert "incomplete is: E" in result.stderr From ee3744a79aabf290841d727a46f4ba659ff185c2 Mon Sep 17 00:00:00 2001 From: Brian Kohan Date: Wed, 3 Apr 2024 20:33:30 -0700 Subject: [PATCH 5/8] fix arg completion test ruff linting issue --- tests/test_compat/test_arg_completion.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_compat/test_arg_completion.py b/tests/test_compat/test_arg_completion.py index ff1c462ded..49383f880d 100644 --- a/tests/test_compat/test_arg_completion.py +++ b/tests/test_compat/test_arg_completion.py @@ -8,8 +8,7 @@ def test_arg_completion(): result = subprocess.run( [sys.executable, "-m", "coverage", "run", mod.__file__, "E"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + capture_output=True, encoding="utf-8", env={ **os.environ, From 72ebc6730dd8808f8a8a514a9b9c0392aae8edd3 Mon Sep 17 00:00:00 2001 From: svlandeg Date: Fri, 19 Apr 2024 10:47:18 +0200 Subject: [PATCH 6/8] cleanup --- ...t_arg_complete_click7_8.py => completion_argument.py} | 0 tests/test_compat/test_arg_completion.py | 9 ++++----- 2 files changed, 4 insertions(+), 5 deletions(-) rename tests/assets/{compat_arg_complete_click7_8.py => completion_argument.py} (100%) diff --git a/tests/assets/compat_arg_complete_click7_8.py b/tests/assets/completion_argument.py similarity index 100% rename from tests/assets/compat_arg_complete_click7_8.py rename to tests/assets/completion_argument.py diff --git a/tests/test_compat/test_arg_completion.py b/tests/test_compat/test_arg_completion.py index 49383f880d..75e1b4567a 100644 --- a/tests/test_compat/test_arg_completion.py +++ b/tests/test_compat/test_arg_completion.py @@ -2,7 +2,7 @@ import subprocess import sys -from tests.assets import compat_arg_complete_click7_8 as mod +from tests.assets import completion_argument as mod def test_arg_completion(): @@ -12,13 +12,12 @@ def test_arg_completion(): encoding="utf-8", env={ **os.environ, - "_COMPAT_ARG_COMPLETE_CLICK7_8.PY_COMPLETE": "complete_zsh", - "_TYPER_COMPLETE_ARGS": "compat_arg_complete_click7_8.py E", + "_COMPLETION_ARGUMENT.PY_COMPLETE": "complete_zsh", + "_TYPER_COMPLETE_ARGS": "completion_argument.py E", "_TYPER_COMPLETE_TESTING": "True", }, ) - # TODO: when deprecating Click 7, remove second option assert "Emma" in result.stdout or "_files" in result.stdout - assert "ctx: compat_arg_complete_click7_8" in result.stderr + assert "ctx: completion_argument" in result.stderr assert "arg is: name" in result.stderr assert "incomplete is: E" in result.stderr From 876d19c7d09271141afd36c842106b4906464f8b Mon Sep 17 00:00:00 2001 From: svlandeg Date: Fri, 19 Apr 2024 11:11:07 +0200 Subject: [PATCH 7/8] move test to same file as other completion tests --- tests/test_others.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/test_others.py b/tests/test_others.py index 7986e1d7f0..da852197b4 100644 --- a/tests/test_others.py +++ b/tests/test_others.py @@ -141,6 +141,25 @@ def main(name: str = typer.Option(..., callback=name_callback)): assert "value is: Camila" in result.stdout +def test_completion_argument(): + file_path = Path(__file__).parent / "assets/completion_argument.py" + result = subprocess.run( + [sys.executable, "-m", "coverage", "run", str(file_path), "E"], + capture_output=True, + encoding="utf-8", + env={ + **os.environ, + "_COMPLETION_ARGUMENT.PY_COMPLETE": "complete_zsh", + "_TYPER_COMPLETE_ARGS": "completion_argument.py E", + "_TYPER_COMPLETE_TESTING": "True", + }, + ) + assert "Emma" in result.stdout or "_files" in result.stdout + assert "ctx: completion_argument" in result.stderr + assert "arg is: name" in result.stderr + assert "incomplete is: E" in result.stderr + + def test_completion_untyped_parameters(): file_path = Path(__file__).parent / "assets/completion_no_types.py" result = subprocess.run( From 2b3c707b3531e356e94f1c1ac41352f88e873ff3 Mon Sep 17 00:00:00 2001 From: svlandeg Date: Fri, 19 Apr 2024 11:12:29 +0200 Subject: [PATCH 8/8] remove duplicate --- tests/test_compat/test_arg_completion.py | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 tests/test_compat/test_arg_completion.py diff --git a/tests/test_compat/test_arg_completion.py b/tests/test_compat/test_arg_completion.py deleted file mode 100644 index 75e1b4567a..0000000000 --- a/tests/test_compat/test_arg_completion.py +++ /dev/null @@ -1,23 +0,0 @@ -import os -import subprocess -import sys - -from tests.assets import completion_argument as mod - - -def test_arg_completion(): - result = subprocess.run( - [sys.executable, "-m", "coverage", "run", mod.__file__, "E"], - capture_output=True, - encoding="utf-8", - env={ - **os.environ, - "_COMPLETION_ARGUMENT.PY_COMPLETE": "complete_zsh", - "_TYPER_COMPLETE_ARGS": "completion_argument.py E", - "_TYPER_COMPLETE_TESTING": "True", - }, - ) - assert "Emma" in result.stdout or "_files" in result.stdout - assert "ctx: completion_argument" in result.stderr - assert "arg is: name" in result.stderr - assert "incomplete is: E" in result.stderr