If you’re not a Python programmer, you probably won’t find much in this post. Sorry.
If you are a Python programmer, then you probably know about virtualenvs, or virtual environments. They allow you to create several different Python environments to work in: each can have it’s own version of Python, as well as its own installed packages. This means I can work on a project that has particular requirements, and then switch to a project with completely different requirements, and the two won’t affect each other.
A while ago I used to use vitualenvwrapper
, which made working with virtualenvs a lot easier. But as I switched to Python 3 over the past few years, I started to have some issues where it didn’t work correctly (sorry, I no longer recall precisely what those issues were). I’m sure a lot had to do with the addition of the venv
module into Python 3, which allowed you to create a virtualenv by running python -m venv /path/to/virtualenv
.
For a while I ran all the commands manually, but I have the quality that makes for good programmers: I’m lazy. A lazy person doesn’t want to do any more work than they have to, so if I can automate something to save time over the long run, I will. And here’s what I came up with:
export VENV_HOME=$HOME/venvs
function workon {
if [ -z $1 ]
then
ls -1 $VENV_HOME
else
source $VENV_HOME/$1/bin/activate
fi
}
function mkvenv {
python3 -m venv $VENV_HOME/$1
workon $1
pip install -U pip setuptools wheel
pip install ipython pytest-pudb requests
}
function rmvenv {
command -v deactivate
rm -rf $VENV_HOME/$1
}
_venvdirs()
{
local cur="$2"
COMPREPLY=( $(cd $HOME/venvs && compgen -d -- "${cur}" ) );
}
complete -F _venvdirs workon rmvenv
Code language: Bash (bash)
These lines should be added to your .bashrc
in Linux, or your .bash_profile
for Macs. I haven’t tried them with zsh
yet, so no guarantees there. Let’s go over what these lines do.
Line #1 defines the directory where the virtualenvs will be stored. You can store them anywhere; it doesn’t make any difference.
Lines #3–10 define the workon
function, which activates the specified virtualenv, or lists all virtualenvs if none is specified. Lines 12–17 define the mkvenv
function, which creates a new venv, and lines 19–22 define rmvenv
, which deletes virtualenvs when you no longer need them.
I’d like to point out 2 lines in mkvenv
that you can customize. Line #15 updates the installed versions of pip
, setuptools
, and wheel
. If for some reason you don’t want the latest versions of these, edit or remove that line.
Line #16 is more interesting: nearly every virtualenv I create needs these packages installed. Rather than install them one-by-one, I add them when I create the virtualenv. If you have different packages you always want available, edit this line.
Finally, lines #24–29 are of utmost importance to someone lazy like myself: they provide auto-completion for the other commands. I had to learn about bash completion to get that working, but it turned out to be much easier than I had imagined.
Here is a gif showing it in action:
Try it out! Let me know if you find this useful, or if you have suggestions for improvement.