55

I'd like to start by pointing out that this question may seem like a duplicate, but it isn't. All the questions I saw here were regarding pip for Python 3 and I'm talking about Python 3.6. The steps used back then don't work for Python 3.6.

  1. I got a clear Ubuntu 16.10 image from the official docker store.
  2. Run apt-get update
  3. Run apt-get install python3.6
  4. Run apt-get install python3-pip
  5. Run pip3 install requests bs4
  6. Run python3.6 script.py

Got ModuleNotFoundError below:

 Traceback (most recent call last):
    File "script.py", line 6, in <module>
     import requests
 ModuleNotFoundError: No module named 'requests'

Python's and pip's I have in the machine:

python3
python3.5
python3.5m
python3.6
python3m
python3-config
python3.5-config
python3.5m-config
python3.6m
python3m-config  

pip
pip3
pip3.5
wjandrea
  • 28,235
  • 9
  • 60
  • 81
JChris
  • 1,638
  • 5
  • 19
  • 37

5 Answers5

105

Let's suppose that you have a system running Ubuntu 16.04, 16.10, or 17.04, and you want Python 3.6 to be the default Python.

If you're using Ubuntu 16.04 LTS, you'll need to use a PPA:

sudo add-apt-repository ppa:jonathonf/python-3.6  # (only for 16.04 LTS)

Then, run the following (this works out-of-the-box on 16.10 and 17.04):

sudo apt update
sudo apt install python3.6
sudo apt install python3.6-dev
sudo apt install python3.6-venv
wget https://bootstrap.pypa.io/get-pip.py
sudo python3.6 get-pip.py
sudo ln -s /usr/bin/python3.6 /usr/local/bin/python3
sudo ln -s /usr/local/bin/pip /usr/local/bin/pip3

# Do this only if you want python3 to be the default Python
# instead of python2 (may be dangerous, esp. before 2020):
# sudo ln -s /usr/bin/python3.6 /usr/local/bin/python

When you have completed all of the above, each of the following shell commands should indicate Python 3.6.1 (or a more recent version of Python 3.6):

