迁移指南
Basilisk 包含帮助现有代码库逐步采用它的工具。在大型代码库上完整迁移可能需要数周时间;以下工具使这个过程可行。
从 Pyright 迁移
第 1 步——导入您的配置
如果您有 pyrightconfig.json,Basilisk 可以读取它并生成等效的 [tool.basilisk] 配置:
basilisk migrate --from pyright
这从当前目录读取 pyrightconfig.json 并将等效设置追加到您的 pyproject.toml。
示例输入(pyrightconfig.json):
{
"include": ["src"],
"exclude": ["**/migrations/**"],
"typeCheckingMode": "strict",
"pythonVersion": "3.12"
}
生成的输出(pyproject.toml):
[tool.basilisk]
python-version = "3.12"
include = ["src/"]
exclude = ["**/migrations/**"]
第 2 步——运行 Basilisk
basilisk check src/
如果您已经将 Pyright 与 typeCheckingMode = "strict" 一起使用,您会看到相对较少的新错误。最常见的添加:
| Pyright 规则 | Basilisk 等效 |
|---|---|
reportMissingTypeArgument |
BSK-E0015 |
reportReturnType |
BSK-E0002 |
reportArgumentType |
BSK-E0012 |
reportAttributeAccessIssue |
BSK-E0050 |
reportUndefinedVariable |
BSK-E0018 |
reportOperatorIssue |
BSK-E0014 |
Basilisk 添加了即使在严格模式下 Pyright 也不标记的错误:
- BSK-E0001 — 缺少参数类型注解(严格强制执行)
- BSK-E0002 — 缺少返回类型注解(严格强制执行)
- BSK-E0011 — 参数和返回位置中的显式
Any——需要说明理由 - BSK-E0023 — 非穷举
match语句(缺少情况) - BSK-E0025 — 覆盖方法缺少
@override装饰器
第 3 步——处理 # type: ignore 注释
Pyright 使用 # type: ignore 进行内联抑制。Basilisk 需要不同的格式,带有强制原因:
# Pyright
x = get_value() # type: ignore[reportArgumentType]
# Basilisk
x = get_value() # basilisk: ignore[BSK-E0012] -- third-party API mismatch, tracked in #456
Basilisk 将标记裸 # type: ignore 注释,因为它不识别它们。迁移工具建议正确的 # basilisk: ignore[CODE] -- reason 格式。
第 4 步——通过每路径覆盖渐进式采用
对于大型代码库,在遗留目录中降低或禁用最嘈杂的规则,并随着进展逐步收紧:
[tool.basilisk]
python-version = "3.12"
include = ["src/"]
[tool.basilisk.per-path-overrides."legacy/**"]
rules."BSK-E0011" = "warning" # 将最嘈杂的规则降级为警告
您也可以在单个文件顶部添加 # basilisk: relaxed,在处理该文件期间将其所有错误变为警告。
严格模式差异
如果您将 Pyright 与 typeCheckingMode = "basic" 或 "standard" 一起使用,您会看到 Basilisk 报告的错误明显更多——因为这些模式允许未类型化的代码。这是预期的,也正是关键所在。使用每路径覆盖,逐目录地分阶段执行。
从 mypy 迁移
第 1 步——导入您的配置
如果您有 mypy.ini 或带有 [mypy] 部分的 setup.cfg:
basilisk migrate --from mypy
示例输入(mypy.ini):
[mypy]
python_version = 3.12
strict = True
ignore_missing_imports = True
exclude = migrations/
生成的输出:
[tool.basilisk]
python-version = "3.12"
exclude = ["**/migrations/**"]
# 注意:ignore_missing_imports → BSK-E0010 仍然激活;
# 对没有存根的特定包使用每路径覆盖
第 2 步——mypy --strict 标志是子集
mypy 的 --strict 启用一组特定的标志。Basilisk 强制执行所有这些标志以及更多。从 mypy --strict 迁移时,预期:
- 来自 BSK-E0011 的更多错误 — mypy 在某些 Basilisk 不允许的位置允许
Any - 来自 BSK-E0023 的更多错误 — mypy 不检查的非穷举
match语句 - 来自 BSK-E0025 的更多错误 — mypy 不要求的缺失
@override装饰器
第 3 步——mypy 插件
mypy 插件(Django、SQLAlchemy、Pydantic)不能与 Basilisk 一起使用。Basilisk 的 WASM 插件系统计划在第 5 阶段。在此之前,您可能会看到框架特定模式的错误,这些错误以前被 mypy 插件抑制。
等待 WASM 插件期间的解决方法:
[tool.basilisk.per-path-overrides."models/**"]
disabled = ["BSK-E0011"] # Django 模型字段广泛使用 Any
第 4 步——更新内联抑制
mypy 使用 # type: ignore[error-code]。Basilisk 需要 # basilisk: ignore[BSK-EXXXX] -- reason。
迁移工具生成代码库中每个 # type: ignore 注释的列表,以及建议的 Basilisk 等效和添加原因的提醒。
第 5 步——删除守护进程
mypy 的守护进程(dmypy)之所以需要,是因为 mypy 很慢。Basilisk 的增量计算是内置的。替换您的 mypy CI 步骤:
# 旧(mypy)
- run: dmypy run -- src/
# 新(Basilisk)
- run: basilisk check src/
一般迁移建议
从缺失注解开始
BSK-E0001(缺失参数注解)和 BSK-E0002(缺失返回注解)往往会级联。首先修复它们通常会自动解决下游错误。
最初只使用这些规则运行:
basilisk check --only E0001,E0002 src/
对遗留目录使用每路径覆盖
不要试图一次性类型化所有内容。在遗留路径中降低最嘈杂的规则,并保持新代码严格:
[tool.basilisk.per-path-overrides."legacy/**"]
rules."BSK-E0011" = "warning"
[tool.basilisk.per-path-overrides."new_modules/**"]
# 新代码立即完全严格
使用 basilisk stats 跟踪进度
basilisk stats src/
输出:
Type coverage report — src/
Files: 142 total, 98 fully typed, 44 partially typed
Functions: 1,847 total, 1,203 typed (65%)
Classes: 318 total, 241 typed (76%)
Top offenders (most errors):
src/legacy/data_pipeline.py — 47 errors
src/utils/converters.py — 23 errors
src/models/legacy_models.py — 19 errors
每周使用此报告跟踪迁移进度。
优先考虑关键路径
在实践中,导入最多的模块中的错误是最高优先级的,因为它们也可能在调用者中导致类型错误。首先修复最深层的共享工具。