Managing Python environments with pyenv
21 Dec 2016We all love Python - it’s a fantastic language, however managing installed
packages can be a pain. How many times have you ran sudo pip install or
sudo python setup.py install, and ended up conflicting with your system
pacakage manager, or had some obscure import error because you accidentally
installed multiple versions of the same package in different places?
The standard solution for this is to install Python packages into virtualenvs,
within which we can install whatever packages we want without impacting the
rest of the system. Once virtualenv is installed through pip, you can
create virtualenvs anywhere with virtualenv myenv and then activate them with
source myenv/bin/activate, however we are still left to manage our own set of
environments, and virtualenv does not help us easily manage different Python
versions. That’s where pyenv and pyenv-virtualenv come in.
pyenv
pyenv is a great tool for installing and managing different Python versions.
To install it, use brew on Mac or install manually.
You’ll then need to add the following line to your ~/.bashrc or similar to
enable pyenv:
eval "$(pyenv init -)"You can then start by listing all the available Python interpreters with:
pyenv install --listYou can see that many versions are available there, not just from the standard
CPython but also anaconda, pypy and others. The standard CPython interpreters
are the non-prefixed ones at the top of the list. To install one of these
versions, run pyenv install with the desired version number, e.g.:
pyenv install 3.5.2You can then set it as your default Python interpreter (instead of your system version) with:
pyenv global 3.5.2
python --version # 3.5.2You can also override the default version temporarily in a single shell with
pyenv shell, e.g.:
pyenv install 2.7.12
pyenv shell 2.7.12
python --version # 2.7.12Another really useful feature is pyenv local, which allows you to configure a
default Python interpreter for a particular directory tree. This allows you to
use a different Python version automatically for different projects. In the
following example, the default Python 3 interpreter is overridden inside the
project directory with a Python 2 interpreter:
pyenv global 3.5.2
mkdir project
cd project
pyenv local 2.7.12
python --version # 2.7.12
cd ..
python --version # 3.5.2pyenv-virtualenv
pyenv does a great job of managing different Python interpreters for you, but
it still doesn’t provide a convenient way of encapsulating different sets of
libraries in the way that virtualenv does. That’s where pyenv-virtualenv, a
pyenv plugin, comes in.
To install pyenv-virtualenv, again either use brew on Mac or
install manually. As with pyenv, you’ll need to
add the following line to your ~/.bashrc or similar to enable
pyenv-virtualenv:
eval "$(pyenv virtualenv-init -)"You can then make a new virtualenv with an installed Python interpreter version:
pyenv virtualenv 3.5.2 myenvYou can then see a list of all installed virtualenvs with:
pyenv virtualenvsYou can explicitly enable and disable virtualenvs with
pyenv activate <virtualenvname> and pyenv deactivate, and use the global
and local features of pyenv with virtualenvs as the argument:
pyenv local myenvThis is a really convenient feature - I use it to set up a new empty virtualenv for each Python project I’m working on, with a name matching the project, then set it as the local default when inside that project directory. This means I can install what I like inside that project without worrying about other projects, and make sure that all the necessary dependencies are retrieved when using the project’s installation helper(s).
In summary, I hope you’ll agree that pyenv and pyenv-virtualenv are a great
pair of tools to lift a lot of burden from managing Python interpreter versions
and virtualenvs. Personally, I’m looking forward to saving a lot of time and
effort in managing my Python environment in the future!