【问题标题】:setup_requires only for some commandssetup_requires 仅适用于某些命令
【发布时间】:2018-01-16 14:27:57
【问题描述】:

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

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

【问题讨论】:

    标签: python pip setuptools distutils


    【解决方案1】:

    您始终可以命令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),phd 在他的answer 中建议的方法将节省您的时间。然而,在为旧的 python 版本构建或像 MacOS 上的系统 python 等晦涩的 python 安装时,通过分发获取鸡蛋可能会派上用场。

    【讨论】:

      【解决方案2】:
      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

      【讨论】:

      • 不幸的是,当构建命令被调用为其他东西的子命令时,它会失败。 (例如:运行python setup.py install时。)
      • 我为答案添加了另一种方法。
      猜你喜欢
      • 2012-05-25
      • 1970-01-01
      • 1970-01-01
      • 2013-09-11
      • 2018-03-31
      • 2022-01-11
      • 2020-01-05
      • 2017-11-19
      • 2021-09-17
      相关资源
      最近更新 更多