1. Home

Anil

< Blog />

Using pyenv to install & manage multiple python versions

in

Pyenv helps us to install, manage and switch between multiple python versions, most commonly done for testing your code across multiple python environments.

In this post, we’ll have a look at getting up and running with pyenv.

If you’re on MacOS, you may have some or all of the python versions listed below.

# /usr/bin (default Apple provided)
ls -al /usr/bin/python*
# python2.7 -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
# python2.6 -> ../../System/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6

# /usr/local/bin (Homebrew)
# All python versions installed via Homebrew
ls -al /usr/local/bin/python*
# /usr/local/bin/python2.7 -> ../Cellar/python/2.7.11/bin/python2.7
# /usr/local/bin/python3 -> ../Cellar/python3/3.5.1/bin/python3
# /usr/local/bin/python3.5 -> ../Cellar/python3/3.5.1/bin/python3.5

These will already be included in your path, in the case of /usr/bin, or you will have updated your PATH in your .bash_profile when installing Homebrew.

Note

You can dump your $PATH with echo $PATH | tr ':' '\n'.


Install & setup of pyenv

Pyenv downloads and installs the specific python versions we need into a ~/.pyenv/versions directory on your system. You can then use pyenv to switch to the specific python version you want to use (globally or locally).

Pyenv does this by adding a shim to your $PATH which directs all python and python related tools like pip and easy_install to /.pyenv/shims/python, from here pyenv manages the various versions for us.

Installing via Homebrew. (You can find instructions for other methods on the Github page.)

# Install pyenv
brew update
brew install pyenv

# View more information
brew info pyenv

# Add the following to your ~/.bash_profile
# We want to load pyenv every time we open a new shell
if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi

# Restart your shell - after updating your ~/.bash_profile

You should now have pyenv installed, by default it will be installed to ~/.pyenv.

Use the which command to find the current location of the python interpreter.

which python
# /Users/anillakhman/.pyenv/shims/python

You should see python being loaded from the ~/.pyenv/shims directory. pyenv currently points python to the user installed version, known as system (either your /usr/bin or /usr/local/bin).

Note

You can use pyenv which python to show the actual location of the python interpreter it’s using.

Currently with no other python versions installed, it should output the location of your existing installation (system).


Installing python versions

Let’s install a few python versions, these will all install into ~/.pyenv/versions.

# List all available versions
pyenv install -l

# Note this may take a while
# We'll install each latest minor release
pyenv install 2.6.9
pyenv install 2.7.12
pyenv install 3.1.5
pyenv install 3.2.6
pyenv install 3.3.6
pyenv install 3.4.5
pyenv install 3.5.2
#pyenv install 3.6-dev

You can view all the installed versions using:

# List current python (should still be `system`)
pyenv which python

# List all versions installed
pyenv versions

# Outputs:
* system (set by /Users/anillakhman/.pyenv/version)
2.6.9
2.7.12
3.1.5
3.2.6
3.3.6
3.4.5
3.5.2

By default pyenv will use our system default python. So when you type python, it will use the default system provided interpreter.



Switching versions globally

We can switch the python interpreter version we’re using in 2 ways, globally, or locally.

Let’s have a look at doing this globally:

# List the current global python version
pyenv global
# `system`

# List all installed versions
pyenv versions
# * system (set by /Users/anillakhman/.pyenv/version)
# 2.6.9
# 2.7.12
# 3.1.5
# 3.2.6
# 3.3.6
# 3.4.5
# 3.5.2

# Let's switch to 3.1.5
pyenv global 3.1.5

# Check python
python --version
# Python 3.1.5

pyenv versions
# ...
# * 3.1.5 (set by /Users/anillakhman/.pyenv/version)
# ...

# Set pyenv to load our python versions
# Order matters (system first, then our custom versions)
pyenv global system 2.7.12 3.1.5 3.2.6 3.3.6 3.4.5 3.5.2 2.6.9

You can see we switched our global python version to our newly installed 3.1.5.

Our global version is stored in the default pyenv home directory /Users/anillakhman/.pyenv/version

cat /Users/anillakhman/.pyenv/version
# 3.1.5

We now have our environment setup to use multiple versions of python.


Tox

If you’re using Tox and setting up an environment to test multiple python versions. The following might help you get started.

# tox.ini, put in same dir as setup.py
[tox]
envlist = py31
#skip_missing_interpreters = True

[testenv]
# pip freeze > requirements.txt
deps = -rrequirements.txt
commands= {envpython} setup.py test

We can now successfully run our tests with py31, but if we change py31 to py32 we get the following error.

ERROR: py32: InvocationError: Failed to get version_info for python3.2: pyenv: python3.2: command not found

The python3.2 command exists in these Python versions:

3.2.6

This may be py26, py27, py31, py32, py33, py34, py35, py36 depending what version you’re testing with.

Although we have 3.2 installed, we have to instruct pyenv that we want to use it globally.

# Load our python versions IN THIS ORDER
pyenv global system 2.7.12 3.1.5 3.2.6 3.3.6 3.4.5 3.5.2 2.6.9

# This updates your ~/.pyenv/version to the following:

# system
# 2.7.12
# 3.1.5
# 3.2.6
# 3.3.6
# 3.4.5
# 3.5.2
# 2.6.9

# pyenv will load python in the above order

pyenv versions
# * system (set by /Users/anillakhman/.pyenv/version)
# * 2.6.9 (set by /Users/anillakhman/.pyenv/version)
# * 2.7.12 (set by /Users/anillakhman/.pyenv/version)
# * 3.1.5 (set by /Users/anillakhman/.pyenv/version)
# * 3.2.6 (set by /Users/anillakhman/.pyenv/version)
# * 3.3.6 (set by /Users/anillakhman/.pyenv/version)
# * 3.4.5 (set by /Users/anillakhman/.pyenv/version)
# * 3.5.2 (set by /Users/anillakhman/.pyenv/version)

# Our system python is still loaded by default
pyenv which python
# /usr/local/bin/python

Our tox test using py32 should now work as expected.


Switching versions locally

You can also switch the python version you want to use locally (per project) by using a .python-version file at the root of your project.

When you enter this directory, pyenv will load the python version’s specified in your .python-version.

You can set this up manually or via the command line like so:

# switch to a working dir
cd ~/Sites/some-project/

# Show the current version
pyenv which python
# /usr/local/bin/python

python --version
# Python 2.7.11

# Create a local pyenv
pyenv local 3.2.6
# created a `.python-version` file with content:
# 3.2.6

# We changed python version for this directory only
python --version
# Python 3.2.6

# Globally, we're still using our default `system`
cd .. && python --version
# Python 2.7.11

View the Github page for more info https://github.com/yyuu/pyenv#readme.