How to handle dependency on scipy in setup.py
Question: I am trying to create a `setup.py` for a project that depends on SciPy. The
following `setup.py` reproduces this:

    
    
    setup(
        name='test',
        version='0.1',
        install_requires=['scipy']
    )
    

When installing this using `python setup.py develop` it generates the
following error:

    
    
    ImportError: No module named numpy.distutils.core
    

However, when I install scipy using `pip`, it installed it from a wheel, and
it works just fine.

So, my questions is, how can I create a `setup.py` that depends on SciPy? Why
won't `setuptools` install dependencies from wheels? Would this work better
when using Python 3 (we plan to migrate anyway, so if it works there, I'll
just wait until the migration is complete).

I am using Python 2.7.8 on Mac OS X 10.10.1 with `setuptools` 3.6 and `pip`
1.5.6.


Answer: Ultimately, this worked for me:

    
    
    #!/usr/bin/env python
    
    from setuptools import setup, Extension
    from setuptools.command.build_ext import build_ext as _build_ext
    
    #
    # This cludge is necessary for horrible reasons: see comment below and
    # http://stackoverflow.com/q/19919905/447288
    #
    class build_ext(_build_ext):
        def finalize_options(self):
            _build_ext.finalize_options(self)
            # Prevent numpy from thinking it is still in its setup process:
            __builtins__.__NUMPY_SETUP__ = False
            import numpy
            self.include_dirs.append(numpy.get_include())
    
    setup(
        #
        # Amazingly, `pip install scipy` fails if `numpy` is not already installed.
        # Since we cannot control the order that dependencies are installed via
        # `install_requires`, use `setup_requires` to ensure that `numpy` is available
        # before `scipy` is installed.
        #
        # Unfortunately, this is *still* not sufficient: `numpy` has a guard to
        # check when it is in its setup process that we must circumvent with
        # the `cmdclass`.
        #
        setup_requires=['numpy'],
        cmdclass={'build_ext':build_ext},
        install_requires=[
            'numpy',
            'scipy',
        ],
        ...
    )
    

