【问题标题】:Setuptools platform specific dependenciesSetuptools 平台特定依赖项
【发布时间】:2013-04-09 22:36:03
【问题描述】:

有没有办法告诉 setuptools 或分发需要特定平台上的包?

在我的具体情况下,我使用 readline,它是 Unix 系统标准库的一部分,但在 Windows 上,我需要 pyreadline 模块来替换该功能(参见 this question)。如果我只是把它放在要求它也安装在它完全没用的Unix系统上。

【问题讨论】:

    标签: python setuptools


    【解决方案1】:

    当我在 2013 年第一次在这里写答案时,我们还没有 PEP 496 – Environment MarkersPEP 508 – Dependency specification for Python Software Packages。既然我们这样做了,答案是:将环境标记放入您的setup_requires

    setup_requires = [
        'foo',
        'bar',
        'pyreadline; sys_platform == "win32"',
    ]
    
    setup(
        # ...
        setup_requires=setup_requires,
    )
    

    从 2016 年 5 月发布的 setuptools 20.6.8 开始支持此功能(在 version 20.5 中引入了支持,但在中间版本中被短暂禁用)。

    请注意,setuptools 在执行时将使用easy_install 安装这些需求,而使用pip 安装项目时很难配置。

    最好使用 setuptools 来处理构建时依赖项,并按照PEP 518 – Specifying Minimum Build System Requirements for Python Projects 的建议使用pyproject.toml 文件。使用带有内置依赖项的 PEP 518 构建系统,意味着创建一个看起来像这样的pyproject.toml 文件:

    [build-system]
    requires = [
        "setuptools",
        "wheel",
        "foo",
        "bar",
        "pyreadline; sys_platform == "win32",
    ]
    

    这与setup_requires 相同,但添加了setuptoolswheel。自 2018 年 3 月发布的 version 10.0.0 起,pip 支持此语法。

    我从 2013 年开始的旧答案如下。


    setup.py 只是一个 python 脚本。您可以在该脚本中创建动态依赖项:

    import sys
    
    setup_requires = ['foo', 'bar']
    
    if sys.platform() == 'win32':
        setup_requires.append('pyreadline')
    
    setup(
        # ...
        setup_requires=setup_requires,
    )
    

    【讨论】:

      【解决方案2】:

      如果需要支持旧的setuptools 版本,其他答案是有效的并且可能更方便,但已经取得了一些进步:

      最新版本的 setuptools 接受 PEP 508 样式依赖规范:

      setup(
          # ...
          install_requires=[
              'pyreadline; platform_system == "Windows"',
          ],
      )
      

      选择合适的参数:

      • install_requires:当前发行版还需要哪些其他发行版才能正常工作
      • extras_require:将可选功能的名称映射到其需求列表的字典
      • setup_requires: 需要存在的其他发行版才能正确运行安装脚本 注意:setup_requires 中列出的项目不会自动安装。如果它们在本地不可用,则只需将它们下载到 ./.eggs 目录即可。

      还有另一种方法可以通过setup.cfg 文件提供这些参数。 See the documentation for more info.

      PEP 518 引入了一种在pyproject.toml 文件中指定setup_requires 的新方法和更强大的方法:

      [build-system]
      # Minimum requirements for the build system to execute.
      requires = ['setuptools>"38.3.0"', 'wheel']  # PEP 508 specifications.
      

      该功能在pip 10.0.0b1 中实现。使用它可以自动安装和更新构建系统要求。

      【讨论】:

        【解决方案3】:
        from setuptools import setup
        
        
        setup(
            install_requires=(['pymsgbox', 'PyTweening>=1.0.1', 'Pillow', 'pyscreeze']
                            + ["python3-xlib; sys_platform == linux"]
                            + ["python-xlib; sys_platform == linux2"]
                            + ["pyobjc-core; sys_platform == darwin"]
                            + ["pyobjc; sys_platform == darwing"]
                            ),
        )
        

        这将安装特定版本的库,具体取决于它的 linux2(对于使用 python2 的 linux 系统)、linux(对于使用 python3 的 linux 系统)、darwin(对于 MacOS 系统)

        【讨论】:

          【解决方案4】:

          虽然 Martijn Pieters 给出的 answer 在当时是完全有效的,但 Python 封装从那时起发生了很大变化。

          分发包的首选格式是使用wheels*。使用轮子在安装期间无法运行 Python 代码。

          Wheel 使用PEP 0427 中指定的元数据版本二。 Environment markers 可用于指定平台特定的依赖关系。

          Setuptools 允许将这些环境标记指定为extras_require 键。以下示例脚本依赖于 Windows 系统的 pyreadline 和 Linux 发行版的 pyxdg

          #!/usr/bin/env python
          from setuptools import setup
          
          setup(
              name='spam',
              version='0.0.1',
              extras_require={
                  ':sys_platform == "win32"': [
                      'pyreadline'
                  ],
                  ':"linux" in sys_platform': [
                      'pyxdg'
                  ]
              })
          

          *同时发布一个sdist,所以不能使用wheel的平台仍然可以安装你的包。

          【讨论】:

          • 而不是':sys_platform == "win32"',写起来更易读、更直观,'platform_system=="Windows"'。而不是':"linux" in sys_platform',您可以使用'platform_system=="Linux"'。这将包括linuxlinux2。其他平台也一样,mac是'platform_system=="Darwin"'等。参考:PEP 508EasyBuilders
          • 由于install_requiresextras_require 都具有特定于平台的依赖机制,只是想知道建议使用哪一个?比如Pipenv中,Pipfile中支持extras_require还有一个问题~
          • 我的理解是:install_requires 应该是一个需要与包一起存在的包的列表,为了包的生命周期,为了包的功能。此软件包列表 (install_requires) 是对所需软件包的补充,并为请求的软件包提供必要的功能。 extras_require 仅在用户请求附加功能时自行决定安装。 setup_requires 是安装脚本继续运行所必需的包(如果您正在重载安装命令,则需要密钥)
          • 使用 PEP 496 和 508,不再需要使用额外的东西。现在我已经更新了我的答案,因为我知道它已经过时了,使用 PEP 496 语法,同时也向 518 致敬。
          猜你喜欢
          • 2020-02-04
          • 2014-10-31
          • 1970-01-01
          • 2017-09-29
          • 2014-10-02
          • 2021-01-01
          • 1970-01-01
          • 2011-09-12
          • 1970-01-01
          相关资源
          最近更新 更多