【问题标题】:Dependency management: subprocess32 needed for Python2.7依赖管理:Python2.7需要subprocess32
【发布时间】:2018-04-16 07:52:31
【问题描述】:

我有一个依赖于 subprocess32 的库 (subx)。 subprocess32 库是 Python2.7 的反向端口,并提供超时 kwarg。

我的库需要 timeout kwarg。

仅当目标平台是 Python2.x 时,我才需要 subprocess32。

我应该如何在我的项目中定义依赖关系?

如果我通过“install_requires”(setup.py) 定义对 subprocess32 的依赖并且我在 python3 virtualenv 中,我会收到此错误消息:

===> pip install -e git+https://github.com/guettli/subx.git#egg=subx
Obtaining subx from git+https://github.com/guettli/subx.git#egg=subx
  Cloning https://github.com/guettli/subx.git to ./src/subx
Collecting subprocess32 (from subx)
  Using cached subprocess32-3.2.7.tar.gz
    Complete output from command python setup.py egg_info:
    This backport is for Python 2.x only.

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-lju3nl1y/subprocess32/

【问题讨论】:

    标签: python pip dependency-management setup.py install-requires


    【解决方案1】:

    有一种声明方式,但是 afaik 它需要或多或少的最新版本 setuptools(如果我正确阅读了 release notes,您至少需要 20.2 版本)。您将在下面看到的称为环境标记,并在PEP 508 中指定,如果您愿意,请通读它以获取可用标记的完整列表并更好地理解标记语法。

    对于python版本,我们以你的包为例:你有subprocess32依赖,应该安装在python2.X环境中。像这样增强你的依赖:

    install_requires=[
        'subprocess32; python_version<"3"',
    ]
    

    现在用python2.7 安装包subx 会产生:

    Processing ./dist/subx-2017.8.0-py2-none-any.whl
    Collecting subprocess32; python_version < "3" (from subx==2017.8.0)
    Installing collected packages: subprocess32, subx
    Successfully installed subprocess32-3.2.7 subx-2017.8.0
    

    如果你用python3.X安装它,输出将是:

    Processing ./dist/subx-2017.8.0-py3-none-any.whl
    Installing collected packages: subx
    Successfully installed subx-2017.8.0
    

    注意subprocess32的安装将被跳过。


    另一个常见的示例是声明特定于平台的依赖项:我有一个项目需要在 Linux 上安装 auditwheel 并在 MacOS 上安装 delocate。我这样声明依赖项:

    install_requires=[
        ...
        'auditwheel==1.7.0; "linux" in sys_platform',
        'delocate==0.7.1; "darwin" == sys_platform',
    ]
    

    请注意,如果您没有专门针对任何主要的 Python 版本,则需要对 Linux 进行此项检查,因为:

    $ python2 -c "import sys; print sys.platform"
    linux2
    

    但是

    $ python3 -c "import sys; print sys.platform"
    linux
    

    因此,例如,如果您的包仅适用于 python2.X,您可以使用检查 "linux2" == sys.platform。这将使您的依赖项只能使用 python2.X 安装。

    【讨论】:

    • 这似乎是一个完整的答案。但是,在 Windows 中,sys.platform 将打印 Windows 的 win32 和 Windows/Cygwin 的 cygwin
    • @ElisByberi afaik 支持基本表达式,因此 "win32" == sys_platform or "cygwin" == sys_platform 应该可以工作。但是,还有其他环境标记,例如 platform_system,可能更适合这种情况。再次查看PEP 508 了解更多详情。
    【解决方案2】:
    import sys
    
    kw = {}
    if sys.version_info[0] == 2:
        kw['install_requires'] = ['subprocess32']
    
    setup(
        …
        **kw
    )
    

    【讨论】:

    • 强烈建议您添加一些关于您的代码如何运行的解释。简单地提供代码并不是学习编程的最佳方法,并且不会像解释得当那样使帖子创建者受益。详细的答案将建立您在社区中的信誉,并且您的答案将吸引投票。
    • 是的,有效。但我问自己是否有更多的声明性解决方案可用。这看起来像编程,而不是定义依赖关系。不要误会我的意思。谢谢你的回答!
    • 此方法仅适用于源焦油,但会因轮子而失败。
    • 不要创建万向轮。特定版本的轮子就可以了。
    • 抱歉,您是对的 - 只有万向轮受到影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    • 2021-11-18
    • 2021-09-09
    • 2011-03-13
    • 2013-06-15
    • 2011-11-24
    相关资源
    最近更新 更多