What's the difference between "pip install" and "python -m pip install"?
Asked Answered
L

4

150

I have a local version of Python 3.4.1 and I can run python -m pip install, but I'm unable to find the pip binary to run pip install. What's the difference between these two?

Langtry answered 9/9, 2014 at 16:24 Comment(0)
S
111

They do exactly the same thing, assuming pip is using the same version of Python as the python executable. The docs for distributing Python modules were just updated to suggest using python -m pip instead of the pip executable, because it allows you to be explicit about which version of Python to use. In systems with more than one version of Python installed, it's not always clear which one pip is linked to.


Here's some more concrete "proof" that both commands should do the same thing, beyond just trusting my word and the bug report I linked :)

If you take a look at the pip executable script, it's just doing this:

from pkg_resources import load_entry_point
<snip>
load_entry_point('pip==1.5.4', 'console_scripts', 'pip')()

It's calling load_entry_point, which returns a function, and then executing that function. The entry point it's using is called 'console_scripts'. If you look at the entry_points.txt file for pip (/usr/lib/python2.7/dist-packages/pip-1.5.4.egg-info/entry_points.txt on my Ubuntu machine), you'll see this:

[console_scripts]
pip = pip:main
pip2.7 = pip:main
pip2 = pip:main

So the entry point returned is the main function in the pip module.

When you run python -m pip, you're executing the __main__.py script inside the pip package. That looks like this:

import sys
from .runner import run

if __name__ == '__main__':
    exit = run()
    if exit:
        sys.exit(exit)

And the runner.run function looks like this:

def run():
    base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    ## FIXME: this is kind of crude; if we could create a fake pip
    ## module, then exec into it and update pip.__path__ properly, we
    ## wouldn't have to update sys.path:
    sys.path.insert(0, base)
    import pip
    return pip.main()

As you can see, it's just calling the pip.main function, too. So both commands end up calling the same main function in pip/__init__.py.

