代码之家  ›  专栏  ›  技术社区  ›  skoy

setup\u仅要求某些命令

  •  2
  • skoy  · 技术社区  · 7 年前

    我有一个distutils风格的Python包,它的构建步骤需要一个特定且非常大的依赖项。当前,此依赖项是在 setup_requires distutils的参数。设置。不幸的是,这意味着将为 任何 安装程序的执行。py,包括运行时 setup.py clean . 这就造成了一种相当讽刺的情况,即清理步骤有时会导致大量代码被编译。

    正如我所说的,只有 build

    2 回复  |  直到 7 年前
        1
  •  2
  •   hoefling    7 年前

    您可以随时订购 Distribution 要显式地获取一些包,方法与在中定义包时相同 setup_requires . 示例 numpy 所需的依赖项 build 仅限命令:

    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\u需要 arg,所以版本规格也可以:

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

    尽管我必须注意,通过 setup\u需要 通常是 比通过安装它们慢 pip (特别是当您有一些必须首先从源代码构建的严重依赖项时),所以如果您可以确定 pip公司 可用( or use python3.4 and newer ),建议的方法 phd 在his中 answer 将节省您的时间。然而,当为旧的python版本或晦涩难懂的python安装(如MacOS上的系统python)构建时,通过分发获取鸡蛋可能很方便。

        2
  •  1
  •   David Brabant    5 年前
    if sys.argv[0] == 'build':
        kw = {'setup_requires': [req1, req2, …]}
    else:
        kw = {}
    
    setup(
        …,
        **kw
    )
    

    另一种尝试方法是重写 build 带有自定义的命令 cmdclass :

    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