Skip to content
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

Handle missing COMP_WORDS and COMP_CWORD in completion script #12401

Merged
merged 3 commits into from
Apr 2, 2024
Merged
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
1 change: 1 addition & 0 deletions news/12401.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix exception with completions when COMP_CWORD is not set
4 changes: 4 additions & 0 deletions src/pip/_internal/cli/autocompletion.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
31 changes: 26 additions & 5 deletions tests/functional/test_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]:
...

Expand All @@ -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,
)

Expand All @@ -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 <path> 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
Expand Down
Loading