Python包开发与发布:使用 build 与 twine(含 project.scripts 示例)
本文面向有一定 Python 基础、希望将代码规范化为可安装包并发布到 PyPI 的工程师。你将学会:
- 如何创建标准的 Python 包工程骨架(src 布局)
- 在
pyproject.toml中使用 PEP 621 声明元数据与project.scripts生成命令行脚本 - 使用
build本地构建分发产物(sdist/wheel) - 使用
twine校验并上传到 TestPyPI 与 PyPI - 常见问题与排错要点
参考标准:PEP 517/518(构建系统),PEP 621(项目元数据)。
适用环境
- Python ≥ 3.8(推荐 3.10+)
- macOS/Linux/Windows
- 包管理:
pip或pipx
一、项目骨架(src 布局)
推荐使用「src 布局」以避免导入歧义,目录结构如下:
1 | mycli/ |
src/mycli:包代码根目录cli.py:命令行入口逻辑(将通过project.scripts暴露为命令)__main__.py:支持python -m mycli直接运行pyproject.toml:声明构建系统与项目元数据(PEP 621)
二、编写包代码(示例:命令行工具)
所有代码与注释统一使用英文(便于社区协作与审核)。
src/mycli/cli.py
1 | import argparse |
src/mycli/__init__.py
1 | __all__ = ["__version__"] |
src/mycli/__main__.py
1 | from .cli import main |
三、pyproject.toml(PEP 621 + project.scripts)
示例使用 setuptools 作为构建后端,启用 PEP 621 元数据与 project.scripts:
1 | [build-system] |
要点:
project.scripts将mycli命令映射到mycli.cli:main- 采用
src布局需设置package-dir与packages.find.where - 设置
requires-python与classifiers便于用户检索与兼容性声明
四、README 与 LICENSE
README.md作为包主页与长描述,需简要说明安装与用法- 许可证建议选择常见的开源协议(如 MIT/Apache-2.0)
README.md 示例:
1 | # mycli-example |
Usage
1 | mycli --name Alice |
1 |
|
执行构建:
1 | python -m build |
构建检查:
1 | twine check dist/* |
六、发布到 TestPyPI 与 PyPI
强烈建议先在 TestPyPI 验证再发布至 PyPI。
方式 A:使用 .pypirc 管理凭据(推荐)
创建 ~/.pypirc(macOS/Linux):
1 | [distutils] |
上传到 TestPyPI:
1 | twine upload -r testpypi dist/* |
验证安装(注意使用 TestPyPI 索引):
1 | python -m pip install --index-url https://test.pypi.org/simple --extra-index-url https://pypi.org/simple mycli-example |
确认无误后,上传至 PyPI:
1 | twine upload -r pypi dist/* |
方式 B:直接指定仓库 URL(无需 .pypirc)
1 | twine upload --repository-url https://test.pypi.org/legacy/ dist/* |
凭据将通过交互提示或环境变量读取(CI 中建议使用环境变量/密文)。
七、使用与验证
安装后应具备两种使用方式:
1 | # 1) 通过脚本(来自 project.scripts) |
八、常见问题与排错
- File already exists(重复版本):PyPI 不允许覆盖同版本;升级
version(如 0.1.1)并重新构建上传 - Invalid long_description:
twine check失败,多为 README 渲染问题;将readme = "README.md"并确保 Markdown 合规 - Script not found:检查
project.scripts的目标路径是否正确(mycli.cli:main)且包已包含在构建中(packages.find设置) - ImportError after install:多因未使用 src 布局或测试时在项目根运行导致导入到源码;建议在全新 venv 中验证
- 401/403 授权失败:确认使用
__token__用户名与有效 PyPI Token;避免泄露令牌(使用 CI 密文) - Wheel 缺少文件:确认未被
MANIFEST.in/忽略规则误排除;或切换到现代 PEP 621 配置并避免遗留 setup.cfg 混用
九、在 CI 中自动发布(可选思路)
- 在 GitHub Actions/其他 CI 中使用发布工作流
- 构建步骤同本地:
python -m build→twine check→twine upload - 凭据使用仓库密文(如
PYPI_API_TOKEN),并在 CI 步骤设置为环境变量
官方参考:
- Packaging User Guide(构建/发布):Packaging Guide
- PyPI(上传与凭据):Publishing packages
十、总结
- 使用 PEP 621 在
pyproject.toml声明元数据,结合project.scripts生成命令行 - 用
build统一构建 sdist/wheel,twine校验与上传 - 先 TestPyPI 验证,再发布至 PyPI
- 采用 src 布局、明确 Python 版本与分类器,提升可维护性与可发现性
本文由 AI 辅助生成,如有错误或建议,欢迎指出。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Michael Blog!
评论




