Recently I was in development of a Python project that supports both the regular Python 2.7 and also the PyPy environment. Here is how to setup the automatic testing environment using Tox and Travis-CI.

Tox Setup and Handling Numpy

Tox is a tool to test if your package can be installed in various Python environment properly. Tox setup is relatively easy: just follow the basic setup document of Tox.

The tricky part of supporting regular Python and PyPy simultaneously is to handle the numpy packet properly. since you can not simply do a pip install numpy in PyPy, but have to use the BitBucket repo URL instead.

[UPDATE 2016-10-05]

I found there is this PyPy port of numpy called numpy-pypy. We can also use this package.

To install numpy properly, I did three things.

First, have one common-requirements.txt that specific all requirements except for the numpy, and then have two separated py27-requirements.txt and pypy-requirements.txt. In py27-requirements.txt, specify the numpy version needed.

1
2
3
# requirements for py27
-r common-requirements.txt
numpy==1.11.1

While in pypy-requirements.txt, use the BitBucket link instead. .. code-block:: text

# requirements for pypy git+https://bitbucket.org/pypy/numpy.git -r common-requirements.txt

Second, detect Python environment at runtime and set up install_requires properly.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
install_requires = [
    # requirements
]

if platform.python_implementation() == 'PyPy':
    install_requires.append('numpy-pypy')
else:
    install_requires.append('numpy')

setup(
    # ...
    install_requires=install_requires,
    # ...
)

At this point, you should be able to use the tox command to test both the py27 and the pypy environment.

Travis Setup

We need to first install the recent version of PyPy as Travis is known to behind on PyPy versions. Here is the .travis.yml that installs the PyPy v5.4.1 using pyenv.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
language: python
python:
    - "2.7"
    - "pypy"
addons:
    apt:
        packages:
            - pypy-dev
            - liblapack-dev
install:
    - |
        if [[ "${TRAVIS_PYTHON_VERSION}" = pypy ]]; then
            git clone https://github.com/yyuu/pyenv.git ~/.pyenv
            PYENV_ROOT="$HOME/.pyenv"
            PATH="$PYENV_ROOT/bin:$PATH"
            eval "$(pyenv init -)"
            pyenv install pypy-5.4.1
            pyenv global pypy-5.4.1
        fi
    - pip install tox-travis
script:
    - tox

The numpy-pypy package depends on pypy-dev and liblapack-dev, so we install them through the addons configuration of Travis.

Note that we also used the tox-travis plugin to easy the integration of tox and Travis.