modern-python

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Modern 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
    pyproject.toml
    configuration
  • 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

需避免的反模式

AvoidUse Instead
[tool.ty]
python-version
[tool.ty.environment]
python-version
uv pip install
uv add
and
uv sync
Editing pyproject.toml manually to add deps
uv add <pkg>
/
uv remove <pkg>
hatchling
build backend
uv_build
(simpler, sufficient for most cases)
Poetryuv (faster, simpler, better ecosystem integration)
requirements.txtPEP 723 for scripts, pyproject.toml for projects
mypy / pyrightty (faster, from Astral team)
[project.optional-dependencies]
for dev tools
[dependency-groups]
(PEP 735)
Manual virtualenv activation (
source .venv/bin/activate
)
uv run <cmd>
pre-commitprek (faster, no Python runtime needed)
Key principles:
  • Always use
    uv add
    and
    uv remove
    to manage dependencies
  • Never manually activate or manage virtual environments—use
    uv run
    for all commands
  • Use
    [dependency-groups]
    for dev/test/docs dependencies, not
    [project.optional-dependencies]
需避免推荐替代方案
[tool.ty]
python-version
[tool.ty.environment]
python-version
uv pip install
uv add
uv sync
手动编辑pyproject.toml添加依赖
uv add <pkg>
/
uv remove <pkg>
hatchling
构建后端
uv_build
(更简洁,满足大多数场景需求)
Poetryuv(速度更快、更简洁、生态集成更好)
requirements.txt脚本使用PEP 723,项目使用pyproject.toml
mypy / pyrightty(速度更快,由Astral团队开发)
使用
[project.optional-dependencies]
管理开发工具
[dependency-groups]
(符合PEP 735标准)
手动激活虚拟环境(
source .venv/bin/activate
uv run <cmd>
pre-commitprek(速度更快,无需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

工具概览

ToolPurposeReplaces
uvPackage/dependency managementpip, virtualenv, pip-tools, pipx, pyenv
ruffLinting AND formattingflake8, black, isort, pyupgrade, pydocstyle
tyType checkingmypy, pyright (faster alternative)
pytestTesting with coverageunittest
prekPre-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

安全工具

ToolPurposeWhen It Runs
shellcheckShell script lintingpre-commit
detect-secretsSecret detectionpre-commit
actionlintWorkflow syntax validationpre-commit, CI
zizmorWorkflow security auditpre-commit, CI
pip-auditDependency vulnerability scanningCI, manual
DependabotAutomated dependency updatesscheduled
See security-setup.md for configuration and usage.
工具用途运行时机
shellcheckShell脚本检查预提交阶段
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
undefined

Create 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 .
undefined
uv run pytest uv run ruff check .
undefined

Full 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-python

1. Create Project Structure

1. 创建项目结构

bash
uv init --package myproject
cd myproject
This creates:
myproject/
├── pyproject.toml
├── README.md
├── src/
│   └── myproject/
│       └── __init__.py
└── .python-version
bash
uv init --package myproject
cd myproject
此命令会创建以下结构:
myproject/
├── pyproject.toml
├── README.md
├── src/
│   └── myproject/
│       └── __init__.py
└── .python-version

2. 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"
undefined
possibly-unresolved-reference = "error" unused-ignore-comment = "warn"
undefined

3. Install Dependencies

3. 安装依赖

bash
undefined
bash
undefined

Install all dependency groups

安装所有依赖组

uv sync --all-groups
uv sync --all-groups

Or install specific groups

或安装指定依赖组

uv sync --group dev
undefined
uv sync --group dev
undefined

4. 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 build
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 build

Migration 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
undefined

Initialize 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 control
grep -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迁移

  1. Run
    uv init --bare
    to create pyproject.toml
  2. Use
    uv add
    to add each dependency from
    install_requires
  3. Use
    uv add --group dev
    for dev dependencies
  4. Copy non-dependency metadata (name, version, description, etc.) to
    [project]
  5. Delete
    setup.py
    ,
    setup.cfg
    ,
    MANIFEST.in
  1. 运行
    uv init --bare
    创建pyproject.toml
  2. 使用
    uv add
    添加
    install_requires
    中的每个依赖
  3. 使用
    uv add --group dev
    添加开发依赖
  4. 将非依赖元数据(名称、版本、描述等)复制到
    [project]
  5. 删除
    setup.py
    setup.cfg
    MANIFEST.in

From flake8 + black + isort

从flake8 + black + isort迁移

  1. Remove flake8, black, isort via
    uv remove
  2. Delete
    .flake8
    ,
    pyproject.toml [tool.black]
    ,
    [tool.isort]
    configs
  3. Add ruff:
    uv add --group dev ruff
  4. Add ruff configuration (see ruff-config.md)
  5. Run
    uv run ruff check --fix .
    to apply fixes
  6. Run
    uv run ruff format .
    to format
  1. 通过
    uv remove
    移除flake8、black、isort
  2. 删除
    .flake8
    pyproject.toml
    中的
    [tool.black]
    [tool.isort]
    配置
  3. 添加ruff:
    uv add --group dev ruff
  4. 添加ruff配置(见ruff-config.md
  5. 运行
    uv run ruff check --fix .
    自动修复问题
  6. 运行
    uv run ruff format .
    格式化代码

From mypy / pyright

从mypy / pyright迁移

  1. Remove mypy/pyright via
    uv remove
  2. Delete
    mypy.ini
    ,
    pyrightconfig.json
    , or
    [tool.mypy]
    /
    [tool.pyright]
    sections
  3. Add ty:
    uv add --group dev ty
  4. Run
    uv run ty check src/
  1. 通过
    uv remove
    移除mypy/pyright
  2. 删除
    mypy.ini
    pyrightconfig.json
    pyproject.toml
    中的
    [tool.mypy]
    /
    [tool.pyright]
  3. 添加ty:
    uv add --group dev ty
  4. 运行
    uv run ty check src/

Quick Reference: uv Commands

速查:uv命令

CommandDescription
uv init
Create new project
uv init --package
Create distributable package
uv add <pkg>
Add dependency
uv add --group dev <pkg>
Add to dependency group
uv remove <pkg>
Remove dependency
uv sync
Install dependencies
uv sync --all-groups
Install all dependency groups
uv run <cmd>
Run command in venv
uv run --with <pkg> <cmd>
Run with temporary dependency
uv build
Build package
uv publish
Publish to PyPI
命令描述
uv init
创建新项目
uv init --package
创建可分发的包
uv add <pkg>
添加依赖
uv add --group dev <pkg>
添加到开发依赖组
uv remove <pkg>
移除依赖
uv sync
安装依赖
uv sync --all-groups
安装所有依赖组
uv run <cmd>
在虚拟环境中运行命令
uv run --with <pkg> <cmd>
临时添加依赖并运行命令
uv build
构建包
uv publish
发布到PyPI

Ad-hoc Dependencies with
--with

使用
--with
临时添加依赖

Use
uv run --with
for one-off commands that need packages not in your project:
bash
undefined
对于需要项目外依赖的一次性命令,使用
uv run --with
bash
undefined

Run 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 test
toml
[dependency-groups]
dev = ["ruff", "ty"]
test = ["pytest", "pytest-cov", "hypothesis"]
docs = ["sphinx", "myst-parser"]
安装命令:
uv sync --group dev --group test

Best Practices Checklist

最佳实践检查清单

  • Use
    src/
    layout for packages
  • Set
    requires-python = ">=3.11"
  • Configure ruff with
    select = ["ALL"]
    and explicit ignores
  • Use ty for type checking
  • Enforce test coverage minimum (80%+)
  • Use dependency groups instead of extras for dev tools
  • Add
    uv.lock
    to version control
  • 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 - 依赖自动更新