.. _tips-and-tricks: ================= Tips and Tricks ================= This is a list of user-contributed tips for making virtualenv and virtualenvwrapper even more useful. If you have tip to share, drop me an email or post a comment on `this blog post `__ and I'll add it here. Enhanced bash/zsh Prompt ======================== Via `Stephan Sokolow `_ While the virtualenv ``activate`` script does attempt to provide an indicator in the prompt, it has various shortcomings, and cannot be customized. However, it does also set a shell variable named ``VIRTUAL_ENV`` which can be used as the basis for disabling the built-in prompt indicator and substituting an improved one, as a customization to ``.bashrc`` or ``.zshrc``:: virtualenv_prompt() { # If not in a virtualenv, print nothing [[ "$VIRTUAL_ENV" == "" ]] && return # Distinguish between the shell where the virtualenv was activated # and its children local venv_name="${VIRTUAL_ENV##*/}" if typeset -f deactivate >/dev/null; then echo "[${venv_name}] " else echo "<${venv_name}> " fi } # Display a "we are in a virtualenv" indicator that works in child shells too VIRTUAL_ENV_DISABLE_PROMPT=1 PS1='$(virtualenv_prompt)'"$PS1" This basic example works in both bash and zsh and has the following advantages: 1. It will also display in sub-shells, because it works by having the shell detect an active virtualenv, rather than by having the ``activate`` script modify the prompt for just the current shell instance. 2. It will clearly indicate if you're in a subshell, where the virtualenv will still apply, but the ``deactivate`` command will be missing. However, if you are using zsh, a better example of what the design is capable of can be constructed by taking advantage of zsh's built-in support for easily adding color and right-aligned segments to prompts:: zsh_virtualenv_prompt() { # If not in a virtualenv, print nothing [[ "$VIRTUAL_ENV" == "" ]] && return # Distinguish between the shell where the virtualenv was activated # and its children local venv_name="${VIRTUAL_ENV##*/}" if typeset -f deactivate >/dev/null; then echo "[%F{green}${venv_name}%f] " else echo "<%F{green}${venv_name}%f> " fi } setopt PROMPT_SUBST PROMPT_PERCENT # Display a "we are in a virtualenv" indicator that works in child shells too VIRTUAL_ENV_DISABLE_PROMPT=1 RPS1='$(zsh_virtualenv_prompt)' Updating cached ``$PATH`` entries ================================= From Nat (was blogger.com/profile/16779944428406910187): I also added the command 'rehash' to ``$WORKON_HOME/postactivate`` and ``$WORKON_HOME/postdeactivate`` as I was having some problems with zsh not picking up the new paths immediately. Creating Project Work Directories ================================= Via `James `_: In the ``postmkvirtualenv`` script I have the following to create a directory based on the project name, add that directory to the python path and then cd into it:: proj_name=$(basename $VIRTUAL_ENV) mkdir $HOME/projects/$proj_name add2virtualenv $HOME/projects/$proj_name cd $HOME/projects/$proj_name In the ``postactivate`` script I have it set to automatically change to the project directory when I use the workon command:: proj_name=$(basename $VIRTUAL_ENV) cd ~/projects/$proj_name Automatically Run workon When Entering a Directory ================================================== `Justin Abrahms posted `__ about some code he added to his shell environment to look at the directory each time he runs ``cd``. If it finds a ``.venv`` file, it activates the environment named within. On leaving that directory, the current virtualenv is automatically deactivated. Installing Common Tools Automatically in New Environments ========================================================= Via rizumu (was rizumu.myopenid.com): I have this ``postmkvirtualenv`` to install the get a basic setup. :: $ cat postmkvirtualenv #!/usr/bin/env bash curl -O http://python-distribute.org/distribute_setup.p... />python distribute_setup.py rm distribute_setup.py easy_install pip==dev pip install Mercurial Then I have a pip requirement file with my dev tools. :: $ cat developer_requirements.txt ipdb ipython pastescript nose http://douglatornell.ca/software/python/Nosy-1.0.tar.gz coverage sphinx grin pyflakes pep8 Then each project has it's own pip requirement file for things like PIL, psycopg2, django-apps, numpy, etc. Changing the Default Behavior of ``cd`` ======================================= Via `mae `__: This is supposed to be executed after workon, that is as a ``postactivate`` hook. It basically overrides ``cd`` to know about the VENV so instead of doing ``cd`` to go to ``~`` you will go to the venv root, IMO very handy and I can't live without it anymore. If you pass it a proper path then it will do the right thing. :: cd () { if (( $# == 0 )) then builtin cd $VIRTUAL_ENV else builtin cd "$@" fi } cd And to finally restore the default behaviour of ``cd`` once you bailout of a VENV via a ``deactivate`` command, you need to add this as a ``postdeactivate`` hook:: unset -f cd Clean up environments on exit ======================================= Via `Michael `__: When you use a temporary virtualenv via ``mktmpenv`` or if you have a :ref:`plugins-post_deactivate` hook, you have to actually run ``deactivate`` to clean up the temporary environment or run the hook, respectively. It's easy to forget and just exit the shell. Put the following in ``~/.bash_logout`` (or your shell's equivalent file) to always deactivate environments before exiting the shell:: [ "$VIRTUAL_ENV" ] && deactivate