为什么setup_requires不适合numpy?

col*_*fix 11 python numpy setuptools

我想创建一个setup.py文件,自动将构建时依赖项解析为numpy(用于编译扩展).我的第一个猜测是使用setup_requires和子类化命令类来导入numpy模块:

from setuptools import setup, Extension
from distutils.command.build import build as _build

class build(_build):
    def run(self):
        import numpy
        print(numpy.get_include())
        _build.run(self)

setup(
    name='test',
    version='0.0',
    description='something',
    cmdclass={'build':build},
    setup_requires=['numpy'],
)
Run Code Online (Sandbox Code Playgroud)

现在,运行python setup.py build成功编译numpy但然后失败(内部build.run):

AttributeError: 'module' object has no attribute 'get_include'
Run Code Online (Sandbox Code Playgroud)

但是,如果再次运行相同的命令,该命令现在成功(并且不需要重新编译numpy).

我已经在python {2.6,2.7,3.3}上使用和不使用virtualenv在最新版本的setuptools上进行了测试.

我已经看到使用pkg_resources.resource_filename解决方法似乎工作得很好,如果我们想要的只是include目录.编辑:只适用于python2!

但是,我现在很好奇.使用setup_requires有什么警告?可能是因为numpy无法正常工作的原因是什么?对于一些更简单的模块,它似乎没有问题.

col*_*fix 11

想通过检查__NUMPY_SETUP__内部来阻止numpy模块的正确初始化numpy/__init__.py:

if __NUMPY_SETUP__:
    import sys as _sys
    _sys.stderr.write('Running from numpy source directory.\n')
    del _sys
else:
    # import subodules etc. (main branch)
Run Code Online (Sandbox Code Playgroud)

安装后,setuptools不会重置此全局状态.以下作品:

...
def run(self):
    __builtins__.__NUMPY_SETUP__ = False
    import numpy
    ...
Run Code Online (Sandbox Code Playgroud)