Repository: pypa/pip

Issue:
pip3 completion
- Pip version: 8.1.2-2
- Python version: 3.5.2+
- Operating System: Debian Stretch

`pip3 completion --bash >> ~/.bashrc`  should write:

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

```

pip3 instead of pip. Otherwise there completion does not work.

Fix bad entry point for completion
According to #3997, completion template now use entry point used to run current command.

Edit: Fixes #3997


Discussion:

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the ``master`` branch into this pull request or rebase this pull request against ``master`` then it will eligible for code review and hopefully merging!
Hi @toxinu!

Could you rebase this PR on master? :)
@pradyunsg Done! 😄 
Thanks! ^.^

This should probably be mentioned in the news file. Could you add a news fragment to this PR?

Edit: Details on that are available [here](https://pip.pypa.io/en/latest/development/#adding-a-news-entry).
Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the ``master`` branch into this pull request or rebase this pull request against ``master`` then it will eligible for code review and hopefully merging!

Resolving patch:
diff --git a/src/pip/_internal/commands/completion.py b/src/pip/_internal/commands/completion.py
--- a/src/pip/_internal/commands/completion.py
+++ b/src/pip/_internal/commands/completion.py
@@ -4,6 +4,7 @@
 import textwrap
 
 from pip._internal.basecommand import Command
+from pip._internal.utils.misc import get_prog
 
 BASE_COMPLETION = """
 # pip %(shell)s completion start%(script)s# pip %(shell)s completion end
@@ -17,7 +18,7 @@
                            COMP_CWORD=$COMP_CWORD \\
                            PIP_AUTO_COMPLETE=1 $1 ) )
         }
-        complete -o default -F _pip_completion pip
+        complete -o default -F _pip_completion %(prog)s
     """,
     'zsh': """
         function _pip_completion {
@@ -28,17 +29,19 @@
                      COMP_CWORD=$(( cword-1 )) \\
                      PIP_AUTO_COMPLETE=1 $words[1] ) )
         }
-        compctl -K _pip_completion pip
+        compctl -K _pip_completion %(prog)s
     """,
     'fish': """
         function __fish_complete_pip
             set -lx COMP_WORDS (commandline -o) ""
-            set -lx COMP_CWORD {cword}
+            set -lx COMP_CWORD ( \\
+                math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\
+            )
             set -lx PIP_AUTO_COMPLETE 1
             string split \\  -- (eval $COMP_WORDS[1])
         end
-        complete -fa "(__fish_complete_pip)" -c pip
-    """.format(cword="(math (contains -i -- (commandline -t) $COMP_WORDS)-1)")
+        complete -fa "(__fish_complete_pip)" -c %(prog)s
+    """,
 }
 
 
@@ -80,7 +83,9 @@ def run(self, options, args):
         shell_options = ['--' + shell for shell in sorted(shells)]
         if options.shell in shells:
             script = textwrap.dedent(
-                COMPLETION_SCRIPTS.get(options.shell, '')
+                COMPLETION_SCRIPTS.get(options.shell, '') % {
+                    'prog': get_prog(),
+                }
             )
             print(BASE_COMPLETION % {'script': script, 'shell': options.shell})
         else:
diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py
--- a/src/pip/_internal/utils/misc.py
+++ b/src/pip/_internal/utils/misc.py
@@ -91,8 +91,11 @@ def ensure_dir(path):
 
 def get_prog():
     try:
-        if os.path.basename(sys.argv[0]) in ('__main__.py', '-c'):
+        prog = os.path.basename(sys.argv[0])
+        if prog in ('__main__.py', '-c'):
             return "%s -m pip" % sys.executable
+        else:
+            return prog
     except (AttributeError, TypeError, IndexError):
         pass
     return 'pip'


Test patch:
diff --git a/tests/functional/test_completion.py b/tests/functional/test_completion.py
--- a/tests/functional/test_completion.py
+++ b/tests/functional/test_completion.py
@@ -1,4 +1,7 @@
 import os
+import sys
+
+import pytest
 
 
 def test_completion_for_bash(script):
@@ -44,7 +47,9 @@ def test_completion_for_fish(script):
     fish_completion = """\
 function __fish_complete_pip
     set -lx COMP_WORDS (commandline -o) ""
-    set -lx COMP_CWORD (math (contains -i -- (commandline -t) $COMP_WORDS)-1)
+    set -lx COMP_CWORD ( \\
+        math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\
+    )
     set -lx PIP_AUTO_COMPLETE 1
     string split \\  -- (eval $COMP_WORDS[1])
 end
@@ -114,3 +119,13 @@ def test_completion_option_for_command(script):
     res, env = setup_completion(script, 'pip search --', '2')
     assert '--help' in res.stdout,\
            "autocomplete function could not complete ``--``"
+
+
+@pytest.mark.parametrize('flag', ['--bash', '--zsh', '--fish'])
+def test_completion_uses_same_executable_name(script, flag):
+    expect_stderr = sys.version_info[:2] == (3, 3)
+    executable_name = 'pip{}'.format(sys.version_info[0])
+    result = script.run(
+        executable_name, 'completion', flag, expect_stderr=expect_stderr
+    )
+    assert executable_name in result.stdout
diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py
--- a/tests/unit/test_utils.py
+++ b/tests/unit/test_utils.py
@@ -23,8 +23,8 @@
 from pip._internal.utils.glibc import check_glibc_version
 from pip._internal.utils.hashes import Hashes, MissingHashes
 from pip._internal.utils.misc import (
-    egg_link_path, ensure_dir, get_installed_distributions, normalize_path,
-    rmtree, untar_file, unzip_file
+    egg_link_path, ensure_dir, get_installed_distributions, get_prog,
+    normalize_path, rmtree, untar_file, unzip_file
 )
 from pip._internal.utils.packaging import check_dist_requires_python
 from pip._internal.utils.temp_dir import TempDirectory
@@ -592,3 +592,23 @@ def test_check_requires(self, metadata, should_raise):
                 check_dist_requires_python(fake_dist)
         else:
             check_dist_requires_python(fake_dist)
+
+
+class TestGetProg(object):
+
+    @pytest.mark.parametrize(
+        ("argv", "executable", "expected"),
+        [
+            ('/usr/bin/pip', '', 'pip'),
+            ('-c', '/usr/bin/python', '/usr/bin/python -m pip'),
+            ('__main__.py', '/usr/bin/python', '/usr/bin/python -m pip'),
+            ('/usr/bin/pip3', '', 'pip3'),
+        ]
+    )
+    def test_get_prog(self, monkeypatch, argv, executable, expected):
+        monkeypatch.setattr('pip._internal.utils.misc.sys.argv', [argv])
+        monkeypatch.setattr(
+            'pip._internal.utils.misc.sys.executable',
+            executable
+        )
+        assert get_prog() == expected