用途
本技能用于指导 Python 项目的打包与分发结构设计,目标是让项目具备可靠的依赖管理和可发布性。它围绕 pyproject.toml、src 布局、依赖管理以及发布工作流展开,适合需要将 Python 代码打包为可安装、可分发组件的场景。
主要能力
项目布局
推荐使用 src 布局:
my-project/
├── pyproject.toml
├── src/
│ └── my_package/
│ ├── __init__.py
│ ├── core.py
│ └── cli.py
├── tests/
│ ├── conftest.py
│ └── test_core.py
└── README.md
src 布局可防止从工作目录意外导入,强制先安装再测试,从而尽早发现打包错误。
对于内部工具或单仓库项目,也可使用扁平布局:
my-project/
├── pyproject.toml
├── my_package/
│ ├── __init__.py
│ └── core.py
└── tests/
pyproject.toml 配置
最小配置示例:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-package"
version = "0.1.0"
description = "A concise description"
requires-python = ">=3.11"
license = "MIT"
dependencies = [
"httpx>=0.27",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"ruff>=0.5",
"mypy>=1.10",
]
构建后端选择
- hatchling:默认选择,快速、配置少、对 monorepo 支持好。
- setuptools:适用于遗留项目、C 扩展或复杂构建需求。
- flit:适用于纯 Python、配置极简的简单项目。
- poetry-core:当使用 Poetry 进行依赖管理时选用。
可选依赖分组
按用途组织可选依赖:
[project.optional-dependencies]
dev = ["pytest>=8.0", "ruff>=0.5", "mypy>=1.10"]
docs = ["sphinx>=7.0", "myst-parser"]
dashboard = ["fastapi>=0.110", "uvicorn"]
metrics = ["prometheus-client"]
安装特定分组:pip install -e ".[dev,dashboard]"
入口点
控制台脚本:
[project.scripts]
my-cli = "my_package.cli:main"
插件入口点:
[project.entry-points."my_app.plugins"]
csv = "my_package.plugins.csv:CsvPlugin"
json = "my_package.plugins.json:JsonPlugin"
版本管理
单一版本来源:
# In pyproject.toml
[project]
dynamic = ["version"]
[tool.hatch.version]
path = "src/my_package/__init__.py"
# In __init__.py
__version__ = "0.1.0"
对于基础设施类包,可使用 CalVer:
__version__ = "2026.03.1" # YYYY.MM.patch
依赖锁定策略
- 库:使用宽松边界(>=1.0,<2.0),在 pyproject.toml 中声明。
- 应用:使用精确锁定,通过 pip-compile 或 uv lock 生成。
- CI:使用锁定文件,如 uv.lock 或 requirements.txt。
生成锁定文件:
# Using uv (recommended)
uv pip compile pyproject.toml -o requirements.txt
uv pip compile pyproject.toml --extra dev -o requirements-dev.txt
# Using pip-tools
pip-compile pyproject.toml -o requirements.txt
可编辑安装
# Standard editable install
pip install -e .
# With dev dependencies
pip install -e ".[dev]"
# In a fresh venv
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
工具配置
Ruff:
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP"]
Pytest:
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
pythonpath = ["."]
Mypy:
[tool.mypy]
strict = true
python_version = "3.11"
发布
发布到 PyPI:
# Build
python -m build
# Upload (use trusted publishing when possible)
python -m twine upload dist/*
GitHub Actions 可信发布:
- uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
常见模式
命名空间包(多仓库共享命名空间):
# Repo A
src/organvm/engine/__init__.py
# Repo B
src/organvm/dashboard/__init__.py
使用隐式命名空间包(命名空间层级不放 init.py)。
条件依赖:
dependencies = [
"tomli>=2.0; python_version < '3.11'",
"typing-extensions>=4.0; python_version < '3.12'",
]
包数据:
[tool.hatch.build.targets.wheel]
packages = ["src/my_package"]
[tool.hatch.build.targets.wheel.force-include]
"assets" = "my_package/assets"
应避免的反模式
- 只有 setup.py 而没有 pyproject.toml:始终以 pyproject.toml 作为唯一配置来源。
- 在库中锁定精确版本:使用兼容范围以避免依赖冲突。
- 在测试中从项目根目录导入:使用 src 布局或确保可编辑安装。
- 多个版本来源:版本只保留在一个地方。
- 仅用 requirements.txt 作为依赖规范:使用 pyproject.toml,并从中生成锁定文件。
使用方式
本技能以模式与配置示例的形式提供,开发者可参照其中的布局、pyproject.toml 片段、命令和工具配置,应用到自己的 Python 项目中。具体使用步骤需结合项目实际情况调整。
适用场景
- 需要将 Python 代码打包为可分发库或应用。
- 需要统一管理依赖、可选依赖和锁定文件。
- 需要配置构建后端、入口点、版本来源和发布流程。
- 需要避免常见的打包反模式。
限制
资料未提供关于收费、价格、平台支持范围或具体效果保证的信息。本技能不涉及运行时性能或安全审计内容。