My magical auto-virtualenv trick (without VirtualenvWrapper)

One thing that pissed me off a few days ago was working in a Python project with some modules and switching between virtualenvs every time[1]. So I quickly hacked a solution.

But before going further, let me say that the solution is highly based on VirtualenvWrapper — to the point that I’m using the same environment variables. I just didn’t want to install a whole package for a simple feature.

And, without further ado…

The whole thing started with two alias added in my .bashrc, one to create a virtualenv and another to “active” the virtualenv. Today, they look like this:

export WORKON_HOME=$HOME/Venv
function venv { source $WORKON_HOME/$1/bin/activate; }
function mkenv { virtualenv $WORKON_HOME/$1; venv $1; echo "$1" > ./.venv; }

Nothing fancy here: I’m using WORKON_HOME exactly as it is used with VirtualenvWrapper, to point the directory where all virtualenvs sit. Then, to avoid going full path to activate them, I can simply use venv <virtualenv-name> to activate any virtualenv and, finally, to create virtualenvs in the right directory, I have mkenv <virtualenv-name>. Simple as that.

One thing you may notice is that I’m saving the virtualenv name in a hidden file inside the current directory, called .venv. This is what makes the magic happen.

Then, I have this script + alias:

function _venv_cd { 
if [ ! -f $PWD/$1 -a "$VIRTUAL_ENV." != "."  ]; then 
    deactivate
fi;
\cd $1; 
if [ -f ./.venv ]; then 
    venv `cat ./.venv`; 
fi }
alias cd=_venv_cd

This basically replaces cd with my function, which checks if the target directory have a .venv and, if it does, activate the virtualenv (so I don’t need to use venv anymore in normal situations); if there is no .venv but a virtualenv is active, deactivate it.

The only problema I still have is that going up inside the project/module won’t check if there is a .venv in any of the parent directories and, thus, would disable the virtualenv.

[1] It was just a matter of “keeping each with their own”. The whole project goes around creating modules for a web framework and each module must be capable of working standalone, without the others.