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:
pyenv
pyenv-virtualenv
- see Note on virtualenv and venv:
pyenv-virtualenv
usespython -m venv
if it is available (CPython 3.3 and newer) and thevirtualenv
command 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
.envrc
file. - below notes permits to install my own version of this file used to make direnv interacts nicely and easily with
pyenv
andpyenv-virtualenv
. - For review: my custom
direnvrc
configuration 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
myproject
is 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
|
|