npx skills add https://github.com/trailofbits/skills --skill modern-python基于 trailofbits/cookiecutter-python 的现代 Python 工具链和最佳实践指南。
pyproject.toml 配置| 避免使用 | 应使用 |
|---|---|
[tool.ty] python-version | [tool.ty.environment] python-version |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
uv pip installuv add 和 uv sync |
| 手动编辑 pyproject.toml 来添加依赖 | uv add <pkg> / uv remove <pkg> |
hatchling 构建后端 | uv_build(更简单,适用于大多数情况) |
| Poetry | uv(更快、更简单、生态系统集成更好) |
| requirements.txt | 脚本使用 PEP 723,项目使用 pyproject.toml |
| mypy / pyright | ty(更快,来自 Astral 团队) |
[project.optional-dependencies] 用于开发工具 | [dependency-groups] (PEP 735) |
手动激活虚拟环境 (source .venv/bin/activate) | uv run <cmd> |
| pre-commit | prek(更快,无需 Python 运行时) |
关键原则:
uv add 和 uv remove 来管理依赖uv run[dependency-groups] 来管理开发/测试/文档依赖,而不是 [project.optional-dependencies]你在做什么?
│
├─ 具有依赖关系的单文件脚本?
│ └─ 使用 PEP 723 内联元数据 (./references/pep723-scripts.md)
│
├─ 新的多文件项目(不发布)?
│ └─ 最小化 uv 设置(见下方的快速开始)
│
├─ 新的可复用包/库?
│ └─ 完整项目设置(见下方的完整设置)
│
└─ 迁移现有项目?
└─ 见下方的迁移指南
| 工具 | 用途 | 替代 |
|---|---|---|
| uv | 包/依赖管理 | pip, virtualenv, pip-tools, pipx, pyenv |
| ruff | 代码检查和格式化 | flake8, black, isort, pyupgrade, pydocstyle |
| ty | 类型检查 | mypy, pyright(更快的替代品) |
| pytest | 带覆盖率的测试 | unittest |
| prek | 预提交钩子 (设置) | pre-commit(更快,Rust 原生) |
| 工具 | 用途 | 何时运行 |
|---|---|---|
| shellcheck | Shell 脚本检查 | pre-commit |
| detect-secrets | 密钥检测 | pre-commit |
| actionlint | 工作流语法验证 | pre-commit, CI |
| zizmor | 工作流安全审计 | pre-commit, CI |
| pip-audit | 依赖漏洞扫描 | CI, 手动 |
| Dependabot | 自动化依赖更新 | 定时 |
配置和使用请参见 security-setup.md。
适用于不打算发布的简单多文件项目:
# 使用 uv 创建项目
uv init myproject
cd myproject
# 添加依赖
uv add requests rich
# 添加开发依赖
uv add --group dev pytest ruff ty
# 运行代码
uv run python src/myproject/main.py
# 运行工具
uv run pytest
uv run ruff check .
如果从零开始,询问用户是否更愿意使用 Trail of Bits 的 cookiecutter 模板来引导一个已预配置好工具的完整项目。
uvx cookiecutter gh:trailofbits/cookiecutter-python
uv init --package myproject
cd myproject
这会创建:
myproject/
├── pyproject.toml
├── README.md
├── src/
│ └── myproject/
│ └── __init__.py
└── .python-version
完整配置参考请见 pyproject.md。
关键部分:
[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]
# 新项目从一开始就严格
possibly-unresolved-reference = "error"
unused-ignore-comment = "warn"
# 安装所有依赖组
uv sync --all-groups
# 或安装特定组
uv sync --group dev
.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
当用户请求从旧版工具迁移时:
首先,确定代码的性质:
对于独立脚本:转换为 PEP 723 内联元数据(见 pep723-scripts.md)
对于项目:
# 在现有项目中初始化 uv
uv init --bare
# 使用 uv 添加依赖(而不是通过编辑 pyproject.toml)
uv add requests rich # 添加每个包
# 或者从 requirements.txt 导入(添加前请审查每个包)
# 注意:复杂的版本说明符可能需要手动处理
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
然后:
requirements.txt, requirements-dev.txtvenv/, .venv/)uv.lock 添加到版本控制uv init --bare 创建 pyproject.tomluv add 从 install_requires 添加每个依赖uv add --group dev 添加开发依赖[project]setup.py, setup.cfg, MANIFEST.inuv remove 移除 flake8, black, isort.flake8, pyproject.toml [tool.black], [tool.isort] 配置uv add --group dev ruffuv run ruff check --fix . 来应用修复uv run ruff format . 来格式化uv remove 移除 mypy/pyrightmypy.ini, pyrightconfig.json, 或 [tool.mypy]/[tool.pyright] 部分uv add --group dev tyuv run ty check src/| 命令 | 描述 |
|---|---|
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 |
--with 进行临时依赖使用 uv run --with 来运行需要项目中没有的包的一次性命令:
# 使用临时包运行 Python
uv run --with requests python -c "import requests; print(requests.get('https://httpbin.org/ip').json())"
# 使用临时依赖运行模块
uv run --with rich python -m rich.progress
# 多个包
uv run --with requests --with rich python script.py
# 与项目依赖结合使用(添加到现有虚拟环境)
uv run --with httpx pytest # 项目依赖 + httpx
何时使用 --with 与 uv add:
uv add:包是项目依赖(进入 pyproject.toml/uv.lock)--with:一次性使用、测试,或在项目上下文之外的脚本完整参考请见 uv-commands.md。
[dependency-groups]
dev = ["ruff", "ty"]
test = ["pytest", "pytest-cov", "hypothesis"]
docs = ["sphinx", "myst-parser"]
使用以下命令安装:uv sync --group dev --group test
src/ 布局requires-python = ">=3.11"select = ["ALL"] 和显式忽略项来配置 ruffuv.lock 添加到版本控制每周安装数
1.3K
仓库
GitHub 星标数
3.9K
首次出现
2026年1月26日
安全审计
安装于
opencode1.1K
claude-code1.1K
codex1.1K
gemini-cli1.0K
github-copilot999
cursor977
Guide for modern Python tooling and best practices, based on trailofbits/cookiecutter-python.
pyproject.toml configuration| Avoid | Use 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) |
| Poetry | uv (faster, simpler, better ecosystem integration) |
| requirements.txt | PEP 723 for scripts, pyproject.toml for projects |
| mypy / pyright | ty (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-commit | prek (faster, no Python runtime needed) |
Key principles:
uv add and uv remove to manage dependenciesuv run for all commands[dependency-groups] for dev/test/docs dependencies, not [project.optional-dependencies]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
| 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) |
| 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.
For simple multi-file projects not intended for distribution:
# Create project with uv
uv init myproject
cd myproject
# Add dependencies
uv add requests rich
# Add dev dependencies
uv add --group dev pytest ruff ty
# Run code
uv run python src/myproject/main.py
# Run tools
uv run pytest
uv run ruff check .
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.
uvx cookiecutter gh:trailofbits/cookiecutter-python
uv init --package myproject
cd myproject
This creates:
myproject/
├── pyproject.toml
├── README.md
├── src/
│ └── myproject/
│ └── __init__.py
└── .python-version
See pyproject.md for complete configuration reference.
Key sections:
[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"
# Install all dependency groups
uv sync --all-groups
# Or install specific groups
uv sync --group dev
.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
When a user requests migration from legacy tooling:
First, determine the nature of the code:
For standalone scripts : Convert to PEP 723 inline metadata (see pep723-scripts.md)
For projects :
# Initialize uv in existing project
uv init --bare
# Add dependencies using uv (not by editing pyproject.toml)
uv add requests rich # add each package
# Or import from requirements.txt (review each package before adding)
# 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:
requirements.txt, requirements-dev.txtvenv/, .venv/)uv.lock to version controluv init --bare to create pyproject.tomluv add to add each dependency from install_requiresuv add --group dev for dev dependencies[project]setup.py, setup.cfg, MANIFEST.inuv remove.flake8, pyproject.toml [tool.black], [tool.isort] configsuv add --group dev ruffuv run ruff check --fix . to apply fixesuv run ruff format . to formatuv removemypy.ini, pyrightconfig.json, or [tool.mypy]/[tool.pyright] sectionsuv add --group dev tyuv run ty check src/| Command | Description |
|---|---|
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 |
--withUse uv run --with for one-off commands that need packages not in your project:
# Run Python with a temporary package
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
# Multiple packages
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 contextSee uv-commands.md for complete reference.
[dependency-groups]
dev = ["ruff", "ty"]
test = ["pytest", "pytest-cov", "hypothesis"]
docs = ["sphinx", "myst-parser"]
Install with: uv sync --group dev --group test
src/ layout for packagesrequires-python = ">=3.11"select = ["ALL"] and explicit ignoresuv.lock to version controlWeekly Installs
1.3K
Repository
GitHub Stars
3.9K
First Seen
Jan 26, 2026
Security Audits
Gen Agent Trust HubFailSocketPassSnykPass
Installed on
opencode1.1K
claude-code1.1K
codex1.1K
gemini-cli1.0K
github-copilot999
cursor977
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装
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 |