virtualenvwrapper is for Windows users too!

For a long time I’ve allowed myself to suffer without virtualenvwrapper on Windows because I didn’t think it would work. It turns out I am not only wrong, but that I can use it in all of my daily activity.

Virtualenvwrapper provides convenience commands and a central location for storing Python virtualenvs. Virtualenvs are an invaluable tool for playing around with incompatible Python modules and testing. If you’re not using them, you should start now. Virtualenvwrapper will save you some typing.

Doug Hellmann’s original virtualenvwrapper now supports MSYS environments out of the box, and David Marble has graciously suffered the unpleasantries of Windows batch file voodoo to bring up his fork virtualenvwrapper-win. Setup for both is quite straightforward and can be done in only a few minutes.

Virtualenv for cmd.exe

Install virtualenv-win:

> pip install virtualenvwrapper-win
> pyassoc

As an added bonus, virtualenvwrapper-win installs whereis in your path, which is akin to which on Unix, though it lists all locations. Since it seems I am incapable of remembering to place the batch file I wrote in my path to emulate which, this is quite convenient.

Enabling virtualenvwrapper on msysgit bash

Virtualenvwrapper will run on msysgit bash, or an install of msys bash. Unfortunately, the experience isn’t quite out of the box because msysgit does not include mktemp.exe. Otherwise, you can generally follow the instructions.

There are three steps:

  1. Install virtualenvwrapper
  2. Configure your .bashrc
  3. Install mktemp.exe

The first step is no different than on Linux:

$ pip install virtualenvwrapper

Next, configure a few extra variables in your .bashrc. msysgit’s bash uses your Windows home directory (%USERPROFILE%), so you’ll set MSYS_HOME to it.

if [ "$MSYSTEM" ]; then
    export MSYS_HOME=/c/MinGW/msys/1.0
    export WORKON_HOME=$HOME/.virtualenvs
    if [ -e /c/Python27/Scripts/virtualenvwrapper.sh ]; then
        source /c/Python27/Scripts/virtualenvwrapper.sh
    fi
fi

Replace your Python location above accordingly. Also, make sure that MSYSTEM is set to MINGW32 in your msysgit bash environment.

Finally, the hard part. To get mktemp, you’ll need to install the real MSYS distribution and download it. There’s certainly a shortcut here, but it was far easier for me to just do this than to figure out how to find where the MSYS project stores the binary. I’ve always found the MSYS website and Sourceforge page incomprehensible. So, download the latest MSYS installer and it let install the defaults. Open up your new MSYS bash prompt and grab mktemp:

$ mingw-get msys-mktemp

You’ll now have a fresh copy of mktemp.exe, whose slightly confusing default location will be C:\MinGW\msys\1.0\bin. Copy this binary into your msysgit’s bin directory. You’re now ready to go. Once you start up msysgit’s bash prompt with your new .bashrc in $HOME, you should be able to create a new virtualenv with mkvirtualenv.

Update 02/09/2013: As pointed out by David Marble, the full install of MSYS is not necessary to get mktemp.exe. I’ve confirmed that I am able to get virtualenvwrapper fully working just by downloading mktemp from Sourceforge and extracting directly into my msysgit bin directory.

This entry was posted in python and tagged , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

9 Comments

  1. David Marble
    Posted January 26, 2013 at 6:41 pm | Permalink

    Instead of installing all of MinGW, I recommend installing msysgit, which gives you a minimal install of msys, and simply downloading the binary for mktemp and putting it in the /bin folder of your msysgit installation. The binary can be found in this folder on sourceforge — the specific binary is here.

    • Posted January 27, 2013 at 2:40 pm | Permalink

      Part of the trouble I had was finding the direct link to mktemp on the mingw project on SF. Since you’ve provided the link that solves that problem. Now I just have to remember why I felt the need to add an MSYS_HOME environment variable pointing to my full MSYS installation. Were you able to use the mktemp binary from msysgit directly?

  2. Posted February 7, 2013 at 11:18 pm | Permalink

    I’m wondering if the act of installing full MSYS is setting some environment variable that makes this work. Using just msystgit + directly downloaded mktemp I’m finding that the wrappers are generating windows-style paths, which chokes bash. For example

    $ mkvirtualenv test
    New python executable in test\Scripts\python.exe
    ... (etc. while it creates files) Then:
    virtualenvwrapper.user_scripts could not run "d:\Users\test\.virtualenvs\premkvirtualenv": [Error 2] The system cannot find the file specified
    virtualenvwrapper.user_scripts could not run "d:\Users\test\.virtualenvs\preactivate": [Error 2] The system cannot find the file specified

    Interestingly, the files do get created correctly, it’s the activation of them that fails, presumably because it should be passing /d/users/test/.virtualenv/foo instead of the windows style path.

    Any thoughts? (As an aside, in this scenario MSYS_HOME points at the msysgit install folder)

    • Posted February 8, 2013 at 8:14 pm | Permalink

      I have had this problem myself, and I also recall that setting MSYS_HOME to a real MSYS install was quite necessary. I will be retesting this procedure today to see whether you can avoid using a full MSYS installation.

    • Posted February 9, 2013 at 11:42 pm | Permalink

      I re-tested this on a (somewhat) fresh install of Windows and I was successfully able to set up virtualenvwrapper with just a copy of mktemp.exe in my Git/bin directory.

      I suspect the problem with your install is that you do not have the MSYSTEM environment variable set to MINGW32. This seems to have already been set on my system. If you set that, it should fix the path issues. You can take a look at the source to see how it is checking.

      • Sergei Maertens
        Posted May 31, 2014 at 7:34 pm | Permalink

        I just tried fixing this again and stumbled on your post (thanks). Unfortunately, the files exist for me and $MSYSTEM is set to MINGW32. Any other ideas why it’s not working for me?

    • B .
      Posted March 5, 2013 at 2:10 am | Permalink

      Indeed, you have to have MinGW’s MSYS installed or Python will use Windows paths in the os.path calls

      • marc
        Posted July 3, 2014 at 8:28 am | Permalink

        I made it work with the MINGW32-Installation of the git bash;

        just replace

        export MSYS_HOME=/c/MinGW/msys/1.0

        with

        export MSYS_HOME=/c/Program\ Files\ \(x86\)/Git

        (or where ever you’ve installed it)

  3. alex
    Posted July 13, 2014 at 6:36 am | Permalink

    For myself, I don’t have MSYS installed so my MSYS_HOME points to my Git directory. Also, my experience was that lsvirtualenv did not work out of the box because it could not find fmt.exe in Git/bin. I followed the directions at http://stackoverflow.com/questions/20424326/where-can-i-get-the-fmt-binary-for-msys-mingw which was to download fmt.exe from:

    http://sourceforge.net/projects/mingw/files/MSYS/Base/coreutils/coreutils-5.97-3/coreutils-5.97-3-msys-1.0.13-ext.tar.lzma/download

    Two DLLs are also needed for it to work and should also be placed in Git/bin:

    libintl
    http://sourceforge.net/projects/mingw/files/MSYS/Base/gettext/gettext-0.18.1.1-1/libintl-0.18.1.1-1-msys-1.0.17-dll-8.tar.lzma/download

    libiconv
    http://sourceforge.net/projects/mingw/files/MSYS/Base/libiconv/libiconv-1.14-1/libiconv-1.14-1-msys-1.0.17-dll-2.tar.lzma/download

    Also, mkproject did not work because it tries to convert your $HOME variable using Python’s os.path.abspath, which results in a “c:” prefix to your Unix style path. Replacing the imports of os with posixpath and instances of os.path.abspath with posixpath seemed to do the trick.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>