Skip to content

pip bash completion when IFS doesn't have its default value #13555

@stephane-chazelas

Description

@stephane-chazelas

Description

$ pip completion --bash

# pip bash completion start
_pip_completion()
{
    COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
                   COMP_CWORD=$COMP_CWORD \
                   PIP_AUTO_COMPLETE=1 $1 2>/dev/null ) )
}
complete -o default -F _pip_completion pip
# pip bash completion end

That has the common mistake of using split+glob (here $(...) unquoted) and "${array[*]}" without setting IFS, so is dependant on the current value of $IFS at the time the completer is invoked. So that all falls apart if the user sets $IFS to a different value. Hopefully, none of the completion values that pip generates contain wildcard characters so the fact that globbing is not disabled can probably be ignored.

That unquoted $1 also invokes split+glob which doesn't make sense here.

The zsh completion with similar code is not affected as the zsh completion system sets IFS locally to $' \t\n\0' ignoring the value set by the user.

However that zsh completion is much much more rudimentary than the one included with zsh, so it may be worth advising users against using the one that comes with pip.

The fix for bash should be just a matter of:

diff --git a/src/pip/_internal/commands/completion.py b/src/pip/_internal/commands/completion.py
index 6d9597bde..05503ccb3 100644
--- a/src/pip/_internal/commands/completion.py
+++ b/src/pip/_internal/commands/completion.py
@@ -14,9 +14,10 @@ COMPLETION_SCRIPTS = {
     "bash": """
         _pip_completion()
         {{
+	    local IFS
             COMPREPLY=( $( COMP_WORDS="${{COMP_WORDS[*]}}" \\
                            COMP_CWORD=$COMP_CWORD \\
-                           PIP_AUTO_COMPLETE=1 $1 2>/dev/null ) )
+                           PIP_AUTO_COMPLETE=1 "$1" 2>/dev/null ) )
         }}
         complete -o default -F _pip_completion {prog}
     """,

I'll create a pull request shortly.

Expected behavior

No response

pip version

25.2-30-g324f3ce0d

Python version

Python 3.13.6

OS

Debian GNU/Linux amd64 forky

How to Reproduce

From bash --norc:

eval "$(pip completion --bash)"
IFS=:
pip <Tab>

Output

No response

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    S: needs triageIssues/PRs that need to be triagedtype: bugA confirmed bug or unintended behavior

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions