After writing some benefits I had using pyenv to isolate and manage my python versions, it would be good to complement that talking about pyenv-virtualenv tool which facilitates the management of python virtual environments.

An important thing is that I’m not using pyenv-virtualenv by itself. I’m using it as plugin of pyenv. This explains the reason my terminal commands starts with pyenv. Now, going straight to the point that most attracted me:

1. Created virtualenvs are all at the same place

All virtualenvs that you create using the tool will be placed at the same directory: ~/.pyenv/versions. I’ve created three different environments so we can take a better look at that.

vagrant@vagrant-ubuntu-trusty-64:~$ pyenv virtualenvs
  3.4.3/envs/venv1 (created from /home/vagrant/.pyenv/versions/3.4.3)
  3.4.3/envs/venv2 (created from /home/vagrant/.pyenv/versions/3.4.3)
  3.5.0/envs/venv3 (created from /home/vagrant/.pyenv/versions/3.5.0)
  venv1 (created from /home/vagrant/.pyenv/versions/3.4.3)
  venv2 (created from /home/vagrant/.pyenv/versions/3.4.3)
  venv3 (created from /home/vagrant/.pyenv/versions/3.5.0)

This is actually showing twice the same environments but if you add --skip-aliases (like the issue says) you’ll be fine:

vagrant@vagrant-ubuntu-trusty-64:~/.pyenv$ pyenv virtualenvs --skip-aliases
  3.4.3/envs/venv1 (created from /home/vagrant/.pyenv/versions/3.4.3)
  3.4.3/envs/venv2 (created from /home/vagrant/.pyenv/versions/3.4.3)
  3.5.0/envs/venv3 (created from /home/vagrant/.pyenv/versions/3.5.0)
 

A good benefit is that it avoids you from creating virtualenv directories arbitrarily on wherever you want and is prone to forget.

2. Pointing to python version when creating environment

Creating a virtualenv of a specific version of python is as easy as this: pyenv virtualenv <PYTHON-VERSION> <virtualenv-name>

vagrant@vagrant-ubuntu-trusty-64:~$ pyenv virtualenv 3.4.3 venv343
Ignoring indexes: https://pypi.python.org/simple
Requirement already satisfied (use --upgrade to upgrade): setuptools in /home/vagrant/.pyenv/versions/3.4.3/envs/venv343/lib/python3.4/site-packages
Requirement already satisfied (use --upgrade to upgrade): pip in /home/vagrant/.pyenv/versions/3.4.3/envs/venv343/lib/python3.4/site-packages

vagrant@vagrant-ubuntu-trusty-64:~$ pyenv virtualenvs
  3.4.3/envs/venv1 (created from /home/vagrant/.pyenv/versions/3.4.3)
  3.4.3/envs/venv2 (created from /home/vagrant/.pyenv/versions/3.4.3)
  3.4.3/envs/venv343 (created from /home/vagrant/.pyenv/versions/3.4.3)
  3.5.0/envs/venv3 (created from /home/vagrant/.pyenv/versions/3.5.0)
  venv1 (created from /home/vagrant/.pyenv/versions/3.4.3)
  venv2 (created from /home/vagrant/.pyenv/versions/3.4.3)
  venv3 (created from /home/vagrant/.pyenv/versions/3.5.0)
  venv343 (created from /home/vagrant/.pyenv/versions/3.4.3)

3. Local python for project-specific needs

This is the one that I like the most. If you type pyenv versions, you get a list of python versions and virtualenvs available for use.

vagrant@vagrant-ubuntu-trusty-64:~$ pyenv versions
  system
  3.4.3
  3.4.3/envs/venv1
  3.4.3/envs/venv2
  3.4.3/envs/venv343
* 3.5.0 (set by /home/vagrant/.pyenv/version)
  3.5.0/envs/venv3
  venv1
  venv2
  venv3
  venv343

I’m currently working on a project that always use my venv343 virtualenv. Once I have all my virtualenvs in the same place, I can use pyenv local venv343 command that tells my terminal to automatically use venv343 while in the project directory:

vagrant@vagrant-ubuntu-trusty-64:~$ pyenv local venv343
pyenv-virtualenv: deactivate 
pyenv-virtualenv: activate venv343
pyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior.

(venv343) vagrant@vagrant-ubuntu-trusty-64:~$ cd ..
pyenv-virtualenv: deactivate 3.4.3/envs/venv343
vagrant@vagrant-ubuntu-trusty-64:/home$ 

vagrant@vagrant-ubuntu-trusty-64:/home$ cd vagrant/
pyenv-virtualenv: deactivate 
pyenv-virtualenv: activate venv343
pyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior.

(venv343) vagrant@vagrant-ubuntu-trusty-64:~$ 

Once set, every time I go to that directory, my terminal will be using venv343. Notice that when entering the directory I ran pyenv local <version> before, my terminal automatically goes into the desired virtualenv. When I leave the directory, the virtualenv is deactivated.

Way of work

The reason of adopting pyenv and pyenv-virtualenv is so that I can create a standard way of working with python projects that requires little intervention of myself. I transfer to these tools the responsabilities of things like enabling or disabling virtualenvs or using the correct python version executable. Let me know you that makes sense to you and also how you usually do it, which tools you use. : )