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 调用修正均已生效)
This commit is contained in:
zhangtao
2026-10-04 06:00:16 +08:00
parent b3882559de
commit a4e8727a86
5 changed files with 136 additions and 13 deletions
+19
View File
@@ -31,6 +31,7 @@ from sqlalchemy.orm import Session
from app.config.setting import settings
from app.core.database import engine
from app.core.exceptions import CustomException
from app.core.logger import logger
# 任务状态常量(与 task_job.status 注释保持一致:0待执行 1执行中 2成功 3失败)
@@ -592,6 +593,24 @@ class SchedulerUtil:
)
return True, None
@classmethod
def require_schedulable(cls, code_block: str | None) -> None:
"""不可调度时抛出业务异常;可调度时直接返回。
把「取判定结果 + 抛异常」收敛到一处:``describe_schedulability`` 的 reason 是
``str | None``(可调度时为 None),调用点直接 ``CustomException(msg=reason)`` 会
传入 None 让客户端收到空文案;这里统一兜底,也避免每个调用点各写一份兜底文案。
参数:
- code_block (str | None): 节点的 func 字段。
异常:
- CustomException: 当前不可调度时抛出(含可操作原因)。
"""
schedulable, reason = cls.describe_schedulability(code_block)
if not schedulable:
raise CustomException(msg=reason or "当前任务不可调度,请检查任务配置")
@classmethod
def job_code_block(cls, job: Job | None) -> str | None:
"""从调度器 job 的 args 中取回 func(约定见 _add_job_with_trigger: args=[job_id, code_block, *args])。