Files
FastapiAdmin/backend/pyrightconfig.json
T
zhangtao a4e8727a86 chore(backend): 新增 basedpyright 校准配置,并修复它暴露的三处真缺陷
背景:仓库此前没有 pyright/basedpyright 配置,basedpyright 使用自身默认(≈recommended),
在 app/ 下产生 247 errors / 3799 warnings,其中 143 条是 reportMissingTypeArgument
(未参数化泛型)这类注解完整度噪音,会把真缺陷淹没(例如 OSS 的 Client.uploader 方法误用)。

配置(backend/pyrightconfig.json)
- typeCheckingMode: basic;显式把能抓真缺陷的规则保持为 error
  (reportAttributeAccessIssue / reportArgumentType / reportOptionalMemberAccess /
  reportIncompatibleMethodOverride / reportConstantRedefinition / reportMissingImports 等)
- 关闭注解完整度与风格类规则;tests/ 用 executionEnvironments 单独放宽(extraPaths 保证 app 可解析)
- 结果:app + main.py + tests 全量 0 errors
- 红绿验证:合成「str | None 传参」「MethodType 上取属性」「Optional 成员访问」三类
  仍全部报 error,证明校准没有把真缺陷一起关掉

修复配置暴露的三处真缺陷
1) template_safety.py:_SQLALCHEMY_TYPE_WHITELIST 对全大写常量二次赋值 → 合并为一次成型
2) template_safety.py:normalize_column_type 假定 _TYPE_BASE_RE 必命中(用 # type: ignore 盖住,
   None 时 .group() 会崩)→ 改为 None 安全,去掉 type-ignore
3) node/service.py ×2:CustomException(msg=reason) 中 reason 为 str | None,客户端可能收到空文案
   → 新增 SchedulerUtil.require_schedulable() 收敛「判定 + 抛异常 + 兜底文案」,调用点改为一行

验证:basedpyright 0 errors(原 247);ruff All checks passed;pytest 97 passed;
      已部署并线上复验(四端 200、Host 收窄、伪造令牌被拒、验证码过期 400 保留业务文案、
      容器内 require_schedulable 与 OSS 调用修正均已生效)
2026-10-04 06:00:16 +08:00

103 lines
4.3 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
// 校准配置:让编辑器只报「真问题」,而不是基于默认推荐规则产生大量噪音。
// 背景:仓库此前没有 pyright/basedpyright 配置,basedpyright 使用自身默认
// (相当于 recommended),在 app/ 下产生 247 errors / 3799 warnings,其中
// 143 条是 reportMissingTypeArgument(未参数化泛型,如 Task / Result / ColumnElement),
// 属「注解完整度」而非缺陷,会掩盖 reportArgumentType / reportAttributeAccessIssue
// 这类能抓到真 bug 的规则(例如 OSS 的 Client.uploader 方法误用)。
"typeCheckingMode": "basic",
"pythonVersion": "3.12",
"venvPath": ".",
"venv": ".venv",
"include": ["app", "main.py", "tests"],
"exclude": ["**/__pycache__", ".venv", ".mypy_cache", ".ruff_cache", "alembic/versions"],
// tests/ 单独放宽:测试普遍用 SimpleNamespace 假对象、从 fixture 取 Optional 后直接使用,
// 这些由 pytest 运行期验证;对 app/ 的严格规则保持不变。
"executionEnvironments": [
{
"root": "tests",
"extraPaths": ["."],
"reportArgumentType": "none",
"reportCallIssue": "none",
"reportOptionalSubscript": "none",
"reportOptionalMemberAccess": "none",
"reportOperatorIssue": "none",
"reportUnusedCallResult": "none"
},
{
"root": "."
}
],
// ── 保留为 error(能抓真缺陷,不允许降级)──
"reportAttributeAccessIssue": "error",
"reportArgumentType": "error",
"reportAssignmentType": "error",
"reportCallIssue": "error",
"reportReturnType": "error",
"reportGeneralTypeIssues": "error",
"reportOptionalMemberAccess": "error",
"reportOptionalCall": "error",
"reportOptionalSubscript": "error",
"reportOptionalIterable": "error",
"reportOptionalOperand": "error",
"reportIndexIssue": "error",
"reportOperatorIssue": "error",
"reportInvalidTypeArguments": "error",
"reportConstantRedefinition": "error",
"reportRedeclaration": "error",
"reportUndefinedVariable": "error",
"reportSelfClsParameterName": "error",
"reportInvalidStringEscapeSequence": "error",
"reportUnhashable": "error",
"reportInvalidCast": "error",
"reportAssertAlwaysTrue": "error",
"reportIncompatibleMethodOverride": "error",
"reportOverlappingOverload": "error",
"reportNoOverloadImplementation": "error",
"reportAbstractUsage": "error",
"reportMissingImports": "error",
"reportMissingModuleSource": "warning",
// SQLAlchemy 声明式模型的已知误报族:基类用 @declared_attr.directive 生成
// __tablename__/__table_args__(pyright 视作描述符/类变量),而各模型普遍用普通
// 类属性覆写(__tablename__: str = "sys_user"),pyright 判定为「实例变量覆写类变量」。
// 试过在基类 TYPE_CHECKING 里补 ClassVar 声明的正规解法:反而新增 reportRedeclaration
// 且错误数上升(62 → 90),故按社区通行做法关闭该规则。真实的方法覆写不兼容由
// reportIncompatibleMethodOverride(保持 error)兜底。
"reportIncompatibleVariableOverride": "none",
"reportUnboundVariable": "error",
// ── 降级为 none:注解完整度/风格类,属增量清理而非缺陷 ──
"reportMissingTypeArgument": "none",
"reportUnknownMemberType": "none",
"reportUnknownArgumentType": "none",
"reportUnknownVariableType": "none",
"reportUnknownParameterType": "none",
"reportUnknownLambdaType": "none",
"reportMissingParameterType": "none",
"reportUnannotatedClassAttribute": "none",
"reportImplicitOverride": "none",
"reportMissingTypeStubs": "none",
"reportAny": "none",
"reportExplicitAny": "none",
"reportUnusedCallResult": "none",
"reportUnusedImport": "none",
"reportPrivateImportUsage": "none",
"reportPrivateLocalImportUsage": "none",
"reportUnnecessaryComparison": "none",
"reportUnnecessaryIsInstance": "none",
"reportUnnecessaryCast": "none",
"reportUnusedParameter": "none",
"reportUnreachable": "none",
"reportImplicitStringConcatenation": "none",
"reportUnsafeMultipleInheritance": "none",
"reportDeprecated": "none",
"reportUnusedClass": "none",
"reportUnusedFunction": "none",
"reportUnusedVariable": "none",
"reportWildcardImportFromLibrary": "none",
"reportUnsupportedDunderAll": "none"
}