Search code examples
pythonvim

Compiling vim with specific version of Python


I'm working on several Python projects who run on various versions of Python. I'm hoping to set up my vim environment to use ropevim, pyflakes, and pylint but I've run into some issues caused by using a single vim (compiled for a specific version of Python which doesn't match the project's Python version).

I'm hoping to build vim into each of my virtualenv directories but I've run into an issue and I can't get it to work. When I try to build vim from source, despite specifying the Python config folder in my virtualenv, the system-wide Python interpreter is always used.

Currently, I have Python 2.6.2 and Python 2.7.1 installed with several virtualenvs created from each version. I'm using Ubuntu 10.04 where the system-default Python is 2.6.5. Every time I compile vim and call :python import sys; print(sys.version) it returns Python 2.6.5.

configure --prefix=/virtualenv/project --enable-pythoninterp=yes --with-python-config-dir=/virtualenv/project/lib/python2.6/config

Results in the following in config.log:

...
configure:5151: checking --enable-pythoninterp argument
configure:5160: result: yes
configure:5165: checking for python
configure:5195: result: /usr/bin/python
...

It should be /virtualenv/project/bin/python. Is there any way to specify the Python interpreter for vim to use?

NOTE: I can confirm that /virtualenv/project/bin appears at the front of PATH environment variable.


Solution

  • I'd recommend building vim against the 2 interpreters, then invoking it using the shell script I provided below to point it to a particular virtualenv.

    I was able to build vim against Python 2.7 using the following command (2.7 is installed under $HOME/root):

    % LD_LIBRARY_PATH=$HOME/root/lib PATH=$HOME/root/bin:$PATH \
        ./configure --enable-pythoninterp \ 
        --with-python-config-dir=$HOME/root/lib/python2.7/config \
        --prefix=$HOME/vim27
    % make install
    % $HOME/bin/vim27
    
    :python import sys; print sys.path[:2]
    ['/home/pat/root/lib/python27.zip', '/home/pat/root/lib/python2.7']
    

    Your virtualenv is actually a thin wrapper around the Python interpreter it was created with -- $HOME/foobar/lib/python2.6/config is a symlink to /usr/lib/python2.6/config.

    So if you created it with the system interpreter, VIM will probe for this and ultimately link against the real interpreter, using the system sys.path by default, even though configure will show the virtualenv's path:

    % PATH=$HOME/foobar/bin:$PATH ./configure --enable-pythoninterp \
        --with-python-config-dir=$HOME/foobar/lib/python2.6/config \
        --prefix=$HOME/foobar
    ..
    checking for python... /home/pat/foobar/bin/python
    checking Python's configuration directory... (cached) /home/pat/foobar/lib/python2.6/config
    ..
    
    % make install
    % $HOME/foobar/bin/vim
    :python import sys; print sys.path[:1]
    ['/usr/lib/python2.6']
    

    The workaround: Since your system vim is most likely compiled against your system python, you don't need to rebuild vim for each virtualenv: you can just drop a shell script named vim in your virtualenv's bin directory, which extends the PYTHONPATH before calling system vim:

    Contents of ~/HOME/foobar/bin/vim:

    #!/bin/sh
    ROOT=`cd \`dirname $0\`; cd ..; pwd`
    PYTHONPATH=$ROOT/lib/python2.6/site-packages /usr/bin/vim $*
    

    When that is invoked, the virtualenv's sys.path is inserted:

    % $HOME/foobar/bin/vim
    :python import sys; print sys.path[:2]
    ['/home/pat/foobar/lib/python2.6/site-packages', '/usr/lib/python2.6']