Samoyed answered 9/9, 2014 at 16:47 Comment(14)
Thanks for the answer, where can I corroborate that info? And where are the packages installed using the local Python?Langtry
And this "concept" does not only apply to pip, but also other Python "command line tools" can be called like this. E.g., python -m markdown. To quote from the python help menu -m mod : run library module as a scriptArchaimbaud
@ilciavo: small correction: python -m pip runs pip/__main__.py module, not pip/__init__.py. It is a general rule: python -m module runs module.__main__ module if module is a package (has __path__ attribute) otherwise it runs the module itself -- both with __name__=="__main__".Kobold
@J.F.Sebastian Yes, you're right. I've corrected that in my answer.Samoyed
For some reason if I try doing python2.6 -m pip install I get /usr/bin/python: pip is a package and cannot be directly executedLangtry
@Langtry Can you import pip at all when you run python2.6?Samoyed
Yes I can import pip but I can't python -m pip install on python 2.6Langtry
@Langtry Looks like that is a limitation of Python 2.6. It doesn't support using packages with the -m flag. You'll have to use python -m pip.__main__ directly.Samoyed
@Kobold just for clarification, python -m module runs both module/__init__.py and module/__main__.py if the module is a package.Cheque
@starriet: it imports the module (__name__ == "module") but it doesn't run it. For comparison, -m package does run package/__main__.py -> __name__ == "__main__"). btw, -m module likely imports other modules too (add -v, to see them).Kobold
@Kobold I mentioned -m package, not import. -m package runs both __init__.py and __main__.py, doesn't it?Cheque
@starriet: -m package does not "run" __init__.py that you can see by inspecting __name__ (if you see __main__ then the code is "running" if you see (for the exact same module, exact same module) just its name then it is just an import.Kobold
They only do the same thing if they're set up that way. It's possible to have a messy setup where pip runs in a different interpreter than python refers to. That's why python -m is the recommended way. So you could edit the first paragraph to say "They should do exactly the same thing, but the docs ... because then you can tell which interpreter is going to be used ..."Superposition
@Superposition Thanks for that suggestion. I used different wording, but I updated my answer to make it clear that they only do the exact same thing if they're targeting the same version of Python.Samoyed
S
27

2021

This only happens if you create the venv with PyCharm. Please check if Scripts/pip-script.py located in your virtual environment

pip install and python -m pip install -- is not really the same. Or welcome back into the HELL of VERSIONING & DEPENDENCIES :-(

I was used to type pip(.exe) install <name> if I want install a package. But I run into trouble, if I try to install package Pillow. It breaks every time with an error message.

Today I retry python -m pip install copy&pasted from the manual and it works. Before I ignored it and type pip.... Because I thought it is the same.

I start to dive a little bit deeper into pip and I find this question/answer. After a while I found that pip.exe calls the script <virtual-environment/Scripts>pip-script.py.

I fighting with the installation of package Pillow.

#! .\venv\Scripts\python.exe
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip3'
__requires__ = 'pip==19.0.3'
import re
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(
        load_entry_point('pip==19.0.3', 'console_scripts', 'pip3')()
    )

I was a little bit surprised that pip.exe still use the old version 19.0.3 of the package and not the new installed version 21.0.1.

I changed the two version strings by hand to 21.0.1. And now pip.exe was able to install Pillow proper.

From now I understand why pip still complains that I use an old version of pip.

enter image description here

I think the old v19 pip has problem to detect the supported platform and therefore sources instead of binaries are installed.

Salters answered 26/2, 2021 at 0:1 Comment(2)
The highest voted answer backs up the answer concrete examples. To disagree with the poster would be more compelling if you built a more concrete case- your example of Pillow seems to be a tangent to answering the question at hand. Would using python -m pip have solved the Pillow issue? Thanks for contributing!Reef
@AllenM Thank you for your answer. I investigate again and I found out that pip-script.py is coming from PyCharm if I create a virtual environment with it. If I create the venv with command-line (python -m venv venv) this script missing in folder Scripts.Salters
K
10

Every installation of Python potentially comes with its own version of Pip. (Some installations may deliberately exclude Pip for security reasons: for example, when Python is included in a Linux distribution, it commonly omits Pip so that the user will not inadvertently install something harmful into a copy of Python that the operating system depends on.)

Conceptually, Pip consists of two pieces: the pip standard library module, contained in a pip.py file; and a pip "wrapper" executable. (On Windows this is implemented as an actual .exe file; on Mac and Linux, it should simply be a Python script that has execution privileges set and which does not have a .py filename extension.) The purpose of the wrapper is to run the "main" code in the corresponding standard library module.

Using pip at the command line will find and run whichever wrapper executable is first in the PATH environment variable, which will then run the corresponding Python code for the installation of Python associated with that wrapper. Therefore, it will install third-party libraries for whichever Python that is.

Using python -m pip at the command line will find and run whichever Python is first in the PATH environment variable, and instruct it to find the pip standard library module in its standard library (not directly; it will search sys.path just like with any module import) and run it "as a module". Therefore, it will install third-party libraries for the Python that was found in the PATH.

On Windows, using py -m pip at the command line will (unless the system is badly misconfigured) find and run the py executable, which is installed to a Windows directory that will always be on the PATH. This, in turn, will use its own logic to choose a Python on the system, run its pip, and from there it proceeds as before.

Depending on how the system is configured, these commands might not all choose the same Python installation.

Using python -m pip ensures that libraries are installed for the same Python that would run, using python myscript.py. This is very useful for those who are writing myscript.py, need that code to use the library that will be installed, and want it to run with whichever python that is.

As a special note for Windows, pip install --upgrade pip will not work. This is because upgrading Pip involves replacing the Pip wrapper executable on disk; by running the command this way, that wrapper executable is the program that is running, and Windows disallows programs from replacing themselves on disk. By using python -m pip install --upgrade pip, or py -m pip install --upgrade pip instead, the problem is avoided, because now the wrapper executable does not run - Python (and possibly also py) runs, using code from the pip.py (or a cached pip.pyc) file.

Kindred answered 4/5, 2023 at 0:2 Comment(2)
Thanks for the update and details about WindowsLangtry
One quibble: pip is not a standard library.Abvolt
I
0

python -m pip: runs the pip module as a python script

pip: runs the pip executable

Usually these are installed together and point to the same python script. So in most cases, you can use either form of the command and they will achieve the same result. However, using python -m pip ensures that libraries are installed for the same Python instance that would run e.g. python <script.py>. If in a virtual environment, this will be the python version the "activate" command set up. Some virtual environments may or may not setup a new path for pip. Therefore being explicit with python -m pip is usually preferred.

If you want to test to make sure they are found correctly on your path:

Windows:

where python
where pip

Linux:

which python
which pip

Note: venv will setup a path to pip as well for an activate environment.

Igniter answered 21/9, 2023 at 21:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.