19

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

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

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


编辑:如果 Python/os/architecture 不匹配 ,pip 如何知道不下载轮子分发?它只是使用.whl 文件名约定还是比幕后发生的更复杂?我们能否以某种方式将元数据提供给源分发,以使 pip 对 .tar.gz 上传做正确的事情?

4

2 回答 2

17

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

在您的setup.py文件中,传递setup()一个python_requires参数,将您的包支持的 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处理参数;早期版本只会忽略它并发出警告。之后构建的所有项目的 sdists 和轮子将包含相关的元数据,告诉 PyPI 告诉 pip 它们适用于哪些 Python 版本。

于 2017-03-14T17:13:10.250 回答
1

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

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

一种选择是仅将二进制发行版上传到 PyPI(最好是wheels)。另一种选择是检查sys.versionsetup.py的兼容版本,否则会引发异常。

于 2017-02-15T00:52:13.927 回答