防止软件包在旧版Python上安装

19
我们可以在setup.py文件中加入什么内容,以防止pip在使用不支持的Python版本时收集并尝试安装包?
例如magicstack是一个列出了trove分类器的项目。
Programming Language :: Python :: 3 :: Only

所以如果 pip --version 与 Python 2.7 相关联,我希望它表现出以下行为:

$ pip install magicstack
Collecting magicstack
  Could not find a version that satisfies the requirement magicstack (from versions: )
No matching distribution found for magicstack

但实际表现是pip会收集一个发布版本,下载它,尝试安装它,然后失败。还有其他Python3-only版本,例如curio,它实际上可以成功安装 - 因为setup.py没有使用任何特定于Python 3的内容 - 只有在使用某些仅适用于Python 3语法的导入时才会失败。我相信还有一些包可以安装,可以导入,也许只有在运行时失败!

什么是指定受支持的Python版本的正确方法,以使pip能够遵守?我找到了一个解决方法,涉及只上传wheel文件,并拒绝上传.tar.gz分发,但我很想知道正确的修复方法。


编辑:如果Python /操作系统/架构不匹配,pip如何知道不下载轮分发? 它只是使用.whl文件名规则还是背后发生了更复杂的事情? 我们是否可以为源分发提供元数据,以使pip对.tar.gz上传执行正确操作?


谷歌搜索出一些之前的问题和答案,建议在setup.py中检查Python版本。 - user2357112
相关:https://packaging.python.org/guides/distributing-packages-using-setuptools/#classifiers,其中提到:“尽管分类器列表通常用于声明项目支持哪些Python版本,但此信息仅用于在PyPI上搜索和浏览项目,而不用于安装项目。要实际限制可以安装项目的Python版本,请使用python_requires参数。” - 0 _
请参考以下链接:https://dev59.com/y2Yr5IYBdhLWcg3wIG5u#64386359 - 0 _
请参考以下链接:https://dev59.com/y2Yr5IYBdhLWcg3wIG5u#45362425 - 0 _
请参考以下链接:https://dev59.com/02Ik5IYBdhLWcg3wJ7P4#48777286 - 0 _
显示剩余2条评论
2个回答

18

有一种正确的方法来做这件事情,但不幸的是,pip只在9.0.0版本(发布于2016-11-02)开始支持它,因此拥有旧版本pip的用户将继续随意下载软件包,而不管它们是否适用于所使用的Python版本。

在您的setup.py文件中,传递一个python_requires参数给setup()函数,将您的软件包支持的Python版本列为PEP 440 版本说明符。例如,如果您的软件包仅适用于Python 3+,则应编写:

setup(
    ...
    python_requires='>=3',
    ...
)

如果您的软件包适用于Python 3.3及更高版本,但您还不愿意承诺支持Python 4,请编写:

setup(
    ...
    python_requires='~=3.3',
    ...
)

如果你的程序包是针对Python 2.6、2.7以及所有从3.3开始的Python 3版本,请写下:

setup(
    ...
    python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <4',
    ...
)

等等就是这样。

完成上述步骤后,您需要将setuptools的版本升级至至少24.2.0,以便处理python_requires参数。早期版本只会忽略该参数并发出警告。在此之后构建的项目压缩包和wheel都将包含相关元数据,告诉PyPI告诉pip它们适用的Python版本。


@wim:你在python_requires中使用了哪个版本说明符? - jwodder
我已经上传了一个源代码分发包到pypi上进行测试(实现请参见此处),看起来它在pypi上的表现与你描述的一样。我只能在另一个索引上重现错误行为。这可能是因为我遇到了devpi服务器的一个bug,明天会进一步调查... - wim
1
点击此处获取更多有用信息:http://www.python3statement.org/practicalities/ - Noah
我的问题确实是由于索引中的错误导致的(旧版本的devpi服务器未能正确提供python_requires元数据 - 我相信这在当前版本中已经得到解决了)。 - wim
1
我认为值得一提的是,项目必须使用 pip3 install [-e] 进行安装(而不是使用 python3 setup.py install 直接安装),如此处所述:https://python3statement.org/practicalities/。 - Guy Avraham

1

magicstack在pypi上的发行版有问题。由于源分发不包含magicstack包,即使源分发的setup.py中指定了它,它仍然会失败。

只要pypi包含源分发(例如.tar.gz.zip),如果找不到与您的python/os/架构版本匹配的二进制分发(例如.egg.whl),pip就会下载该源分发。

一种选择是仅向PyPI上传二进制分发(最好是wheels)。另一种选择是在setup.py中检查兼容版本的sys.version,否则引发异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接