modern-python
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseModern Python Skill
现代Python工具链实践
<!-- Agent: evolution-orchestrator | Task: #2 | Session: 2026-02-21 -->
<!-- License: CC-BY-SA-4.0 | Source: Trail of Bits (github.com/trailofbits/skills) -->
<!-- Attribution: Adapted from Trail of Bits modern-python skill and trailofbits/cookiecutter-python -->
<identity>
Modern Python tooling skill adapted from Trail of Bits coding standards. Mandates the use of uv (package management), ruff (linting and formatting), ty (type checking), and pytest (testing) as the standard Python toolchain. Based on patterns from trailofbits/cookiecutter-python for consistent, high-quality Python projects.
</identity>
<capabilities>
- Project initialization with modern Python toolchain (uv + ruff + ty + pytest)
- Migration from legacy tools (pip/Poetry/pipenv to uv, black/flake8/isort to ruff, mypy to ty)
- pyproject.toml configuration for all tools (single source of truth)
- Dependency management with uv (lock files, dependency groups, virtual environments)
- Linting and formatting with ruff (replaces flake8, isort, black, pyflakes, pycodestyle)
- Type checking with ty (Rust-based, faster than mypy)
- Testing with pytest, pytest-cov, and hypothesis
- CI/CD configuration with GitHub Actions
- Dependabot setup for automated dependency updates
- Pre-commit hook configuration
</capabilities>
<!-- Agent: evolution-orchestrator | Task: #2 | Session: 2026-02-21 -->
<!-- License: CC-BY-SA-4.0 | Source: Trail of Bits (github.com/trailofbits/skills) -->
<!-- Attribution: Adapted from Trail of Bits modern-python skill and trailofbits/cookiecutter-python -->
<identity>
基于Trail of Bits编码标准适配的现代Python工具链实践。强制使用uv(包管理)、ruff(代码检查与格式化)、ty(类型校验)和pytest(测试)作为标准Python工具链。基于trailofbits/cookiecutter-python的模式,用于构建一致、高质量的Python项目。
</identity>
<capabilities>
- 基于现代Python工具链(uv + ruff + ty + pytest)初始化项目
- 从传统工具链迁移(pip/Poetry/pipenv 迁移至 uv,black/flake8/isort 迁移至 ruff,mypy 迁移至 ty)
- 为所有工具配置pyproject.toml(单一可信源)
- 使用uv进行依赖管理(锁文件、依赖组、虚拟环境)
- 使用ruff进行代码检查与格式化(替代flake8、isort、black、pyflakes、pycodestyle)
- 使用ty进行类型校验(基于Rust,比mypy更快)
- 使用pytest、pytest-cov和hypothesis进行测试
- 配置GitHub Actions实现CI/CD
- 配置Dependabot实现依赖自动更新
- 配置预提交钩子
</capabilities>
Overview
概述
This skill implements Trail of Bits' modern Python coding standards for the agent-studio framework. The core philosophy is: use Rust-based tools for faster feedback loops, especially when working with AI agents. Every tool in this stack (uv, ruff, ty) is written in Rust and provides sub-second execution times, enabling tight iteration cycles.
Source repository:
Template:
License: CC-BY-SA-4.0
https://github.com/trailofbits/skillshttps://github.com/trailofbits/cookiecutter-python本实践为agent-studio框架实现了Trail of Bits的现代Python编码标准。核心理念是:使用基于Rust的工具以实现更快的反馈循环,尤其是在与AI Agent协作时。该工具栈中的每一个工具(uv、ruff、ty)均基于Rust开发,执行时间可达亚秒级,支持高效的迭代周期。
源码仓库:
模板:
许可证:CC-BY-SA-4.0
https://github.com/trailofbits/skillshttps://github.com/trailofbits/cookiecutter-pythonWhen to Use
适用场景
- When creating new Python projects from scratch
- When migrating Python projects from legacy tooling
- When setting up CI/CD pipelines for Python projects
- When standardizing Python tooling across a team
- When writing standalone Python scripts that need proper structure
- When an AI agent needs fast feedback from Python tooling
- 从零开始创建新Python项目时
- 将Python项目从传统工具链迁移时
- 为Python项目搭建CI/CD流水线时
- 在团队内标准化Python工具链时
- 编写需要规范结构的独立Python脚本时
- AI Agent需要从Python工具链获取快速反馈时
Iron Law
铁律
ALL PYTHON TOOLING CONFIGURED IN pyproject.toml — NO SEPARATE CONFIG FILESpyproject.tomlsetup.cfg.flake8mypy.iniblack.toml所有Python工具配置均需写入pyproject.toml — 禁止使用单独的配置文件pyproject.tomlsetup.cfg.flake8mypy.iniblack.tomlThe Modern Python Stack
现代Python工具栈
| Tool | Replaces | Purpose | Speed |
|---|---|---|---|
| uv | pip, Poetry, pipenv, pip-tools | Package & project management | 10-100x faster |
| ruff | flake8, isort, black, pyflakes, pycodestyle, pydocstyle | Linting + formatting | 10-100x faster |
| ty | mypy, pyright, pytype | Type checking | 5-10x faster |
| pytest | unittest | Testing | -- |
| hypothesis | (manual property tests) | Property-based testing | -- |
| 工具 | 替代工具 | 用途 | 速度 |
|---|---|---|---|
| uv | pip、Poetry、pipenv、pip-tools | 包与项目管理 | 快10-100倍 |
| ruff | flake8、isort、black、pyflakes、pycodestyle、pydocstyle | 代码检查 + 格式化 | 快10-100倍 |
| ty | mypy、pyright、pytype | 类型校验 | 快5-10倍 |
| pytest | unittest | 测试 | -- |
| hypothesis | (手动属性测试) | 基于属性的测试 | -- |
Project Setup
项目搭建
New Project
新项目
bash
undefinedbash
undefinedCreate new project with uv
使用uv创建新项目
uv init my-project
cd my-project
uv init my-project
cd my-project
Add dependency groups
添加依赖组
uv add --group dev ruff ty
uv add --group test pytest pytest-cov hypothesis
uv add --group docs sphinx myst-parser
uv add --group dev ruff ty
uv add --group test pytest pytest-cov hypothesis
uv add --group docs sphinx myst-parser
Install all dependencies
安装所有依赖
uv sync --all-groups
undefineduv sync --all-groups
undefinedpyproject.toml Configuration
pyproject.toml配置
toml
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []
[dependency-groups]
dev = ["ruff", "ty"]
test = ["pytest", "pytest-cov", "hypothesis"]
docs = ["sphinx", "myst-parser"]toml
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []
[dependency-groups]
dev = ["ruff", "ty"]
test = ["pytest", "pytest-cov", "hypothesis"]
docs = ["sphinx", "myst-parser"]=== Ruff Configuration ===
=== Ruff配置 ===
[tool.ruff]
target-version = "py312"
line-length = 100
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"N", # pep8-naming
"UP", # pyupgrade
"B", # flake8-bugbear
"A", # flake8-builtins
"C4", # flake8-comprehensions
"SIM", # flake8-simplify
"S", # flake8-bandit (security)
"TCH", # flake8-type-checking
"RUF", # ruff-specific rules
]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101"] # Allow assert in tests
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
[tool.ruff]
target-version = "py312"
line-length = 100
[tool.ruff.lint]
select = [
"E", # pycodestyle错误
"W", # pycodestyle警告
"F", # pyflakes
"I", # isort
"N", # pep8-naming
"UP", # pyupgrade
"B", # flake8-bugbear
"A", # flake8-builtins
"C4", # flake8-comprehensions
"SIM", # flake8-simplify
"S", # flake8-bandit(安全)
"TCH", # flake8-type-checking
"RUF", # ruff专属规则
]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101"] # 允许在测试中使用assert
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
=== Pytest Configuration ===
=== Pytest配置 ===
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = [
"--strict-markers",
"--strict-config",
"-ra",
]
[tool.coverage.run]
source = ["src"]
branch = true
[tool.coverage.report]
fail_under = 80
show_missing = true
exclude_lines = [
"if TYPE_CHECKING:",
"if name == .main.:",
]
undefined[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = [
"--strict-markers",
"--strict-config",
"-ra",
]
[tool.coverage.run]
source = ["src"]
branch = true
[tool.coverage.report]
fail_under = 80
show_missing = true
exclude_lines = [
"if TYPE_CHECKING:",
"if name == "main":",
]
undefinedDaily Workflow Commands
日常工作流命令
Package Management (uv)
包管理(uv)
bash
undefinedbash
undefinedAdd a dependency
添加依赖
uv add requests
uv add requests
Add a dev dependency
添加开发依赖
uv add --group dev ipdb
uv add --group dev ipdb
Remove a dependency
移除依赖
uv remove requests
uv remove requests
Update all dependencies
更新所有依赖
uv lock --upgrade
uv lock --upgrade
Update a specific dependency
更新特定依赖
uv lock --upgrade-package requests
uv lock --upgrade-package requests
Run a script in the project environment
在项目环境中运行脚本
uv run python script.py
uv run python script.py
Run a tool (without installing globally)
运行工具(无需全局安装)
uv run --with httpie http GET https://api.example.com
undefineduv run --with httpie http GET https://api.example.com
undefinedLinting and Formatting (ruff)
代码检查与格式化(ruff)
bash
undefinedbash
undefinedCheck for lint errors
检查代码错误
uv run ruff check .
uv run ruff check .
Auto-fix lint errors
自动修复代码错误
uv run ruff check --fix .
uv run ruff check --fix .
Format code
格式化代码
uv run ruff format .
uv run ruff format .
Check formatting (dry run)
检查代码格式(试运行)
uv run ruff format --check .
uv run ruff format --check .
Check specific rules
检查特定规则
uv run ruff check --select S . # Security rules only
undefineduv run ruff check --select S . # 仅检查安全规则
undefinedType Checking (ty)
类型校验(ty)
bash
undefinedbash
undefinedRun type checker
运行类型校验
uv run ty check
uv run ty check
Check specific file
检查特定文件
uv run ty check src/main.py
undefineduv run ty check src/main.py
undefinedTesting (pytest)
测试(pytest)
bash
undefinedbash
undefinedRun all tests
运行所有测试
uv run pytest
uv run pytest
Run with coverage
运行测试并生成覆盖率报告
uv run pytest --cov
uv run pytest --cov
Run specific test file
运行特定测试文件
uv run pytest tests/test_auth.py
uv run pytest tests/test_auth.py
Run with verbose output
详细输出测试结果
uv run pytest -v
uv run pytest -v
Run and stop at first failure
遇到第一个测试失败时停止
uv run pytest -x
undefineduv run pytest -x
undefinedMigration Guide
迁移指南
From pip/requirements.txt
从pip/requirements.txt迁移
bash
undefinedbash
undefinedInstall uv
安装uv
curl -LsSf https://astral.sh/uv/install.sh | sh
curl -LsSf https://astral.sh/uv/install.sh | sh
Initialize project from existing requirements
从现有requirements初始化项目
uv init
uv add $(cat requirements.txt | grep -v '^#' | grep -v '^$')
uv init
uv add $(cat requirements.txt | grep -v '^#' | grep -v '^$')
Remove old files
删除旧文件
rm requirements.txt requirements-dev.txt
undefinedrm requirements.txt requirements-dev.txt
undefinedFrom Poetry
从Poetry迁移
bash
undefinedbash
undefineduv can read pyproject.toml with Poetry sections
uv可以读取包含Poetry配置段的pyproject.toml
uv init
uv init
Move Poetry dependencies to [project.dependencies]
将Poetry依赖移至[project.dependencies]
Move [tool.poetry.group.dev.dependencies] to [dependency-groups]
将[tool.poetry.group.dev.dependencies]移至[dependency-groups]
Remove [tool.poetry] section
移除[tool.poetry]配置段
uv sync
undefineduv sync
undefinedFrom flake8/black/isort to ruff
从flake8/black/isort迁移至ruff
bash
undefinedbash
undefinedRemove old tools
移除旧工具
uv remove flake8 black isort pyflakes pycodestyle
uv remove flake8 black isort pyflakes pycodestyle
Add ruff
添加ruff
uv add --group dev ruff
uv add --group dev ruff
Convert .flake8 config to ruff (manual)
手动将.flake8配置转换为ruff配置
ruff supports most flake8 rules with same codes
ruff支持大多数flake8规则,且规则代码一致
Remove old config files
删除旧配置文件
rm .flake8 .isort.cfg pyproject.toml.bak
undefinedrm .flake8 .isort.cfg pyproject.toml.bak
undefinedFrom mypy to ty
从mypy迁移至ty
bash
undefinedbash
undefinedRemove mypy
移除mypy
uv remove mypy
uv remove mypy
Add ty
添加ty
uv add --group dev ty
uv add --group dev ty
ty uses the same type annotation syntax as mypy
ty使用与mypy相同的类型注解语法
Most code requires no changes
大多数代码无需修改
undefinedundefinedCI/CD Configuration
CI/CD配置
GitHub Actions
GitHub Actions
yaml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Install dependencies
run: uv sync --all-groups
- name: Lint
run: uv run ruff check .
- name: Format check
run: uv run ruff format --check .
- name: Type check
run: uv run ty check
- name: Test
run: uv run pytest --cov --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: coverage.xmlyaml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Install dependencies
run: uv sync --all-groups
- name: Lint
run: uv run ruff check .
- name: Format check
run: uv run ruff format --check .
- name: Type check
run: uv run ty check
- name: Test
run: uv run pytest --cov --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: coverage.xmlDependabot Configuration
Dependabot配置
yaml
undefinedyaml
undefined.github/dependabot.yml
.github/dependabot.yml
version: 2
updates:
- package-ecosystem: 'uv' directory: '/' schedule: interval: 'weekly' groups: all: patterns: - '*'
undefinedversion: 2
updates:
- package-ecosystem: 'uv' directory: '/' schedule: interval: 'weekly' groups: all: patterns: - '*'
undefinedPre-commit Hooks
预提交钩子
yaml
undefinedyaml
undefined.pre-commit-config.yaml
.pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.0
hooks:
- id: ruff args: [--fix]
- id: ruff-format
undefinedrepos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.0
hooks:
- id: ruff args: [--fix]
- id: ruff-format
undefinedCode Patterns
代码模式
Type Annotations
类型注解
python
from __future__ import annotations
from collections.abc import Sequence
from typing import TypeAliaspython
from __future__ import annotations
from collections.abc import Sequence
from typing import TypeAliasUse modern syntax (Python 3.12+)
使用现代语法(Python 3.12+)
type Vector = list[float] # Type alias (PEP 695)
def process_items(items: Sequence[str], *, limit: int = 10) -> list[str]:
"""Process items with a limit."""
return [item.strip() for item in items[:limit]]
type Vector = list[float] # 类型别名(PEP 695)
def process_items(items: Sequence[str], *, limit: int = 10) -> list[str]:
"""按限制条件处理条目。"""
return [item.strip() for item in items[:limit]]
Use | instead of Union
使用|替代Union
def maybe_int(value: str) -> int | None:
try:
return int(value)
except ValueError:
return None
undefineddef maybe_int(value: str) -> int | None:
try:
return int(value)
except ValueError:
return None
undefinedProject Structure
项目结构
my-project/
pyproject.toml # Single config file for all tools
uv.lock # Locked dependencies (commit this)
src/
my_project/
__init__.py
main.py
models.py
utils.py
tests/
__init__.py
test_main.py
test_models.py
conftest.py # Shared fixtures
.github/
workflows/
ci.yml
dependabot.yml
.pre-commit-config.yamlmy-project/
pyproject.toml # 所有工具的统一配置文件
uv.lock # 锁定的依赖(需提交至仓库)
src/
my_project/
__init__.py
main.py
models.py
utils.py
tests/
__init__.py
test_main.py
test_models.py
conftest.py # 共享夹具
.github/
workflows/
ci.yml
dependabot.yml
.pre-commit-config.yamlCommon Pitfalls
常见陷阱
- Using pip directly: Always use /
uv add/uv remove. Neveruv run.pip install - Separate config files: All configuration goes in . Delete
pyproject.toml,.flake8,mypy.ini.black.toml - Global installs: Use or
uv runinstead of globally installing CLI tools.uv tool run - Missing lock file: Always commit for reproducible builds.
uv.lock - Old Python syntax: Use to auto-upgrade to modern syntax (match statements,
ruff --select UPunions, etc.).| - Ignoring security rules: Enable (bandit) rules in ruff to catch security issues.
S
- 直接使用pip:始终使用/
uv add/uv remove。禁止使用uv runpip install - 使用单独配置文件:所有配置必须写入。删除
pyproject.toml、.flake8、mypy.iniblack.toml - 全局安装工具:使用或
uv run替代全局安装CLI工具uv tool run - 缺失锁文件:必须提交以实现可复现的构建
uv.lock - 使用旧Python语法:使用自动升级至现代语法(match语句、
ruff --select UP联合类型等)| - 忽略安全规则:在ruff中启用(bandit)规则以捕获安全问题
S
Integration with Agent-Studio
与Agent-Studio的集成
Recommended Workflow
推荐工作流
- Use to set up or migrate Python projects
modern-python - Use for framework-specific patterns (Django, FastAPI)
python-backend-expert - Use skill for test-driven development workflow
tdd - Use for test strategy
comprehensive-unit-testing-with-pytest
- 使用搭建或迁移Python项目
modern-python - 使用获取框架特定模式(Django、FastAPI)
python-backend-expert - 使用技能遵循测试驱动开发工作流
tdd - 使用制定测试策略
comprehensive-unit-testing-with-pytest
Complementary Skills
互补技能
| Skill | Relationship |
|---|---|
| Framework-specific patterns (Django, FastAPI, Flask) |
| Testing strategies and patterns |
| Type annotation best practices |
| Modern Python language features |
| Test-driven development methodology |
| Hypothesis-based testing patterns |
| 技能 | 关系 |
|---|---|
| 框架特定模式(Django、FastAPI、Flask) |
| 测试策略与模式 |
| 类型注解最佳实践 |
| 现代Python语言特性 |
| 测试驱动开发方法论 |
| 基于Hypothesis的属性测试模式 |
Memory Protocol
记忆协议
Before starting: Check if the project already has Python tooling configured. Identify which legacy tools need migration.
During setup: Write configuration incrementally, verifying each tool works before moving to the next. Run , , and at each step.
ruff checkruff format --checkuv run pytestAfter completion: Record the toolchain versions and any migration issues to for future reference.
.claude/context/memory/learnings.md开始前:检查项目是否已配置Python工具链。识别需要迁移的传统工具。
搭建过程中:逐步编写配置,在进行下一步前验证每个工具是否正常工作。每一步都要运行、和。
ruff checkruff format --checkuv run pytest完成后:记录工具链版本和迁移过程中遇到的问题至,以备未来参考。
.claude/context/memory/learnings.md