Testing a NumPy-based code on Travis with plain pip and wheels

Installing the scientific Python stack is not the most obvious task in a scientist's routine. This is especially annoying for automated deployments such as for continuous integration testing. I present here a short way to deploy Travis CI testing for a small library that depends only on NumPy.

The goal

I developed a small library that relies only on Python and NumPy, as a design requirement. I wanted a simple pip-based deployment of my Python package testing via continuous integration, including the version of NumPy of my choice and with no rebuild of NumPy.

I started by performing the tests on my machines, simply issuing python -m pytest when changing the code. This is a limitation, mostly because I am limited to a few Python/NumPy versions.

How to set up Travis

Travis has instructions and support for Python-based projects. The typical "SciPy stack" is not covered (except for one version of NumPy that ships with their images), so most Python-based scientific software downloads Anaconda or Miniconda as part of their continuous integration testing, getting access to plently of binary packages.

I have no specific argument against the conda solution apart that it is a large dependency in terms of download size, and that I believe "plain pip" is the most general solution for Python and I like to stick to it.

So, I set up Travis with a test matrix for Python 2.7, 3.5 and 3.6. I wanted to test several NumPy versions as well. I couldn't find a lightweight solution (i.e. a nice sample .travis.yml file) as most projects use (ana/mini)conda. Since the arrival of manylinux wheels, it is actually easy to rely on "plain pip" to install NumPy on Travis. Make sure to update pip itself first and to install "wheels" as well.

The timing of the build on travis is between 30 and 80s, so there is obviously no build of NumPy occurring there and this is a reasonable use of resources.

In the example, I exclude NumPy 1.11.0 from the Python 3.6 test because there are no "Python 3.6 NumPy 1.11.0" manylinux wheels.

language: python

python:
- 2.7
- 3.5
- 3.6

env:
- NUMPY_VERSION=1.11.0
- NUMPY_VERSION=1.12.1
- NUMPY_VERSION=1.14.0

matrix:
exclude:
- python: 3.6
env: NUMPY_VERSION=1.11.0

script:
- virtualenv --python=python venv
- source venv/bin/activate
- python -m pip install -U pip
- pip install -U wheel
- pip install numpy==\$NUMPY_VERSION
- pip install pytest
- python setup.py build
- python -m pytest


Ending

I hope that this solution will be useful to others. If you want to see the repository itself, it is here (with a badge to the travis-ci builds).

The resulting .travis.yml file is really short, which is (in my opinion) a benefit. As SciPy also provides manylinux wheels, this is really a powerful and easy way to deploy. Any scientific package that depends on NumPy/SciPy can use it and add a build of the compiled package with, for instance, an extra dependency on GCC or Cython.