Using Pyenv-virtualenv+direnv
Some times ago, I made a post entitled ‘Sandboxed Python with Pyenv, virtualenv and autoenv’. This new post, considering direnv tool as a better replacement to autoenv (from the own terms of autoenv author) was initially created on Nov 22, 2017 and reviewed/updated in Sept 10, 2019.
So here are my updated notes to setup a clean and sandboxed environment for python projects (similar to what can be done in Ruby with RVM and project gemsets).
Reference:
pyenvpyenv-virtualenv- see Note on virtualenv and venv:
pyenv-virtualenvusespython -m venvif it is available (CPython 3.3 and newer) and thevirtualenvcommand is not available.
- see Note on virtualenv and venv:
- Blog posts:
Summary of the pyenv/pyenv-virtualenv most important commands:
| Command | Description |
|---|---|
pyenv install --list |
List known versions of Python that can be installed |
pyenv install <version> |
Install python version <version> |
pyenv uninstall <version> |
Uninstall python version <version> |
pyenv versions |
List currently installed version |
pyenv version |
Get current version |
pyenv local <version> |
Set locally current version to <version> |
pyenv virtualenvs |
List currently available virtualenvs |
pyenv virtualenv --force --quiet <version> <name> |
Create a new virtualenv <name> for version <version> |
pyenv virtualenv <name> |
Create virtualenv from current $(pyenv version) |
pyenv activate <name> |
Activate virtualenv <name> |
pyenv deactivate (or source deactivate) |
Deactivate current virtualenv |
pyenv uninstall <name> |
Uninstall virtualenv <name> |
pyenv virtualenv-delete <name> |
(as above) |
Installation
Under Mac OS X, prefer (as always) an installation through Homebrew:
1 2 | |
Under Linux, see pyenv-installer:
1 2 3 4 | |
You probably want also to activate the pyenv bash/zsh completion
Configuration for pyenv[-virtualenv]
Adapt your environment i.e. ~/.{profile | bash* | zsh* etc.} to support pyenv shims, virtualenv and direnv.
See my own pyenv.sh and direnv.sh common shell hook scripts for up-to-date content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
If you’re using oh-my-zsh, you probably want to enable the pyenv plugin
Configuration for direnv
- Reference documentation:
- Direnv has a standard library of functions / layout
- See direnv-stdlib - man page
- You can override the direnv-stdlib with your own set of function though
~/.config/direnv/direnvrc.- This file is loaded and it’s content made available to any
.envrcfile. - below notes permits to install my own version of this file used to make direnv interacts nicely and easily with
pyenvandpyenv-virtualenv. - For review: my custom
direnvrcconfiguration file installed below
- This file is loaded and it’s content made available to any
1 2 3 4 5 6 | |
From this global direnvrc configuration, a typical .envrc at the root of your project directory would look like.
For instance:
1 2 3 4 5 6 7 8 9 10 11 | |
You can take a look at my default template for the .envrc file
Note: DEEPRECATION: since Python 2.7 will reach the end of its life on January 1st, 2020, the above configuration enforces to use the latest Python 3.x version (at the time of writing).
Time for the awesome magic
First of all, you should have installed a few different recent pythons
1 2 3 4 5 6 7 | |
Assuming you wish to configure you project hosted within the /path/to/myproject directory:
Define the expected python version under .python-version and copy the default template for the local direnv configuration file .envrc:
1 2 3 4 5 | |
Eventually, if you don’t want to use the virtualenv named myproject (i.e. the basename of the directory), you can define the expected name for the virtualenv under .python-virtualenv as follows:
1
| |
That’s all !
Just allow (one time) the .envrc file and enjoy from now on the automatic loading/unloading of your virtualenv (created if needed) every time you visit/leave your project [sub]directories!
1 2 3 4 5 | |
In particular, the following action were performed (and this will happen every time you enter this directory):
- the expected python version is loaded (default or from
.python-version)- An error message is raised to ask you to install it if that version cannot be found
- a virtualenv
myprojectis created (or whatever name you specified in.python-virtualenv) - this virtualenv is activated
Enjoy your sand-boxed environment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Leave your directory to unload the virtualenv and thus ensure the isolation:
1 2 3 4 5 6 7 8 9 10 | |
Reminder: You can later on install all pip packages back from the requirements.txt file (generated by pip freeze -l > requirements.txt) via:
1
| |