Codespell
相关工具推荐
| 工具 | 说明 |
|---|---|
| Typos | Rust 实现的拼写检查工具,性能更高,适合大型项目 |
| Markdownlint | Markdown 文件的 lint 工具,包含部分拼写规则 |
| Ruff | Python 代码检查工具,可配合 Codespell 覆盖代码质量与拼写 |
1. 简介
Codespell 是一个通用拼写检查工具,用于检测文本文件中的常见拼写错误。它最初由 Lucas De Marchi 创建,设计初衷是针对源代码文件(能够识别并跳过反斜杠转义的字符串),但也适用于其他类型的文本文件。
- 主要检查语言:通用(不限于特定语言)
- 主要检查能力:检测源代码和文档中的常见拼写错误;涵盖拼写检查
- 核心检查原理:基于 Wikipedia 常见拼写错误字典进行 token 匹配
- 检查规则/选项:提供多个 CLI 与配置文件选项(skip、ignore-words-list、exclude-file 等),维护一份持续更新的内置拼写错误词典(词条随版本动态变化),配置选项说明
- GitHub 仓库:https://github.com/codespell-project/codespell(2,384 stars)
- 开源协议:GPL-2.0-or-later
- 最新稳定版本:v2.4.1
- 运行环境要求:Python 3.8+
- 误报率:低
2. 官方文档
- 项目主页与文档: https://github.com/codespell-project/codespell
- 完整 README(含所有配置说明): https://github.com/codespell-project/codespell/blob/main/README.rst
- 内置字典文件列表: https://github.com/codespell-project/codespell/tree/main/codespell_lib/data
- Releases 页面: https://github.com/codespell-project/codespell/releases
- pre-commit hooks 定义: https://github.com/codespell-project/codespell/blob/main/.pre-commit-hooks.yaml
Codespell 没有独立的文档网站,所有文档均包含在仓库的 README.rst 中。命令行帮助可通过
codespell -h获取完整参数说明。
3. 社区优秀实践
3.1 pytest
pytest 是 Python 测试框架领域的事实标准项目,在 .pre-commit-config.yaml 中集成了 Codespell,并通过 pyproject.toml 管理配置。
pre-commit 配置(.pre-commit-config.yaml):
- repo: https://github.com/codespell-project/codespell
rev: v2.4.2
hooks:
- id: codespell
args: ["--toml=pyproject.toml"]
additional_dependencies:
- tomli
pyproject.toml 配置:
[tool.codespell]
ignore-words-list = "afile,asend,asser,assertio,feld,hove,ned,noes,notin,paramete,parth,tesults,varius,wil"
skip = "AUTHORS,*/plugin_list.rst"
write-changes = true
参考: https://github.com/pytest-dev/pytest
3.2 Flask
Flask 是 Python Web 框架领域的代表性项目(Pallets 团队维护),在 .pre-commit-config.yaml 中集成了 Codespell,并配置了自动修复。
pre-commit 配置(.pre-commit-config.yaml):
- repo: https://github.com/codespell-project/codespell
rev: 2ccb47ff45ad361a21071a7eedda4c37e6ae8c5a # frozen: v2.4.2
hooks:
- id: codespell
args: ["--write-changes"]
pyproject.toml 配置:
[tool.codespell]
ignore-words-list = "te"
参考: https://github.com/pallets/flask
3.3 Linux Kernel
Linux Kernel 是全球最大的开源项目之一,其 scripts/spelling.txt 文件记录了内核代码中发现的所有拼写错误及修正建议,该字典的原始来源正是 Codespell 所基于的拼写检查机制(源自 Debian Lintian 工具的拼写列表)。Codespell 仓库中也包含了 linux-kernel.exclude 文件,用于适配内核项目的特殊需求。
参考:
- https://github.com/torvalds/linux(
scripts/spelling.txt) - https://github.com/codespell-project/codespell/blob/main/codespell_lib/data/linux-kernel.exclude
4. 工具配置说明
Codespell 是拼写检查工具而非代码格式化工具,但其字典选择和配置对检查效果有显著影响。
4.1 配置文件说明
Codespell 支持多种配置文件格式:
| 配置文件 | 格式 | 用途 | 使用场景 |
|---|---|---|---|
.codespellrc |
INI | 项目级默认配置 | 放在项目根目录,自动加载 |
setup.cfg |
INI | 通过 [codespell] 段配置 |
与项目其他工具配置统一管理 |
pyproject.toml |
TOML | 通过 [tool.codespell] 段配置 |
推荐,与项目其他 Python 工具配置统一管理 |
配置文件查找优先级(从高到低):
- 命令行参数(最高优先级)
--config指定的配置文件.codespellrc(INI 格式)setup.cfg中的[codespell]段(INI 格式)pyproject.toml中的[tool.codespell]段(TOML 格式)
4.2 配置文件详解
配置项说明:
| 配置项 | 类型 | 说明 |
|---|---|---|
skip |
string | 跳过检查的文件或目录(逗号分隔的 glob 模式) |
count |
bool | 是否统计拼写错误数量 |
quiet-level |
int | 静默级别(控制输出详细程度) |
ignore-words-list |
string | 忽略的单词列表(逗号分隔) |
builtin |
string | 启用的内置字典名称(逗号分隔) |
dictionary |
string | 自定义字典文件路径 |
ignore-words |
string | 自定义忽略单词文件路径 |
exclude-file |
string | 排除文件列表文件路径 |
注意:配置文件中的值不能以
-字符开头。如需以-开头的值(如使用-表示 stdin),需将-放在值末尾,例如dictionary = mydict,-。
最小配置示例:
pyproject.toml 配置(推荐):
[tool.codespell]
skip = '*.po,*.ts,./src/3rdParty,./src/Test'
count = true
quiet-level = 3
ignore-words-list = "foo,bar,baz"
setup.cfg / .codespellrc 配置:
[codespell]
skip = *.po,*.ts,./src/3rdParty,./src/Test
count =
quiet-level = 3
ignore-words-list = foo,bar,baz
推荐配置示例:
以下是适合大多数项目的推荐配置,兼顾检查覆盖率和误报控制:
[tool.codespell]
# 跳过常见的非文本文件
skip = '*.po,*.ts,*.lock,*.json,*.svg,*.png,*.jpg'
# 忽略项目中常见的误报词(需根据项目实际情况调整)
ignore-words-list = "fo,foe"
# 启用代码专用字典,捕获代码中常见的拼写错误
builtin = 'code'
# 统计拼写错误数量
count = true
4.3 内置字典说明
Codespell 提供多个可选的内置字典,可通过 --builtin 参数启用:
| 字典名称 | 说明 | 启用方式 |
|---|---|---|
clear |
更明确的拼写错误 | --builtin=clear |
rare |
罕见的拼写错误(可能产生更多误报) | --builtin=rare |
informal |
非正式用语 | --builtin=informal |
usage |
用法错误 | --builtin=usage |
code |
代码中常见的拼写错误 | --builtin=code |
names |
常见人名误拼 | --builtin=names |
en-GB_to_en-US |
英式英语到美式英语的差异 | --builtin=en-GB_to_en-US |
--builtin=all可启用所有内置字典,但可能增加误报率。建议根据项目需要选择性启用。
4.4 自定义字典
如需添加项目特有的拼写规则,可创建自定义字典文件:
# 创建自定义字典
cat > .codespell-dictionary.txt << 'EOF'
teh->the
recieve->receive
occured->occurred
EOF
# 使用自定义字典
codespell --dictionary=.codespell-dictionary.txt
字典格式为 错误拼写->正确拼写,每行一条。详细格式说明参见官方文档 Dictionary format。
5. 主流集成方式
5.1 pre-commit 集成(推荐)
Codespell 在业界的主流集成方式是通过 pre-commit 框架。Codespell 官方仓库提供了 .pre-commit-hooks.yaml,hook 的 language: python,pre-commit 会自动管理其 Python 环境,无需手动安装。
基本配置(.pre-commit-config.yaml):
repos:
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
- id: codespell
使用 pyproject.toml 配置时(Python < 3.11 需要额外依赖 tomli):
repos:
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
- id: codespell
additional_dependencies:
- tomli
依赖来源:hook 使用
language: python,pre-commit 会自动创建隔离的 Python 虚拟环境并安装 codespell,无需项目本地预装 codespell。additional_dependencies中的tomli仅在 Python < 3.11 且使用pyproject.toml配置时需要。
限制只检查变更文件:pre-commit 默认仅将暂存区中的变更文件传递给 hook,天然支持增量检查。
增量检查:当使用 pre-commit 集成时,pre-commit 框架默认仅将暂存区中的变更文件传递给 hook,天然实现文件级增量检查。无需额外配置,pre-commit 自动处理增量逻辑。
5.2 IDE 集成
VS Code
VS Code Marketplace 中没有 Codespell 官方扩展。推荐通过以下方式间接集成:
- 通过 pre-commit 框架:安装 pre-commit 的 VS Code 扩展(社区扩展),在保存或提交时自动运行 Codespell
- 通过任务配置:在
.vscode/tasks.json中配置 codespell 作为构建任务
Vim/Neovim
可通过 ALE (Asynchronous Lint Engine) 集成 Codespell:
let g:ale_linters = {'*': ['codespell']}
ALE 会调用系统 PATH 中的 codespell 命令,需确保已通过 pip 安装。
IntelliJ IDEA / PyCharm
JetBrains IDE 没有官方的 Codespell 插件。可通过 External Tool 配置或 pre-commit 集成实现。
5.3 命令行使用方式
检查当前目录所有文件(默认为 dry run):
codespell
检查指定文件或目录:
codespell some_file some_dir/ *.py
自动修复模式(-w 会直接修改文件):
codespell -w
交互式修复(推荐与 -w 配合使用):
codespell -i 3 -w
常用参数:
| 参数 | 说明 |
|---|---|
-w, --write-changes |
直接修改文件中的拼写错误 |
-i, --interactive |
交互式模式,逐个确认修复(0-3 级别) |
-L, --ignore-words-list |
逗号分隔的忽略词列表 |
-I, --ignore-words |
从文件读取忽略词列表(每行一个词) |
-S, --skip |
跳过的文件/目录(支持 glob 模式) |
-x, --exclude-file |
忽略匹配指定文件中内容的行 |
-D, --dictionary |
使用自定义字典文件 |
--builtin |
启用内置的附加字典(如 clear, rare, informal, usage, code, names) |
--builtin=all |
启用所有内置附加字典 |
-q, --quiet-level |
静默级别(0-3) |
--count |
统计拼写错误数量 |
--ignore-sic |
跳过标记了 [sic] 的拼写 |
--check-hidden |
检查隐藏文件 |
-d, --disable-colors |
禁用终端颜色输出 |
增量检查 -- Codespell 本身没有专门的增量参数(如 --new-from-rev),但支持通过文件路径参数限定检查范围:
# 检查指定文件列表
codespell file1.py file2.py file3.md
# 检查指定目录
codespell src/ docs/
配合 Git 获取变更文件列表:
# 检查所有变更文件(相对于 main 分支)
codespell $(git diff --name-only --diff-filter=ACMR main)
# 检查暂存区变更文件
codespell $(git diff --name-only --diff-filter=ACMR --cached)
# 检查未提交的变更文件
codespell $(git diff --name-only --diff-filter=ACMR)
CI 脚本调用:
GitHub Actions
name: codespell
on: [push, pull_request]
jobs:
codespell:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install codespell
- run: codespell
也可以通过 pre-commit 的 CI 模式运行:
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pre-commit/action@v3.0.1
GitLab CI
codespell:
image: python:3.12
before_script:
- pip install codespell
script:
- codespell
增量检查 -- 仅检查 PR/MR 变更文件:
GitHub Actions -- 仅检查 PR 变更文件:
name: codespell
on:
pull_request:
jobs:
codespell:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install codespell
- name: Check changed files
run: |
CHANGED=$(git diff --name-only --diff-filter=ACMR origin/${{ github.base_ref }}...HEAD)
if [ -n "$CHANGED" ]; then
codespell $CHANGED
fi
GitLab CI -- 仅检查 MR 变更文件:
codespell:
image: python:3.12
before_script:
- pip install codespell
script:
- |
CHANGED=$(git diff --name-only --diff-filter=ACMR origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD)
if [ -n "$CHANGED" ]; then
codespell $CHANGED
fi
rules:
- if: $CI_MERGE_REQUEST_IID
5.4 pip 安装(Python 生态主流)
Codespell 是一个 Python 包,通过 pip 安装是最基础的集成方式:
pip install codespell
安装后即可在命令行直接使用 codespell 命令。Python 3.9+ 是最低版本要求。
6. 告警抑制(屏蔽)方法
6.1 通过 pre-commit 框架屏蔽
在 .pre-commit-config.yaml 中,可以通过 hook 级别的 files、exclude、types 等参数控制检查范围:
repos:
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
- id: codespell
files: ^(src|docs)/.*\.(py|md|rst)$ # 仅检查匹配的文件
exclude: ^src/vendor/ # 排除 vendor 目录
types: [text] # 仅检查文本文件(默认已设置)
参考官方文档:pre-commit hook
6.2 通过工具配置文件屏蔽
pyproject.toml:
[tool.codespell]
# 跳过特定文件或目录(支持 glob 模式)
skip = '*.po,*.ts,./src/3rdParty,./src/Test'
# 忽略特定单词(逗号分隔)
ignore-words-list = "foo,bar,baz"
setup.cfg / .codespellrc:
[codespell]
skip = *.po,*.ts,./src/3rdParty,./src/Test
ignore-words-list = foo,bar,baz
6.3 通过工具命令行参数屏蔽
# 跳过特定文件类型和目录
codespell --skip="*.po,*.ts,./src/3rdParty,./src/Test"
# 忽略特定单词
codespell --ignore-words-list="foo,bar,baz"
# 从文件读取忽略词列表
codespell --ignore-words=.codespell-ignore
# 使用自定义字典
codespell --dictionary=mydict.txt
# 排除匹配指定文件内容的行
codespell --exclude-file=.codespell-exclude
参考官方文档:Usage、Ignoring Words
6.4 通过代码注释屏蔽
Codespell 支持行内注释语法,可在代码中精确控制忽略范围:
忽略当前行的特定单词:
def wrod() # codespell:ignore wrod
pass
忽略当前行的所有拼写错误:
def wrod(wrods) # codespell:ignore
pass
忽略下一行的特定单词(适用于格式化工具会将注释推到新行的情况):
# codespell:ignore-next-line wrod
def wrod():
pass
忽略下一行的所有拼写错误:
# codespell:ignore-next-line
def wrod(wrods):
pass
使用 [sic] 标记(需启用 --ignore-sic 参数):
correct the "wrod" [sic] typo in a changelog entry
参考官方文档:Inline ignore、Ignoring misspellings marked with "[sic]"