课题20:项目代码规范与格式化

难度:低 | 类型:项目实战 | 源文件.pre-commit-config.yaml, docs/CODING_STANDARDS.md, scripts/lint_check.sh | 行数:~200 状态:✅ 已完成


概述

为项目引入代码格式化工具(Black、isort)和静态检查工具(Ruff、mypy),统一代码风格,确保质量。


理解背景

是什么?

代码规范体系确保 ScratchV 项目的所有代码风格一致、类型安全、无低级错误。包含自动化工具链:

工具 用途 触发方式
Black Python 代码格式化 git commit 时自动
isort import 排序 git commit 时自动
Ruff 快速 lint(替代 flake8) git commit 时自动
mypy 静态类型检查 git commit 时自动
pre-commit 钩子管理器 安装后自动运行

为什么?
  • 一致性:10 个贡献者的代码看起来像一个人写的
  • 减少 review 负担:格式化问题自动修复,reviewer 只需关注逻辑
  • 提前发现 bug:类型检查和 lint 在 commit 之前就拦下低级错误

核心概念

pre-commit 钩子

每次 git commit 时自动运行配置的检查工具。如果有问题: - Black/isort/Ruff → 自动修复并阻止 commit(需要重新 add + commit) - mypy → 报告类型错误,需要手动修复

配置要点
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/psf/black
    rev: 24.x
    hooks:
      - id: black
        args: [--line-length=88, --target-version=py312]

  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.x
    hooks:
      - id: ruff
        args: [--fix]

详细任务
  1. 配置pyproject.toml,添加Black和isort配置。
  2. 配置Ruff(或Flake8)进行代码风格检查,定义忽略规则。
  3. 配置mypy进行静态类型检查,为关键模块添加类型注解。
  4. 添加pre-commit hooks,确保提交前自动格式化和检查。
  5. 在CI中增加lint步骤(结合课题6的CI)。
  6. 格式化整个项目代码库,修复所有lint错误。

交付产物
  • pyproject.toml配置文件
  • .pre-commit-config.yaml
  • CI配置文件中的lint作业
  • 文档:代码规范指南、如何运行格式化和检查

代码走读

安装
pip install pre-commit
pre-commit install

手动运行
# 对所有文件运行所有检查
pre-commit run --all-files

# 只运行 Black
pre-commit run black --all-files

# 用便捷脚本
bash scripts/lint_check.sh          # 只检查
bash scripts/lint_check.sh --fix    # 自动修复
bash scripts/lint_check.sh --all    # 包含测试文件

编码规范速查
规范 要求
导入 使用 scratchv.* 绝对导入,不用相对导入(from . import
命名 模块 snake_case,类 PascalCase,函数/变量 snake_case
类型提示 所有公开 API 必须有 type hints
Docstring 模块级 + 类级 + 方法级,用 """..."""
行宽 88 字符(Black 默认)

lint_check.sh 核心
# 只检查 scratchv/ 目录
ruff check scratchv/
mypy scratchv/ --ignore-missing-imports --follow-imports=silent

# --fix: 同时运行 Black 和 isort 自动修复
black scratchv/ tests/
isort scratchv/ tests/

CI 集成
# .github/workflows/ci.yml
- name: Lint
  run: |
    pip install ruff mypy
    ruff check .
    mypy scratchv/ --ignore-missing-imports

动手练习

练习 1: 安装 pre-commit

在本地项目安装 pre-commit install,提交一个代码改动,观察自动检查过程。

练习 2: 修复 lint 问题

运行 ruff check .,挑一个 warning 手动修复。

练习 3: 添加类型提示

找一个没写类型提示的公开函数,添加正确的 type hints,运行 mypy 确认通过。


常见坑
说明
pre-commit 未安装 如果只 pip install pre-commit 但没运行 pre-commit install,钩子不会触发
Black vs isort 冲突 两个工具对 import 排序的默认规则不同——确保 isort 使用 profile=black
mypy 误报 第三方库(如 onnx)可能没有类型存根,用 --ignore-missing-imports 跳过
CI 环境差异 CI 可能用不同版本的 mypy/ruff,保持 pyproject.toml 中的版本约束

进阶阅读

12周每周目标
  • W1:学习Black/isort/Ruff/mypy的用法和配置方法,本地安装测试。
  • W2:编写pyproject.toml,配置Black行长度(如88)、isort配置。
  • W3:配置Ruff,选择要启用的检查规则(如E、F、W),定义忽略规则。
  • W4:在本地运行Black和isort格式化整个项目,提交PR。
  • W5:配置mypy,为项目根目录添加mypy.ini,先忽略错误较多的模块。
  • W6:为关键模块(如ir.pydsl_parser.py)添加类型注解。
  • W7:逐步为其他模块添加类型注解,修复mypy错误。
  • W8:安装pre-commit,编写.pre-commit-config.yaml,包含black、isort、ruff、mypy。
  • W9:测试pre-commit hooks,确保每次提交自动运行。
  • W10:在CI配置中添加lint作业(使用ruff和mypy),与课题6的CI集成。
  • W11:修复CI中发现的剩余lint错误,确保CI通过。
  • W12:撰写代码规范文档,包含如何安装pre-commit、如何运行检查。