有没有标准方法声明旧版Python不再支持?
我想正式停止对我维护的程序的 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 个回答
我会选择这个回答,不过我会抛出一个异常:
import sys
if sys.version_info[0] < 3:
raise ImportError('Only Python 3 is supported.')
标准的做法是在 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")
从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”而进行这样的检测可能有点过于复杂。
不过我实际上还没见过有人这样做。大多数维护者只是说明支持哪些版本,而不去检查。