Twine是PyPI官方唯一推荐的上传工具,因其强制HTTPS、支持API token认证、提供上传前校验(twine check)且避免setup.py upload等不安全旧方式;必须用__token__用户名配合scope限定的PyPI API token,而非密码。

Twine 是目前唯一被 PyPI 官方推荐的上传工具,不使用它而直接调用 python setup.py upload 或旧版 setuptools 上传命令,会触发 403 错误或被拒绝——因为 PyPI 自 2020 年起已彻底弃用非 HTTPS 上传通道。
为什么 twine upload 会报 401 或 “Invalid or non-existent authentication information”
这不是 Twine 的 bug,而是认证方式变更导致的典型失败。PyPI 现在强制要求使用 API token(而非账户密码)进行上传,且 token 必须限定作用域(如仅限上传指定包)。
- 错误现象:
HTTPError: 401 Client Error: Unauthorized for url: https://upload.pypi.org/legacy/ - 根本原因:你在
~/.pypirc中写了明文密码,或运行twine upload时没传--username __token__ --password pypi-xxxxx... - 正确做法:登录 https://www.php.cn/link/0e1ceaca3e404ed57c3d9d6eaa2928a3 创建一个 scope 为
Upload packages to the specified projects的 token,并只授权给你的包名(比如my-awesome-package) - 临时上传命令示例:
twine upload --username __token__ --password pypi-AgEIcHlwaS1... dist/* - 长期方案:把 token 写进
~/.pypirc,但必须用__token__作为用户名,不能写邮箱或账号名
twine check 报 “Failed validation” 怎么快速定位问题
这个命令不是可选步骤,是上传前必跑的“包体检”。它检查的是 setup.py 或 pyproject.toml 中元数据是否符合 PyPI 解析规则,常见失败点和修复方式如下:
-
long_description格式错误:如果你用了README.md,必须显式声明long_description_content_type='text/markdown',否则会被当成纯文本解析,导致渲染失败 - 包名含非法字符:PyPI 只接受小写字母、数字、
-和_,MyPackage_v2会失败,应改为mypackage-v2 - 版本号违反 PEP 440:像
1.0.0-beta不合法,应写成1.0.0b0;2.1.0.dev应为2.1.0.dev0 - 缺失必要字段:
name、version、description三者缺一不可;url和author_email虽非强制,但缺失会导致 PyPI 页面警告
上传时该选 dist/*.whl 还是 dist/*.tar.gz
两者都要传,但顺序和用途不同。PyPI 会按用户环境自动选择安装最匹配的格式,忽略任一格式都会降低安装成功率。
-
*-py3-none-any.whl:纯 Python wheel,跨平台、安装快,优先级最高 -
*.tar.gz(sdist):源码包,当用户环境没有匹配 wheel 时回退使用,也是 CI 构建和审计的唯一可信来源 - 不要只传 wheel:某些 Linux 发行版或嵌入式 Python 环境不支持 wheel 安装,只传 wheel = 主动放弃这部分用户
- 构建命令建议统一用:
python -m build(需先pip install build),它会同时生成 wheel 和 sdist,比老式python setup.py sdist bdist_wheel更可靠
为什么上传成功后 pip install 找不到你的包
不是网络或缓存问题,大概率是包名冲突、索引延迟或项目结构缺陷。
- 包名已被占用:PyPI 包名全局唯一,
requests、numpy这类通用名肯定注册不了;可用pip search mypkg(已废弃)或直接访问https://pypi.org/project/mypkg/确认 - 上传到测试仓库却误以为是正式库:确认你传的是
https://upload.pypi.org/legacy/,而不是https://test.pypi.org/legacy/;后者需用pip install -i https://test.pypi.org/simple/ mypkg才能安装 - src 目录未正确配置:若你把代码放在
src/my_package/下,但setup.py没写packages=find_packages(where="src")且没配package_dir={"": "src"},生成的 wheel 里就是空的 - PyPI 索引更新有延迟:上传成功后最多 10 分钟才可被
pip search或网页搜索到,但pip install通常秒生效
真正容易被忽略的是:PyPI 不校验代码逻辑,只校验包结构和元数据。哪怕你上传了一个 print("hello") 的空包,只要 twine check 通过、token 正确、名字未被占,它就“合法上架”了——所以发布前务必本地验证:pip install --find-links dist/ --no-index your-package-name,确保能真正 import 和运行。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











