diff --git a/news/12401.bugfix.rst b/news/12401.bugfix.rst new file mode 100644 index 00000000000..371f80011b3 --- /dev/null +++ b/news/12401.bugfix.rst @@ -0,0 +1 @@ +Fix exception with completions when COMP_CWORD is not set diff --git a/src/pip/_internal/cli/autocompletion.py b/src/pip/_internal/cli/autocompletion.py index e5950b90696..f3f70ac8553 100644 --- a/src/pip/_internal/cli/autocompletion.py +++ b/src/pip/_internal/cli/autocompletion.py @@ -17,6 +17,10 @@ def autocomplete() -> None: # Don't complete if user hasn't sourced bash_completion file. if "PIP_AUTO_COMPLETE" not in os.environ: return + # Don't complete if autocompletion environment variables + # are not present + if not os.environ.get("COMP_WORDS") or not os.environ.get("COMP_CWORD"): + return cwords = os.environ["COMP_WORDS"].split()[1:] cword = int(os.environ["COMP_CWORD"]) try: diff --git a/tests/functional/test_completion.py b/tests/functional/test_completion.py index cc8583b1a38..94a25eea219 100644 --- a/tests/functional/test_completion.py +++ b/tests/functional/test_completion.py @@ -120,7 +120,12 @@ def autocomplete_script( class DoAutocomplete(Protocol): def __call__( - self, words: str, cword: str, cwd: Union[Path, str, None] = None + self, + words: str, + cword: str, + cwd: Union[Path, str, None] = None, + include_env: bool = True, + expect_error: bool = True, ) -> Tuple[TestPipResult, PipTestEnvironment]: ... @@ -133,16 +138,21 @@ def autocomplete( autocomplete_script.environ["PIP_AUTO_COMPLETE"] = "1" def do_autocomplete( - words: str, cword: str, cwd: Union[Path, str, None] = None + words: str, + cword: str, + cwd: Union[Path, str, None] = None, + include_env: bool = True, + expect_error: bool = True, ) -> Tuple[TestPipResult, PipTestEnvironment]: - autocomplete_script.environ["COMP_WORDS"] = words - autocomplete_script.environ["COMP_CWORD"] = cword + if include_env: + autocomplete_script.environ["COMP_WORDS"] = words + autocomplete_script.environ["COMP_CWORD"] = cword result = autocomplete_script.run( "python", "-c", "from pip._internal.cli.autocompletion import autocomplete;" "autocomplete()", - expect_error=True, + expect_error=expect_error, cwd=cwd, ) @@ -160,6 +170,17 @@ def test_completion_for_unknown_shell(autocomplete_script: PipTestEnvironment) - assert error_msg in result.stderr, "tests for an unknown shell failed" +def test_completion_without_env_vars(autocomplete: DoAutocomplete) -> None: + """ + Test getting completion after options in command + given absolute path + """ + res, env = autocomplete( + words="pip install ", cword="", include_env=False, expect_error=False + ) + assert res.stdout == "", "autocomplete function did not complete" + + def test_completion_alone(autocomplete_script: PipTestEnvironment) -> None: """ Test getting completion for none shell, just pip completion