twine上传必须使用带pypi-前缀的API token,禁用明文密码;需同时构建wheel和sdist格式,通过环境变量TWINE_USERNAME=__token__和TWINE_PASSWORD=pypi-xxx安全传入,并用twine upload dist/*上传。

twine 上传必须用 API token,不能输密码
PyPI 自 2023 年起已禁用账户密码直传方式,twine upload 若提示 403 Forbidden 或 Invalid or non-existent authentication information,基本就是还在用明文密码。API token 是唯一被接受的身份凭证,且必须带前缀 pypi-(例如 pypi-abc123...xyz)。
生成方式:登录 https://www.php.cn/link/0e1ceaca3e404ed57c3d9d6eaa2928a3 → “Add API token” → 选 scope(建议限制为仅当前项目)→ 复制生成的完整 token 字符串。
- 绝不要把 token 硬编码进
setup.py或pyproject.toml - 不要用
.pypirc明文存 token(哪怕设了 chmod 600,仍属高危) - 推荐用环境变量方式传递:
export TWINE_USERNAME=__token__+export TWINE_PASSWORD=pypi-abc123... - Windows 用户注意:PowerShell 中用
$env:TWINE_USERNAME="__token__",CMD 中用set TWINE_USERNAME=__token__
上传前必须构建 wheel 和 sdist 两种格式
只传 sdist(源码包)或只传 wheel(二进制包)都可能导致用户安装失败——比如 Windows 用户没装编译工具时无法从 sdist 构建,而某些平台又不支持预编译 wheel。PyPI 推荐同时上传两者,且顺序无关。
现代标准做法是用 build 工具替代旧式 python setup.py sdist bdist_wheel:
pip install --upgrade build python -m build
执行后会在 dist/ 目录下生成类似 mylib-0.1.0-py3-none-any.whl 和 mylib-0.1.0.tar.gz 的文件。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
build默认同时产出 wheel + sdist;加--sdist或--wheel可单独指定 - 确保
pyproject.toml中有[build-system]配置,否则build会 fallback 到 legacy 模式并报 warning - 上传命令始终用
twine upload dist/*,不要漏掉通配符*,否则只传一个文件
上传失败常见错误和对应检查点
twine upload 报错往往不是网络问题,而是包元数据或本地环境不合规。最常触发的三个错误:
-
HTTPError: 400 Bad Request→ 通常因name在 PyPI 已存在,或version格式非法(如含下划线、大写字母);检查pyproject.toml中[project].name是否全小写、连字符分隔,version是否符合 PEP 440(如0.1.0合法,0.1.0-dev需加devclassifier) -
InvalidDistribution: Cannot find .egg-info directory→ 说明build没成功,或项目根目录下没有pyproject.toml(或setup.py),导致无法识别为可构建项目 -
InvalidConfiguration: Missing 'username' and 'password'→ 环境变量未生效,或误用了twine upload --repository-url却没配--username/--password;优先用环境变量,避免命令行泄露 token
验证上传结果不能只看终端输出“100%”
终端显示 Uploading distributions to https://upload.pypi.org/legacy/ + 进度条走完 ≠ 包已可用。PyPI 有异步索引延迟,且上传后需人工审核是否违反政策(如含恶意代码、license 不明确等)。
真正确认成功的操作是:
- 打开
https://pypi.org/project/,看页面是否加载出 metadata、download files 列表是否包含你刚传的 wheel/sdist/ - 在干净虚拟环境中执行
pip install --index-url https://pypi.org/simple/ --no-deps,观察是否能拉取并解压成功(不加--no-deps可能因依赖未上传而失败,干扰判断) - 若页面 404 或 pip 报
Could not find a version that satisfies the requirement,大概率是包名拼写错误,或上传时用了twine upload --repository testpypi却忘了切回正式源
最容易被忽略的是:上传后首次访问 PyPI 页面可能缓存旧 404,强制刷新(Ctrl+F5)或换隐身窗口再试;另外,PyPI 不允许覆盖已上传的 version,哪怕删掉了也要换新 version 才能重传。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










