推荐使用pyproject.toml(PEP 517/518),setup.py仅兼容;必填字段包括name、version、description、readme、requires-python;必须用PyPI API token而非密码,上传前需执行python -m build、twine check、本地pip安装三步验证。

能传上去,但大概率第一次会失败——不是代码问题,而是 setup.py 或 pyproject.toml 里少写了关键元数据,或者认证方式没走对 twine 流程。
setup.py 和 pyproject.toml 到底该用哪个?
Python 官方已明确推荐 pyproject.toml(PEP 517/518),setup.py 处于“兼容但不鼓励新增使用”状态。新项目直接写 pyproject.toml,避免后续迁移成本。
- 如果你用
setuptools>=61.0,pyproject.toml可完全替代setup.py,无需两者共存 -
setup.py若仍存在,会被忽略(除非显式加[build-system]指向它) - 常见错误:只改了
setup.py版本号,却忘了同步pyproject.toml里的version字段,导致上传的包版本和本地不一致
pyproject.toml 必须填哪些字段才能过 PyPI 校验?
PyPI 在上传时会严格校验元数据,缺一不可。最常被漏掉的是 description 和 readme,哪怕内容只写一行也会通过。
-
name:必须全小写、仅含字母数字和短横线(my-awesome-lib✅,MyAwesomeLib❌) -
version:建议用dynamic方式从__version__读取,避免手动维护两处 -
description:不能为空,哪怕填"A small utility" -
readme:必须存在且路径正确(如"README.md"),否则twine check直接报错Invalid value for 'long_description': No content type specified. -
requires-python:例如>=3.8,不写会导致上传成功但安装时提示Package requires Python >=3.x but running on 3.y
twine upload 总是 403 或 “invalid or non-existent authentication information”
这不是密码错了,而是你没用 PyPI 的 API token,还在试图传账号密码——PyPI 自 2023 年起已禁用密码直传。
立即学习“Python免费学习笔记(深入)”;
- 去 https://www.php.cn/link/0e1ceaca3e404ed57c3d9d6eaa2928a3 创建一个
Scopedtoken(限制到具体项目名更安全) - 上传命令必须用
twine upload --repository testpypi(测试)或--repository pypi(正式),不能省略--repository - 凭证要存在
~/.pypirc或用环境变量TWINE_USERNAME=__token__+TWINE_PASSWORD=your-token-here - 常见坑:
twine upload dist/*如果 dist 目录里混着旧包(比如不同版本或 .tar.gz / .whl 都有),可能因重复上传失败,建议每次先rm -rf dist/
上传前必须跑的三步本地检查
跳过这三步,90% 的上传失败都发生在这儿,而且错误信息藏得深。
-
python -m build:生成dist/下的.whl和.tar.gz,失败说明pyproject.toml语法或依赖声明有硬伤 -
twine check dist/*:验证包描述是否可解析、README 格式是否合法,报InvalidDistribution多半是readme路径错或没指定content-type -
pip install --find-links dist/ --no-index your-package-name:在干净虚拟环境中装一下,确认import和入口点是否真能工作——很多包上传后 install 成功但 import 报ModuleNotFoundError,是因为packages没自动发现子模块
最麻烦的其实是包结构本身:比如你的模块在 src/mylib/ 下,但 pyproject.toml 没配 packages = [{include = "mylib", from = "src"}],那么生成的 wheel 里就压根没代码。这种问题不会在 twine check 里暴露,只能靠最后那步本地安装验证。


















