Skip to content

Python 2.x and Python 3.x

Yee Cheng Chin edited this page Jan 4, 2021 · 12 revisions

MacVim binary distribution is enabled to use Python 2.7 and Python 3.6 out of the box (These Python 2.x and 3.x version number may vary with MacVim snapshot version. Please take a look at release description.)

But common Python distribution doesn't allow to use Python 2.7 and Python 3.6 at the same time due to Python shared module loading. You will get error.

E837: This Vim cannot execute :py3 after using :python
E263: Sorry, this command is disabled, the Python library could not be loaded.

For example,

$ mvim -u NONE -U NONE --noplugin -c 'py print("test")'
WORK

$ mvim -u NONE -U NONE --noplugin -c 'py3 print("test")'
WORK

$ mvim -u NONE -U NONE --noplugin -c 'py print("test")' -c 'py3 print("test")'
DOESN'T WORK

$ mvim -u NONE -U NONE --noplugin -c 'py3 print("test")' -c 'py print("test")'
DOESN'T WORK

You must build MacVim, Python 2.x and 3.x as the following way by yourself if you really really want to use Python 2.x and 3.x at the same time. It's not common use case.

  • Install python 2.7.x

    Use pyenv. It requires in order to use Python 2.x and 3.x interface in MacVim, it doesn't mean that you have to use this pyenv for you Python runtime.

    $ PYTHON_CONFIGURE_OPTS="--enable-shared" \
        LDSHARED="clang -bundle" \
        LDCXXSHARED="clang++ -bundle" \
        BLDSHARED="clang -bundle -lpython2.7" \
        pyenv install 2.7.11
    
  • Verify python 2.7.x

    Use otool to verify the binary.

    $ otool -L $HOME/.pyenv/versions/2.7.11/lib/python2.7/lib-dynload/_ctypes.so
    /Users/foo/.pyenv/versions/2.7.11/lib/python2.7/lib-dynload/_ctypes.so:
        /Users/foo/.pyenv/versions/2.7.11/lib/libpython2.7.dylib (compatibility version 2.7.0, current version 2.7.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
    

    libpython2.7.dylib should be included in the result.

  • Install python 3.6.x

    Use pyenv. It requires in order to use Python 2.x and 3.x interface in MacVim, it doesn't mean that you have to use this pyenv for you Python runtime.

    $ PYTHON_CONFIGURE_OPTS="--enable-shared" \
        LDSHARED="clang -bundle" \
        LDCXXSHARED="clang++ -bundle" \
        BLDSHARED="clang -bundle -lpython3.6m" \
        pyenv install 3.6.0
    
  • Verify python 3.6.x

    Use otool to verify the binary.

    $ otool -L $HOME/.pyenv/versions/3.6.0/lib/python3.6/lib-dynload/_ctypes.cpython-36m-darwin.so
    /Users/foo/.pyenv/versions/3.6.0/lib/python3.6/lib-dynload/_ctypes.cpython-36m-darwin.so:
            /Users/foo/.pyenv/versions/3.6.0/lib/libpython3.6m.dylib (compatibility version 3.6.0, current version 3.6.0)
            /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
    

    libpython3.6m.dylib should be included in the result.

  • Install MacVim with the option

    Currently, the officially supported way is to manually build MacVim by following the instructions at https://github.com/macvim-dev/macvim/wiki/Building and pass the --with-properly-linked-python2-python3 flag when calling ./configure.

    (Deprecated) There used to a maintained Homebrew tap that you could use. The tap is currently unmaintained, but to use it, you could do the following:

    $ brew tap macvim-dev/macvim
    $ brew install --HEAD macvim-dev/macvim/macvim --with-properly-linked-python2-python3
    
  • Verify

    Check version output

    $ /usr/local/Cellar/macvim/HEAD/bin/vim --version|grep python
    +cscope          +lispindent      +python/dyn      +viminfo
    +cursorbind      +listcmds        +python3/dyn     +vreplace
    

    Both +python/dyn and +python3/dyn should be here.

  • Sample setting

    This setting is just sample, and it just uses the pyenv Python runtime what we used to build MacVim. The path is vary with your system.

    .vimrc

    set pythonhome=$HOME/.pyenv/versions/2.7.11
    set pythondll=$HOME/.pyenv/versions/2.7.11/lib/libpython2.7.dylib
    set pythonthreehome=$HOME/.pyenv/versions/3.6.0
    set pythonthreedll=$HOME/.pyenv/versions/3.6.0/lib/libpython3.6m.dylib
    
  • Test

    Execute this vim script

    function! s:py3_test()
        py3 import time
        py3 from ctypes import *
        py3 lib = cdll.LoadLibrary("/usr/lib/libc.dylib")
        py3 print(time.ctime(lib.time(0)))
    endfunction
    function! s:py_test()
        py import time
        py from ctypes import *
        py lib = cdll.LoadLibrary("/usr/lib/libc.dylib")
        py print(time.ctime(lib.time(0)))
    endfunction
    call s:py3_test()
    call s:py_test()