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

时间:2017-02-15 00:00:44

标签: python pip setuptools pypi python-packaging

在使用不受支持的Python版本时,我们可以在setup.py文件中放置什么来阻止pip收集并尝试安装软件包?

例如magicstack是使用特洛伊分类器列出的项目:

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的版本,例如curio,实际上安装得很好 - 因为setup.py没有使用任何Python 3特定的东西 - 只在导入时失败,因为只有一些Python 3语法是用过的。而且我确定有些软件包安装正常,导入正常,可能只在运行时失败!

以pip会尊重的方式指定支持的Python版本的正确方法是什么?我找到了一种解决方法,只涉及上传一个轮文件,并拒绝上传.tar .gz发布,但我很想知道正确的解决方法。

编辑:如果Python / os / architecture不匹配,pip如何知道下载滚轮分发?它只是使用.whl filename convention还是有更复杂的东西比幕后发生的更复杂?我们可以以某种方式将元数据提供给源代码分发,以使pip使用.tar.gz上传做正确的事吗?

2 个答案:

答案 0 :(得分:11)

有一种正确的方法可以做到这一点,但不幸的是pip只在版本9.0.0(2016-11-02发布)中开始支持它,所以使用旧版本的pip的用户将继续不顾一切地下载软件包他们的Python版本是什么。

在您的setup.py文件中,传递setup()一个python_requires参数,其中列出了您的软件包支持的Python版本PEP 440 version specifier。例如,如果您的软件包仅适用于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参数;早期版本只会通过警告忽略它。之后构建的所有项目的sdists和wheel将包含相关的元数据,告诉PyPI告诉pip他们的Python版本。

答案 1 :(得分:1)

pypi上的magicstack分布已被破坏。它失败了,因为源代码分发并不包含magicstack包,即使源代码分发的setup.py说明它应该。

只要pypi包含源代码分发(例如.tar.gz.zip),如果pip无法找到匹配的二进制分布(例如.egg),则会下载pip, .whl)您的python / os / architecture版本。

您的选择是仅将二进制分发上传到pypi(最好是wheels),但我甚至不知道是否允许二进制pypi包。另一个选项是检查sys.versionsetup.py的兼容版本,否则会引发异常。