python_requires需配合wheel格式发布才生效,仅写>=3.8不足;必须生成含py38等标签的.whl文件并上传pypi,且安装时使用pip≥9.0.0,源码包.tar.gz会忽略该限制。

setup.py里python_requires写什么才真正生效
只写 python_requires=">=3.8" 不够,它不会阻止用户在 3.7 上 pip install,除非配合正确的打包和上传方式。真正起作用的前提是:项目必须以 wheel(.whl)格式发布到 PyPI,并且安装时使用 pip ≥ 9.0.0(2017 年后默认都满足)。源码包(.tar.gz)会被 pip 忽略 python_requires,直接解压运行 setup.py —— 此时校验完全失效。
实操建议:
- 用
python -m build构建 wheel,别只打 sdist - 上传前检查 dist/ 目录下是否有
.whl文件,且文件名含py38、py39等标签(如mylib-1.0-py38-none-any.whl) - 本地验证:用低于要求的 Python 版本(如 3.7)执行
pip install ./dist/mylib-1.0-py38-none-any.whl,应报错ERROR: Package 'mylib' requires a different Python: 3.7.x not in '>=3.8'
python_requires支持哪些语法——别用错范围表达式
它不是 shell glob,也不是正则,而是 PEP 508 定义的版本说明符,常见合法写法有:
">=3.8, —— 推荐,明确限定主版本边界-
"~=3.8"—— 等价于">=3.8, ==3.*",允许 3.8.x、3.9.x,但拒绝 4.0 -
"==3.9.*"—— 只接受 3.9.x 系列(x 为任意次版本),不包括 3.10 - 错误写法:
"3.8+"(非法)、"3.8 - 3.10"(不被解析)、"3.8 or 3.9"(语法错误)
注意:~=` 比 <code>>= 更严格,适合依赖 C 扩展或特定 stdlib 行为的项目;若你用了 typing.Literal(3.8+)或 zoneinfo(3.9+),就别写成 ~=3.8,否则 3.9 用户反而被拦住。
为什么pip install没报错?可能是wheel没生成或平台不匹配
即使写了正确的 python_requires,仍可能静默安装成功,常见原因:
- 发布的只有
.tar.gz,没有.whl——python_requires被跳过 - wheel 文件名中平台标记为
manylinux_x86_64但 Python 标签是py3(即 “universal”),此时 pip 不校验具体小版本 - 用户用
pip install --no-deps --force-reinstall强制覆盖,会绕过所有约束 - Windows 上安装时,wheel 名为
py3-none-win_amd64.whl,但 Python 解释器实际是 3.7 —— 若python_requires是">=3.8",pip 仍会拒绝,除非 wheel 标记为py3(非py38)
自查命令:python -m wheel unpack dist/mylib-*.whl && cat mylib-*/MYLIB-*.dist-info/WHEEL,看 Tag: 行是否包含具体 Python 版本标签(如 cp38 或 py38)。
setup.cfg 或 pyproject.toml 里怎么写等效配置
如果你已迁移到 pyproject.toml,python_requires 不再写在 setup.py,而是在 [project] 段落里:
[project] requires-python = ">=3.8" # 注意:不是 python_requires,也不是 dependencies 下的条目
对应旧式 setup.cfg:
[metadata] python_requires = >=3.8
三者语义一致,但优先级:pyproject.toml > setup.cfg > setup.py。如果同时存在,后两者会被忽略。另外,requires-python 在 pyproject.toml 中是必填项(PEP 621),不写会导致构建工具(如 setuptools 61+)报错。
真正容易被忽略的是:即便声明了 requires-python,如果项目里用了 from __future__ import annotations(3.7+)却声称只支持 3.8+,这种“声明与行为不一致”不会被自动检测,只能靠人审代码。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











