I recently started developing some Python packages and wanted to be able to test my code with multiple Python versions: 2.6, 2.7, 3.3, 3.4, and 3.5. I already had the OS X system Python, which was version 2.7, plus I had a /usr/local/bin install of Python from Homebrew, and then I ran Enthought Canopy with Python 2.7 on top of that. Needless to say, I didn’t want to mess up my existing setup, I just wanted to have the other versions of Python available to Tox when testing my package. I already added multiple Python versions to my tox.ini, but they didn’t exist on my system yet:
[tox] envlist = py26, py27, py33, py34, py35
Installing Python 2.6, 3.3, 3.4, and 3.5 as “alternative installs” of Python is a fairly simple solution, although there doesn’t seem to be a consensus about how this should be done, with examples using Macports, pyenv, and other tools. Here’s how you do it the good ‘ol clean way:
First, we need to install Xcode command line tools so we can get zlib. If Python is not compiled with zlib Tox will not be able to create its virtualenvs. We also need to ensure we have openssl, and probably readline, then we can download and compile a specific version of Python.
xcode-select --install # Get zlib and other nonsense brew install readline # Worth a try brew install openssl export CPPFLAGS=-I$(brew --prefix openssl)/include; export LDFLAGS=-L$(brew --prefix openssl)/lib wget https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz tar xfz Python-3.4.3.tgz cd Python-3.4.3
Next, open setup.py, find the line that begins {python inline=”true”}search_for_ssl_incs_in = {/python} and add {python inline=”true”}/usr/local/opt/openssl/include/{/python} to that list. This is the path to your Homebrew openssl, which you’ll need to compile Python. Exporting the CPPFLAGS above should do this trick, but I found I had to modify setup.py, as well.
The {bash inline=”true”}–prefix=/usr/local{/bash} line below configures this version of Python to be installed in the /usr/local/bin folder, so that folder needs to be in your {bash inline=”true”}$PATH{/bash}; if you’re using Homebrew, it already is. Next, and critically, rather than using {bash inline=”true”}sudo make install{/bash} we use {bash inline=”true”}sudo make altinstall{/bash}, which prevents your existing {bash inline=”true”}python{/bash} executable from being overwritten.
./configure --prefix=/usr/local make sudo make altinstall sudo chown -R Nikhil:staff /usr/local/ # Replace username # Test that it works mkvirtualenv test -p /usr/local/bin/python3.4
Multiple versions of Python can be installed using this same method. They will be installed to /usr/local/bin/pythonX.Y, where X.Y corresponds to the version number. To run Python 3.4, simple run {bash inline=”true”}python3.4{/bash} in your Terminal. Tox should now have access to these alternative versions of Python, as well.
If you have already run Tox, then you’ll might need to recreate the virtualenv: {bash inline=”true}tox –recreate -e py34{/bash}. Or to recreate them all, use {bash inline=”true”}tox –recreate{/bash}. As of virtualenv version 13.something, Python 3 virtualenvs created with Python 2.x will fail, so revert back to virtualenv==12.0.2 to ensure you can create and test with Python 3.Y virtualenvs.