有没有标准方法声明旧版Python不再支持?

10 投票
3 回答
2352 浏览
提问于 2025-04-28 06:04

我想正式停止对我维护的程序的 Python 2 支持,充分利用 Python 3 的特性。与其让程序在 Python 2 下勉强工作,但在某些特殊情况下出现奇怪的行为,我更希望能明确地让程序在 Python 2 下报错,并显示“请使用 Python 3”这样的提示信息。那么,如何合理地让不支持的 Python 版本出现错误呢?

举个例子,我希望在 Python 2 中导入我的代码(至少是顶层包)时能触发一个错误,并且在尝试为 Python 2 安装或构建我的 distutils 的 setup.py 脚本时也能报错(即使是通过 Python 3 调用,比如 python3 setup.py sdist_dsc --with-python2)。我还想加入一些相关的信息,正式声明我支持哪些 Python 版本。在 PEP 345 中有一个 Requires-Python 字段,但我觉得如果我不使用 distutils2,这个字段就没什么意义。

暂无标签

3 个回答

2

我会选择这个回答,不过我会抛出一个异常:

import sys

if sys.version_info[0] < 3:
    raise ImportError('Only Python 3 is supported.')
3

标准的做法是在 setup.py 文件中设置 classifiers:

if sys.version_info < (3, 3):
    sys.exit("error: this script requires Python 3.3 or greater.")

setup(...,
classifiers=[
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
        # ... other non-version info
    ],
    ...)

例如,tulip 项目(asyncio)只支持 Python 3.3

你也可以在你的包的 __init__.py 文件中添加:

if sys.version_info < (3, 3):
    raise ImportError("Python 3.3 or greater is required")
9

从setuptools 24.2.0(2016年7月20日)和pip 9.0.0(2016年11月2日)开始,setup.py中的setup()函数可以使用python_requires这个参数,告诉打包工具不要安装不符合要求的包。例如,如果你只想支持Python 3.6及以上版本,可以这样写:

setup(
    ...
    python_requires=">=3.6",
    ...
)

如果你只想支持Python 2.7和3.4及以上版本,可以这样写:

setup(
    ...
    python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
    ...
)

由于现在有了内置的支持,下面这些方法在这个回答中就不需要再用了。


如果你想防止导入,可以在模块的最上面加上这一行:

import sys

if sys.version_info[0] < 3:
    raise ImportError('Python < 3 is unsupported.')

如果你想防止安装,可以在setup.py的最上面加上这一行:

import sys

if sys.version_info[0] < 3:
    sys.exit('Python < 3 is unsupported.')

如果你使用了与Python 2不兼容的语法,这样做也会在检查之前就失败,因为模块会在运行之前被解析。为了“不要支持Python 2”而进行这样的检测可能有点过于复杂。

不过我实际上还没见过有人这样做。大多数维护者只是说明支持哪些版本,而不去检查。

撰写回答