setup_requires 仅针对某些命令

setup_requires only for some commands

我有一个 distutils 风格的 Python 包,它的构建步骤需要一个特定的、相当大的依赖项。目前,此依赖项在 distutils.setup 的 setup_requires 参数下指定。不幸的是,这意味着将为 any 执行 setup.py 构建依赖项,包括 运行ning setup.py clean 时。这会产生颇具讽刺意味的清洁步骤情况,有时会导致编译大量代码。

正如我所说,只有 build 步骤才需要此设置依赖项。有没有办法在 setup.py 中编码此逻辑,以便所有不调用构建命令的命令都是 运行 没有它?

if sys.argv[0] == 'build':
    kw = {'setup_requires': [req1, req2, …]}
else:
    kw = {}

setup(
    …,
    **kw
)

另一种尝试方法是使用自定义 cmdclass 覆盖 build 命令:

from setuptools.command.build import build as _build

class build(_build):
    def run(self):
        subprocess.call(["pip", "install", req1, req2…])
        _build.run(self)

setup(
    …,
    cmdclass={'build': build},
)

并完全避免 setup_requires

您始终可以命令 Distribution 显式获取某些包,与在 setup_requires 中定义它们的方式相同。仅 build 命令需要 numpy 依赖项的示例:

from distutils.command.build import build as build_orig
from setuptools import setup, find_packages,  Command, dist


class build(build_orig):

    def run(self):
        self.distribution.fetch_build_eggs(['numpy'])
        # numpy becomes available after this line. Test it:
        import numpy
        print(numpy.__version__)
        super().run()

setup(
    name='spam',
    packages=find_packages(),
    cmdclass={'build': build,}
    ...
)

依赖项的传递与它们在 setup_requires arg 中定义的相同,因此版本规范也可以:

self.distribution.fetch_build_eggs(['numpy>=1.13'])

尽管我必须注意,通过 setup_requires 获取依赖项通常比通过 pip 安装它们 很多(尤其是当您有一些严重的依赖项时必须先从源代码构建),所以如果你能确定你会有 pip 可用(or use python3.4 and newer), the approach suggested by phd in his 会节省你的时间。然而,通过分发获取鸡蛋可能会在为旧 python 版本或晦涩的 python 安装,例如 MacOS 上的系统 python。