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. 官方文档

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 文件,用于适配内核项目的特殊需求。

参考:

4. 工具配置说明

Codespell 是拼写检查工具而非代码格式化工具,但其字典选择和配置对检查效果有显著影响。

4.1 配置文件说明

Codespell 支持多种配置文件格式:

配置文件 格式 用途 使用场景
.codespellrc INI 项目级默认配置 放在项目根目录,自动加载
setup.cfg INI 通过 [codespell] 段配置 与项目其他工具配置统一管理
pyproject.toml TOML 通过 [tool.codespell] 段配置 推荐,与项目其他 Python 工具配置统一管理

配置文件查找优先级(从高到低):

  1. 命令行参数(最高优先级)
  2. --config 指定的配置文件
  3. .codespellrc(INI 格式)
  4. setup.cfg 中的 [codespell] 段(INI 格式)
  5. 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 级别的 filesexcludetypes 等参数控制检查范围:

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

参考官方文档:Using a config fileIgnoring Words

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

参考官方文档:UsageIgnoring 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 ignoreIgnoring misspellings marked with "[sic]"