python --version   # (this will reflect your choice, see above)
python3 --version
$(head -1 `which pip` | tail -c +3) --version
$(head -1 `which pip3` | tail -c +3) --version
Miles Erickson
  • 2,574
  • 2
  • 17
  • 18
  • 3
    I believe it should be `sudo ln -s /usr/local/bin/pip3.6 /usr/local/bin/pip3`, as `pip3` defaults to the default pip3.x installed on the system. – JChris May 30 '17 at 09:27
  • In the example that I've provided, pip is installed via `sudo python3.6 get-pip.py` as `/usr/local/bin/pip` and is aliased to `/usr/local/bin/pip3`. There is no `/usr/local/bin/pip3.6` on the system. – Miles Erickson May 31 '17 at 17:35
  • 1
    Oh ok. I get it now. Created one Ubuntu Server 17.04 for testing and out-of-the-box it comes with Python 3.5.x only, nothing regarding Python 2.x and no `pip` installed. After `apt install python3.6 / -dev / -env` I get Python 3.6.x, but `python3` symlink continues to point to the default Python 3.5.x as expected. Then a simple `sudo ln -s /usr/bin/python3.6 /usr/local/bin/python` takes care of it. Then wget get-pip.py and run with `python` (Python 3.6.x after the symlink) and it's done. Marked yours as the correct anwser now, because it feels cleaner than the older. – JChris May 31 '17 at 23:19
  • 5
    fwiw, [pep 0394](https://www.python.org/dev/peps/pep-0394/) doesn't suggest the following: `sudo ln -s /usr/bin/python3.6 /usr/local/bin/python` – anthony sottile Jun 10 '17 at 23:43
  • 5
    [PEP 394](https://www.python.org/dev/peps/pep-0394/#recommendation) says "The more general `python` command should be installed whenever any version of Python 2 is installed and should invoke the same version of Python as the `python2` command". It could be dangerous to link `python3.6` to `python` on Ubuntu 16. – Asclepius Jun 20 '17 at 20:36
  • Edited the original answer per the two comments above. – Miles Erickson Dec 13 '17 at 16:51
  • I needed to run sudo apt-get install python3-distutils too. – penitent_tangent Mar 04 '19 at 13:20
  • I did all of the above, and i am getting python 3.6 when i run `python3 --version` but i still get python3.5 when i run `$(head -1 `which pip3` | tail -c +3) --version` – Harshit Singhal Jun 05 '20 at 07:27
36

In at least in ubuntu 16.10, the default python3 is python3.5. As such, all of the python3-X packages will be installed for python3.5 and not for python3.6.

You can verify this by checking the shebang of pip3:

$ head -n1 $(which pip3)
#!/usr/bin/python3

Fortunately, the pip installed by the python3-pip package is installed into the "shared" /usr/lib/python3/dist-packages such that python3.6 can also take advantage of it.

You can install packages for python3.6 by doing:

python3.6 -m pip install ...

For example:

$ python3.6 -m pip install requests
$ python3.6 -c 'import requests; print(requests.__file__)'
/usr/local/lib/python3.6/dist-packages/requests/__init__.py
anthony sottile
  • 61,815
  • 15
  • 148
  • 207
  • @Anthony Sottile, Any suggestion on how to make python 3.6 default? – Soumendra Mar 19 '17 at 08:39
  • One way to make python3.6 the default for pip is to make an executable which is named "pip" but essentially does `exec python3.6 -m pip` -- throw that in `~/bin` or `/usr/local/bin`. Replacing the operating system default `python3` executable is not suggested and will lead to OS instability. – anthony sottile Mar 19 '17 at 16:12
  • 2
    "No module named pip" When I try this. – Turtles Are Cute Mar 21 '17 at 06:27
  • 1
    @TurtlesAreCute do you have `python-pip` installed (via `apt`)? – anthony sottile Mar 21 '17 at 14:42
  • Anthony - yes. _ – Turtles Are Cute Mar 24 '17 at 08:37
  • 1
    @TurtlesAreCute from testing, that probably means you ran (at some point) `sudo pip install pip --upgrade`, this will move pip to the py35 dist-packages. You can probably get the old one back with `sudo apt install --reinstall python-pip` or use `get-pip.py` with python3.6 as suggested in the comments above – anthony sottile Mar 24 '17 at 16:09
  • That sounds like something I may have done. Thanks; I'll try that once I get Ubuntu reinstalled; I think I somehow broke the login screen beyond repair while troubleshooting this :/ – Turtles Are Cute Mar 24 '17 at 20:33
12

This answer assumes that you have python3.6 installed. For python3.7, replace 3.6 with 3.7. For python3.8, replace 3.6 with 3.8, but it may also first require the python3.8-distutils package.

Installation with sudo

With regard to installing pip, using curl (instead of wget) avoids writing the file to disk.

curl https://bootstrap.pypa.io/get-pip.py | sudo -H python3.6

The -H flag is evidently necessary with sudo in order to prevent errors such as the following when installing pip for an updated python interpreter:

The directory '/home/someuser/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.

The directory '/home/someuser/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.

Installation without sudo

curl https://bootstrap.pypa.io/get-pip.py | python3.6 - --user

This may sometimes give a warning such as:

WARNING: The script wheel is installed in '/home/ubuntu/.local/bin' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

Verification

After this, pip, pip3, and pip3.6 can all be expected to point to the same target:

$ (pip -V && pip3 -V && pip3.6 -V) | uniq
pip 18.0 from /usr/local/lib/python3.6/dist-packages (python 3.6)

Of course you can alternatively use python3.6 -m pip as well.

$ python3.6 -m pip -V
pip 18.0 from /usr/local/lib/python3.6/dist-packages (python 3.6)
Asclepius
  • 57,944
  • 17
  • 167
  • 143
3

This website contains a much cleaner solution, it leaves pip intact as-well and one can easily switch between 3.5 and 3.6 and then whenever 3.7 is released.

http://ubuntuhandbook.org/index.php/2017/07/install-python-3-6-1-in-ubuntu-16-04-lts/

A short summary:

sudo apt-get install python python-pip python3 python3-pip
sudo add-apt-repository ppa:jonathonf/python-3.6
sudo apt-get update
sudo apt-get install python3.6
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.5 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 2

Then

$ pip -V
pip 8.1.1 from /usr/lib/python2.7/dist-packages (python 2.7)
$ pip3 -V
pip 8.1.1 from /usr/local/lib/python3.5/dist-packages (python 3.5)

Then to select python 3.6 run

sudo update-alternatives --config python3

and select '2'. Then

$ pip3 -V
pip 8.1.1 from /usr/local/lib/python3.6/dist-packages (python 3.6)

To update pip select the desired version and

pip3 install --upgrade pip

$ pip3 -V
pip 9.0.1 from /usr/local/lib/python3.6/dist-packages (python 3.6)

Tested on Ubuntu 16.04.

genetica
  • 39
  • 1
  • Please note. Currently the python package "apt_pkg" is not yet available from pip in python 3.6, meaning that some commands such as "apt-add-repository" might not work. – genetica Dec 07 '17 at 13:35
  • 1
    On Ubuntu, Python 3 is tightly integrated with the OS, so different versions are not alternatives, and you shouldn't change the symlink `/usr/bin/python3`. So this could easily cause problems. E.g. [your terminal might not open](https://askubuntu.com/q/880188/301745). – wjandrea Aug 05 '18 at 01:33
3

Some of the solutions above using the script get-pip.py worked until a couple of weeks ago.

The latest version of this script now requires python3.7 throwing the following error

ERROR: This script does not work on Python 3.6 
The minimun supported Python version is 3.7. 
Please use https://bootstrap.pypa.io/pip/3.6/get-pip.py instead.

So making the corresponding change works now.

wget https://bootstrap.pypa.io/pip/3.6/get-pip.py
sudo python3.6 get-pip.py
Miguel Trejo
  • 5,913
  • 5
  • 24
  • 49