modern-python
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseModern Python
现代Python开发
Guide for modern Python tooling and best practices, based on trailofbits/cookiecutter-python.
基于trailofbits/cookiecutter-python的现代Python工具链与最佳实践指南。
When to Use This Skill
何时使用本技能
- Creating a new Python project or package
- Setting up configuration
pyproject.toml - Configuring development tools (linting, formatting, testing)
- Writing Python scripts with external dependencies
- Migrating from legacy tools (when user requests it)
- 创建新的Python项目或包
- 配置文件
pyproject.toml - 配置开发工具(代码检查、格式化、测试)
- 编写带有外部依赖的Python脚本
- 从旧版工具迁移(用户有相关需求时)
When NOT to Use This Skill
何时不使用本技能
- User wants to keep legacy tooling: Respect existing workflows if explicitly requested
- Python < 3.11 required: These tools target modern Python
- Non-Python projects: Mixed codebases where Python isn't primary
- 用户希望保留旧版工具链:若用户明确要求,需尊重现有工作流
- 需要支持Python < 3.11:这些工具仅针对现代Python版本
- 非Python主导的项目:Python并非核心语言的混合代码库
Anti-Patterns to Avoid
需避免的反模式
| Avoid | Use Instead |
|---|---|
| |
| |
| Editing pyproject.toml manually to add deps | |
| |
| Poetry | uv (faster, simpler, better ecosystem integration) |
| requirements.txt | PEP 723 for scripts, pyproject.toml for projects |
| mypy / pyright | ty (faster, from Astral team) |
| |
Manual virtualenv activation ( | |
| pre-commit | prek (faster, no Python runtime needed) |
Key principles:
- Always use and
uv addto manage dependenciesuv remove - Never manually activate or manage virtual environments—use for all commands
uv run - Use for dev/test/docs dependencies, not
[dependency-groups][project.optional-dependencies]
| 需避免 | 推荐替代方案 |
|---|---|
| |
| |
| 手动编辑pyproject.toml添加依赖 | |
| |
| Poetry | uv(速度更快、更简洁、生态集成更好) |
| requirements.txt | 脚本使用PEP 723,项目使用pyproject.toml |
| mypy / pyright | ty(速度更快,由Astral团队开发) |
使用 | |
手动激活虚拟环境( | |
| pre-commit | prek(速度更快,无需Python运行时) |
核心原则:
- 始终使用和
uv add管理依赖uv remove - 绝不手动激活或管理虚拟环境——所有命令均使用执行
uv run - 开发/测试/文档依赖使用,而非
[dependency-groups][project.optional-dependencies]
Decision Tree
决策树
What are you doing?
│
├─ Single-file script with dependencies?
│ └─ Use PEP 723 inline metadata (./references/pep723-scripts.md)
│
├─ New multi-file project (not distributed)?
│ └─ Minimal uv setup (see Quick Start below)
│
├─ New reusable package/library?
│ └─ Full project setup (see Full Setup below)
│
└─ Migrating existing project?
└─ See Migration Guide below你正在做什么?
│
├─ 编写带依赖的单文件脚本?
│ └─ 使用PEP 723内联元数据(./references/pep723-scripts.md)
│
├─ 创建新的多文件项目(无需分发)?
│ └─ 极简uv配置(见下方快速开始)
│
├─ 创建可复用的包/库?
│ └─ 完整项目配置(见下方完整设置)
│
└─ 迁移现有项目?
└─ 见下方迁移指南Tool Overview
工具概览
| Tool | Purpose | Replaces |
|---|---|---|
| uv | Package/dependency management | pip, virtualenv, pip-tools, pipx, pyenv |
| ruff | Linting AND formatting | flake8, black, isort, pyupgrade, pydocstyle |
| ty | Type checking | mypy, pyright (faster alternative) |
| pytest | Testing with coverage | unittest |
| prek | Pre-commit hooks (setup) | pre-commit (faster, Rust-native) |
| 工具 | 用途 | 替代工具 |
|---|---|---|
| uv | 包/依赖管理 | pip、virtualenv、pip-tools、pipx、pyenv |
| ruff | 代码检查+格式化 | flake8、black、isort、pyupgrade、pydocstyle |
| ty | 类型检查 | mypy、pyright(更快的替代方案) |
| pytest | 带覆盖率统计的测试 | unittest |
| prek | 预提交钩子(配置) | pre-commit(速度更快,基于Rust开发) |
Security Tools
安全工具
| Tool | Purpose | When It Runs |
|---|---|---|
| shellcheck | Shell script linting | pre-commit |
| detect-secrets | Secret detection | pre-commit |
| actionlint | Workflow syntax validation | pre-commit, CI |
| zizmor | Workflow security audit | pre-commit, CI |
| pip-audit | Dependency vulnerability scanning | CI, manual |
| Dependabot | Automated dependency updates | scheduled |
See security-setup.md for configuration and usage.
| 工具 | 用途 | 运行时机 |
|---|---|---|
| shellcheck | Shell脚本检查 | 预提交阶段 |
| detect-secrets | 敏感信息检测 | 预提交阶段 |
| actionlint | 工作流语法验证 | 预提交阶段、CI流程 |
| zizmor | 工作流安全审计 | 预提交阶段、CI流程 |
| pip-audit | 依赖漏洞扫描 | CI流程、手动执行 |
| Dependabot | 依赖自动更新 | 定时执行 |
配置与使用方法见security-setup.md。
Quick Start: Minimal Project
快速开始:极简项目
For simple multi-file projects not intended for distribution:
bash
undefined适用于无需分发的简单多文件项目:
bash
undefinedCreate project with uv
使用uv创建项目
uv init myproject
cd myproject
uv init myproject
cd myproject
Add dependencies
添加依赖
uv add requests rich
uv add requests rich
Add dev dependencies
添加开发依赖
uv add --group dev pytest ruff ty
uv add --group dev pytest ruff ty
Run code
运行代码
uv run python src/myproject/main.py
uv run python src/myproject/main.py
Run tools
运行工具
uv run pytest
uv run ruff check .
undefineduv run pytest
uv run ruff check .
undefinedFull Project Setup
完整项目设置
If starting from scratch, ask the user if they prefer to use the Trail of Bits cookiecutter template to bootstrap a complete project with already preconfigured tooling.
bash
uvx cookiecutter gh:trailofbits/cookiecutter-python如果从零开始,可询问用户是否希望使用Trail of Bits的cookiecutter模板快速搭建已预配置好工具链的完整项目。
bash
uvx cookiecutter gh:trailofbits/cookiecutter-python1. Create Project Structure
1. 创建项目结构
bash
uv init --package myproject
cd myprojectThis creates:
myproject/
├── pyproject.toml
├── README.md
├── src/
│ └── myproject/
│ └── __init__.py
└── .python-versionbash
uv init --package myproject
cd myproject此命令会创建以下结构:
myproject/
├── pyproject.toml
├── README.md
├── src/
│ └── myproject/
│ └── __init__.py
└── .python-version2. Configure pyproject.toml
2. 配置pyproject.toml
See pyproject.md for complete configuration reference.
Key sections:
toml
[project]
name = "myproject"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = []
[dependency-groups]
dev = [{include-group = "lint"}, {include-group = "test"}, {include-group = "audit"}]
lint = ["ruff", "ty"]
test = ["pytest", "pytest-cov"]
audit = ["pip-audit"]
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["ALL"]
ignore = ["D", "COM812", "ISC001"]
[tool.pytest]
addopts = ["--cov=myproject", "--cov-fail-under=80"]
[tool.ty.terminal]
error-on-warning = true
[tool.ty.environment]
python-version = "3.11"
[tool.ty.rules]完整配置参考见pyproject.md。
核心配置段:
toml
[project]
name = "myproject"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = []
[dependency-groups]
dev = [{include-group = "lint"}, {include-group = "test"}, {include-group = "audit"}]
lint = ["ruff", "ty"]
test = ["pytest", "pytest-cov"]
audit = ["pip-audit"]
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["ALL"]
ignore = ["D", "COM812", "ISC001"]
[tool.pytest]
addopts = ["--cov=myproject", "--cov-fail-under=80"]
[tool.ty.terminal]
error-on-warning = true
[tool.ty.environment]
python-version = "3.11"
[tool.ty.rules]Strict from day 1 for new projects
新项目从第一天起启用严格模式
possibly-unresolved-reference = "error"
unused-ignore-comment = "warn"
undefinedpossibly-unresolved-reference = "error"
unused-ignore-comment = "warn"
undefined3. Install Dependencies
3. 安装依赖
bash
undefinedbash
undefinedInstall all dependency groups
安装所有依赖组
uv sync --all-groups
uv sync --all-groups
Or install specific groups
或安装指定依赖组
uv sync --group dev
undefineduv sync --group dev
undefined4. Add Makefile
4. 添加Makefile
makefile
.PHONY: dev lint format test build
dev:
uv sync --all-groups
lint:
uv run ruff format --check && uv run ruff check && uv run ty check src/
format:
uv run ruff format .
test:
uv run pytest
build:
uv buildmakefile
.PHONY: dev lint format test build
dev:
uv sync --all-groups
lint:
uv run ruff format --check && uv run ruff check && uv run ty check src/
format:
uv run ruff format .
test:
uv run pytest
build:
uv buildMigration Guide
迁移指南
When a user requests migration from legacy tooling:
当用户要求从旧版工具链迁移时:
From requirements.txt + pip
从requirements.txt + pip迁移
First, determine the nature of the code:
For standalone scripts: Convert to PEP 723 inline metadata (see pep723-scripts.md)
For projects:
bash
undefined首先确定代码类型:
独立脚本:转换为PEP 723内联元数据(见pep723-scripts.md)
项目:
bash
undefinedInitialize uv in existing project
在现有项目中初始化uv
uv init --bare
uv init --bare
Add dependencies using uv (not by editing pyproject.toml)
使用uv添加依赖(不要手动编辑pyproject.toml)
uv add requests rich # add each package
uv add requests rich # 逐个添加包
Or import from requirements.txt (review each package before adding)
或从requirements.txt导入(添加前需审核每个包)
Note: Complex version specifiers may need manual handling
注意:复杂版本声明可能需要手动处理
grep -v '^#' requirements.txt | grep -v '^-' | grep -v '^\s*$' | while read -r pkg; do
uv add "$pkg" || echo "Failed to add: $pkg"
done
uv sync
Then:
1. Delete `requirements.txt`, `requirements-dev.txt`
2. Delete virtual environment (`venv/`, `.venv/`)
3. Add `uv.lock` to version controlgrep -v '^#' requirements.txt | grep -v '^-' | grep -v '^\s*$' | while read -r pkg; do
uv add "$pkg" || echo "添加失败: $pkg"
done
uv sync
后续步骤:
1. 删除`requirements.txt`、`requirements-dev.txt`
2. 删除虚拟环境(`venv/`、`.venv/`)
3. 将`uv.lock`加入版本控制From setup.py / setup.cfg
从setup.py / setup.cfg迁移
- Run to create pyproject.toml
uv init --bare - Use to add each dependency from
uv addinstall_requires - Use for dev dependencies
uv add --group dev - Copy non-dependency metadata (name, version, description, etc.) to
[project] - Delete ,
setup.py,setup.cfgMANIFEST.in
- 运行创建pyproject.toml
uv init --bare - 使用添加
uv add中的每个依赖install_requires - 使用添加开发依赖
uv add --group dev - 将非依赖元数据(名称、版本、描述等)复制到段
[project] - 删除、
setup.py、setup.cfgMANIFEST.in
From flake8 + black + isort
从flake8 + black + isort迁移
- Remove flake8, black, isort via
uv remove - Delete ,
.flake8,pyproject.toml [tool.black]configs[tool.isort] - Add ruff:
uv add --group dev ruff - Add ruff configuration (see ruff-config.md)
- Run to apply fixes
uv run ruff check --fix . - Run to format
uv run ruff format .
- 通过移除flake8、black、isort
uv remove - 删除、
.flake8中的pyproject.toml、[tool.black]配置[tool.isort] - 添加ruff:
uv add --group dev ruff - 添加ruff配置(见ruff-config.md)
- 运行自动修复问题
uv run ruff check --fix . - 运行格式化代码
uv run ruff format .
From mypy / pyright
从mypy / pyright迁移
- Remove mypy/pyright via
uv remove - Delete ,
mypy.ini, orpyrightconfig.json/[tool.mypy]sections[tool.pyright] - Add ty:
uv add --group dev ty - Run
uv run ty check src/
- 通过移除mypy/pyright
uv remove - 删除、
mypy.ini或pyrightconfig.json中的pyproject.toml/[tool.mypy]段[tool.pyright] - 添加ty:
uv add --group dev ty - 运行
uv run ty check src/
Quick Reference: uv Commands
速查:uv命令
| Command | Description |
|---|---|
| Create new project |
| Create distributable package |
| Add dependency |
| Add to dependency group |
| Remove dependency |
| Install dependencies |
| Install all dependency groups |
| Run command in venv |
| Run with temporary dependency |
| Build package |
| Publish to PyPI |
| 命令 | 描述 |
|---|---|
| 创建新项目 |
| 创建可分发的包 |
| 添加依赖 |
| 添加到开发依赖组 |
| 移除依赖 |
| 安装依赖 |
| 安装所有依赖组 |
| 在虚拟环境中运行命令 |
| 临时添加依赖并运行命令 |
| 构建包 |
| 发布到PyPI |
Ad-hoc Dependencies with --with
--with使用--with
临时添加依赖
--withUse for one-off commands that need packages not in your project:
uv run --withbash
undefined对于需要项目外依赖的一次性命令,使用:
uv run --withbash
undefinedRun Python with a temporary package
临时添加依赖并运行Python
uv run --with requests python -c "import requests; print(requests.get('https://httpbin.org/ip').json())"
uv run --with requests python -c "import requests; print(requests.get('https://httpbin.org/ip').json())"
Run a module with temporary deps
临时添加依赖并运行模块
uv run --with rich python -m rich.progress
uv run --with rich python -m rich.progress
Multiple packages
多个临时依赖
uv run --with requests --with rich python script.py
uv run --with requests --with rich python script.py
Combine with project deps (adds to existing venv)
结合项目依赖运行(添加到现有虚拟环境)
uv run --with httpx pytest # project deps + httpx
**When to use `--with` vs `uv add`:**
- `uv add`: Package is a project dependency (goes in pyproject.toml/uv.lock)
- `--with`: One-off usage, testing, or scripts outside a project context
See [uv-commands.md](./references/uv-commands.md) for complete reference.uv run --with httpx pytest # 项目依赖 + httpx
**`--with`与`uv add`的使用场景区分:**
- `uv add`:包是项目的正式依赖(会写入pyproject.toml/uv.lock)
- `--with`:一次性使用、测试或项目外脚本场景
完整命令参考见[uv-commands.md](./references/uv-commands.md)。Quick Reference: Dependency Groups
速查:依赖组
toml
[dependency-groups]
dev = ["ruff", "ty"]
test = ["pytest", "pytest-cov", "hypothesis"]
docs = ["sphinx", "myst-parser"]Install with:
uv sync --group dev --group testtoml
[dependency-groups]
dev = ["ruff", "ty"]
test = ["pytest", "pytest-cov", "hypothesis"]
docs = ["sphinx", "myst-parser"]安装命令:
uv sync --group dev --group testBest Practices Checklist
最佳实践检查清单
- Use layout for packages
src/ - Set
requires-python = ">=3.11" - Configure ruff with and explicit ignores
select = ["ALL"] - Use ty for type checking
- Enforce test coverage minimum (80%+)
- Use dependency groups instead of extras for dev tools
- Add to version control
uv.lock - Use PEP 723 for standalone scripts
- 包使用目录结构
src/ - 设置
requires-python = ">=3.11" - 配置ruff时设置并显式忽略规则
select = ["ALL"] - 使用ty进行类型检查
- 强制设置测试覆盖率最小值(80%+)
- 开发工具使用依赖组而非额外依赖
- 将加入版本控制
uv.lock - 独立脚本使用PEP 723
Read Next
延伸阅读
- migration-checklist.md - Step-by-step migration cleanup
- pyproject.md - Complete pyproject.toml reference
- uv-commands.md - uv command reference
- ruff-config.md - Ruff linting/formatting configuration
- testing.md - pytest and coverage setup
- pep723-scripts.md - PEP 723 inline script metadata
- prek.md - Fast pre-commit hooks with prek
- security-setup.md - Security hooks and dependency scanning
- dependabot.md - Automated dependency updates
- migration-checklist.md - 分步迁移清理指南
- pyproject.md - 完整pyproject.toml参考
- uv-commands.md - uv命令参考
- ruff-config.md - Ruff检查/格式化配置
- testing.md - pytest与覆盖率设置
- pep723-scripts.md - PEP 723脚本内联元数据
- prek.md - 使用prek实现快速预提交钩子
- security-setup.md - 安全钩子与依赖扫描
- dependabot.md - 依赖自动更新