[Distutils] NumPy extensions and setup_requires

Michael Hoffman b3i4old02 at sneakemail.com
Thu Sep 13 12:17:48 CEST 2007

Michael Hoffman wrote:
> I'm creating a package that uses NumPy to build an extension module. In 
> order to do this, one must call numpy.get_include() like this:
> ext_modules = [Extension("_fwd_bwd",
>                           ["src/_fwd_bwd.pyx", "src/fwd_bwd.c"],
>                           include_dirs=[numpy.get_include()])]
> The problem is that if NumPy is not already installed, this will fail. I 
> can't use setup_requires in a simple manner because the function call 
> needs to happen before the call to setup().
> The solution of creating another Distribution object to satisfy 
> setup_requires before running setup() suggested in 
> <http://mail.python.org/pipermail/distutils-sig/2006-October/006744.html> 
> is unsatisfactory for the reasons also suggested there--if I do this 
> --help will not work and it also seems a bit clunky.
> I was thinking of instead making a subclass of Extension that will call 
> populate include_dirs from a function rather than a list of strings. Is 
> this the best solution?

The below seems to work partially. The problem is that you don't 
immediately get help when running setup.py --help. It tries to install 
numpy first, which isn't very friendly.

setuptools would also be more friendly if 
setuptools.dist.fetch_build_egg printed a message that it was about to 
go off and fetch software much like easy_install does. The first warning 
I get is "Running from numpy source directory." only after a long delay 
to download the source. PJE, would you consider adding such a message?

My NumpyExtension subclass:

from setuptools import Extension, setup

class NumpyExtension(Extension):
     def __init__(self, *args, **kwargs):
         Extension.__init__(self, *args, **kwargs)

         self._include_dirs = self.include_dirs
         del self.include_dirs # restore overwritten property

     # warning: Extension is a classic class so it's not really read-only
     def include_dirs(self):
         from numpy import get_include

         return self._include_dirs + [get_include()]

ext_modules = [NumpyExtension("_fwd_bwd",
                               ["src/_fwd_bwd.pyx", "src/fwd_bwd.c"])]

$ python -c "import pkg_resources; print 
[setuptools 0.6c7 

More information about the Distutils-SIG mailing list