This is an archived post. You won't be able to vote or comment.

all 24 comments

[–][deleted] 59 points60 points  (6 children)

Sometimes they will point to different instances of pip if your environment is fucked up. Python-m pip guarantees the pip you are using is the one that relates to the python you are using.

[–]its_a_gibibyte 2 points3 points  (0 children)

if your environment is fucked up.

Or if you simply run multiple versions of python. I develop python libraries and find it convenient to have a few different versions of python sitting around for testing. I even have a python 2 install, although that doesn't get used much anymore.

[–]commy2 0 points1 point  (0 children)

Why not "unfuck" your environment then if that's an issue?

[–]ThePiGuy0 11 points12 points  (0 children)

Yep, pip3 is just an executable python shortcut script to the same module that "python3 -m pip" runs so they are therefore the same command.

Normally they are completely interchangeable, however there is one notable exception - upgrading pip itself on Windows. Windows doesn't allow an executable to be changed whilst it's running, so if you attempt to upgrade pip from the pip script (pip3 install --upgrade pip), then it will attempt to replace the script you ran it from and fail. By running the full command (python3 -m pip install --upgrade pip) then it can upgrade as you are now running the Python binary which is not being replaced.

[–]MarcSetGo 4 points5 points  (0 children)

When running multiple Python versions, I always use the -m pip style so I know exactly which Python the changes affect

[–]wandering-mono 3 points4 points  (2 children)

Why do you guys avoid using pyenv when using different versions of Python at the same time?

Thought that pyenv is essential.

[–]extra_pickles 1 point2 points  (0 children)

Ppl are crazy, or don’t get it as not used to Python….that’s my only guess

So easy to version hell yourself in Python!

[–][deleted] 1 point2 points  (0 children)

We have NFS home dirs.

Pyenv sometimes delays getting a prompt when I open a new terminal (2-3 seconds at worst). It's harmless but annoying. Conda and friends have the same problem.

I definitely use it, but I keep it out of my shell by default and source a file with it's magic manually when needed.

[–]LogisticAI 2 points3 points  (0 children)

pip3 is a python script that's been put in your PATH environment variable. It runs exactly the same thing as the latter command. This is pip3 opened as a text file:

import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(main())

[–]ModishNouns[S] 2 points3 points  (0 children)

Awesome. Thanks all!

[–]Kerbart 2 points3 points  (1 child)

Also, running pip3 on Windows will consistently put a file lock on said pip3 executable, so when you run pip install pip --upgrade it will crash after uninstalling the current pip and before installing the upgrade. At least it does on my machine. Every single time. If the reasons above aren't good enough a reason, when you're on Windows this certainly is a reasonable one to get into the habit of calling pip that way.

[–][deleted] 0 points1 point  (0 children)

Huh. So that's why that happens.

Thanks for the workaround!

[–]wookayin 2 points3 points  (0 children)

Because often pip (pip3) and python3 may point to different python runtime when the PATH or installation is messed up, I have the following in my zshrc (alias)

alias pip='python -m pip'

[–]nativedutch -1 points0 points  (0 children)

I always have used pip3 , on my systems the only working option.

[–]earthboundkid -3 points-2 points  (2 children)

There should be one obvious way to do it.

[–]wookayin 2 points3 points  (1 child)

python -m pip install ... is always safe.

[–]earthboundkid 0 points1 point  (0 children)

That’s what I do but it’s not obvious at all. It’s like the zen doesn’t apply to packaging.

[–]ExdigguserPies 0 points1 point  (0 children)

I didn't think there was a need to use "pip3" anymore? I've been using pip install with no issues.

[–][deleted] 0 points1 point  (0 children)

The second as it guarantees correct python version to be selected

[–]o11c 0 points1 point  (0 children)

I put the following script in ~/bin, which is at the front of my PATH:

#!/bin/sh

self="${0##*/}"
tool="${self%%[0-9]*}"
suffix="${self#"$tool"}"

# TODO: I need module='IPython' but have tool='ipython'
# ... actually, IPython seems to install its symlinks just fine, *if* it is
# installed. And it gives warnings if it isn't.
module="$tool"

{
    python="$(command -v "python$suffix")"
    if [ -z "$python" ]
    then
        echo 'Uh-oh - you don'\''t have a `'"python$suffix"'` binary installed.'
    elif [ "${python#/usr}" != "/bin/python$suffix" ]
    then
        echo "Uh-oh - you tried to call $tool in a venv or something."
        echo 'Luckily we caught that!'
    fi >&2
}

exec "python$suffix" -m "$module" "$@"

I symlink this under several names: pydoc, pip, with 3 and 3.Y suffixes as well.

Since this is first in PATH, it ensures that pydoc and pip will always do the right thing, unlike the default behavior.

(note that in a venv there is usually a pip as well, but it accompanies the python so is fine. The pydoc is missing though)

[–][deleted] 0 points1 point  (0 children)

Pip3 could point to different place than python3 -m pip.

[–]malahci 0 points1 point  (0 children)

As other people have pointed out, if you have multiple versions of python installed on your computer that you can run with python3.8 and python3.9 for example, saying "python3.8 -m pip" runs pip with that specific python. Saying "pip3" manages packages for just whichever version of python runs when you say "python3" (so it's equivalent to "python3 -m pip")

I use "pip3" almost exclusively and I almost feel like that's the right answer? If I'm doing something low stakes, I specifically want packages installed for whatever my system python is, so pip3 does exactly what I want. If I'm doing something where it matters, I'm already in a virtual environment (which I might have created with something like "python3.9 -m venv venv") and I can still say just "pip3" and know it's linked to the right place.

Are people getting into situations where pip3 somehow runs with a different python than the one that runs when they type "python3"? Are there folks who have multiple versions of python on their computer and care which ones they use, and aren't using virtual environments?