Archived
fix: 修复 7 处变量可能未绑定的真缺陷,类型检查升到 standard
为什么:IDE 里成片的黄色波浪线并非风格噪声。ruff 与 pyright(basic) 都是 0 报错,但 basic 会整体漏报「变量可能未绑定」这类**可执行缺陷**;实测 standard 多报 7 处且全部为真——异常处理器引用了尚未赋值的局部变量,一旦走进 异常分支就会 NameError 二次崩溃,把原始异常彻底掩盖。 - core/db.py, core/http_client.py:3 处 @asynccontextmanager 的返回标注 AsyncIterator[X] 更正为 AsyncGenerator[X, None](前者不含 send 语义) - core/state.py:三个模块级缓存补 TypedDict 建模。原先无标注的 dict 字面量被 推断为「所有值类型的并集」(float | None),每个读写点都退化成联合类型; 拆成 _VipCache(data 可为 None 表示未探测)与 _VipEntry(data 必定存在)后, 类型检查立刻抓出 account.py 对未探测缓存的直接解包隐患 - services/batch.py:zip_valid 提到函数头。ZIP 构建前的业务错误(参数缺失/ 无歌曲)会 early raise,而异常处理器引用了该名字 → NameError 二次崩溃 - services/podcast.py:radio_name、pct 同理补初始化 - services/downloads.py:声明返回 str 却可能给出 None,改 `or ''` 满足契约 - web/routers/download.py:id_list 提前绑定 - web/auth_state.py:解包出的 c 未被使用 - pyproject.toml:typeCheckingMode 由 basic 升到 standard 作为门禁,并移除 已被 standard 覆盖的 reportGeneralTypeIssues 门禁:ruff All checks passed · pyright(standard) 0 errors 0 warnings
This commit is contained in:
1 parent
fc7fc21284
commit
183f5744d8
9 files changed
+58
-16
No files matched your search
+35
-5
@@ -15,7 +15,7 @@ web/ 与各服务模块共用,并为后续封装成带锁的单例(State 对
|
||||
|
||||
import collections
|
||||
import threading
|
||||
from typing import Any
|
||||
from typing import Any, NotRequired, TypedDict
|
||||
|
||||
# ============ 短链展开结果缓存 ============
|
||||
# 用户反复解析同一分享链接不再重复请求 163cn.tv(有界防膨胀)
|
||||
@@ -57,15 +57,45 @@ REQ_LOG: list[dict[str, Any]] = []
|
||||
|
||||
|
||||
# ============ 上游探测缓存 ============
|
||||
# 带时间戳的缓存一律用 TypedDict 显式声明字段类型:无标注的 dict 字面量会被类型
|
||||
# 检查器推断为「所有键的值类型取并集」(如 `{'v': None, 'ts': 0.0}` → float | None),
|
||||
# 于是每个读写点都退化成联合类型,既丢失精确性也淹没真实缺陷。
|
||||
class _TimedValue(TypedDict):
|
||||
"""值 + 写入时刻的二元缓存。"""
|
||||
v: str | None
|
||||
ts: float
|
||||
|
||||
|
||||
class _NickCache(TypedDict):
|
||||
"""服务器账号昵称缓存。"""
|
||||
nick: str | None
|
||||
ts: float
|
||||
|
||||
|
||||
class _VipCache(TypedDict):
|
||||
"""全局 VIP 缓存:data 为 None 表示尚未探测(读侧需判空)。"""
|
||||
data: dict[str, Any] | None
|
||||
ts: float
|
||||
ttl: NotRequired[int]
|
||||
|
||||
|
||||
class _VipEntry(TypedDict):
|
||||
"""已写入的 VIP 缓存条目——三个字段齐备,data 必定存在。"""
|
||||
data: dict[str, Any]
|
||||
ts: float
|
||||
ttl: int
|
||||
|
||||
|
||||
# 全局账号 MUSIC_U(5 分钟缓存;后台重新扫码后自动跟随新值)
|
||||
GLOBAL_MUSIC_U_CACHE = {'v': None, 'ts': 0.0}
|
||||
GLOBAL_MUSIC_U_CACHE: _TimedValue = {'v': None, 'ts': 0.0}
|
||||
|
||||
# 服务器网易云账号昵称缓存(10 分钟):非管理员可见响应中遮蔽真实昵称
|
||||
SERVER_NICK_CACHE = {'nick': None, 'ts': 0.0}
|
||||
SERVER_NICK_CACHE: _NickCache = {'nick': None, 'ts': 0.0}
|
||||
SERVER_NICK_LOCK = threading.Lock() # 刷新单飞锁,防并发重复打上游
|
||||
VIP_PROBE_LOCK = threading.Lock() # 音质探测单飞锁(有界等待)
|
||||
|
||||
# 全局账号 VIP 探测缓存(5 分钟):probe 一次要打 8 次网易云接口,
|
||||
# 公网下账号栏高频刷新会连累服务器账号触发风控。
|
||||
VIP_CACHE = {'data': None, 'ts': 0.0}
|
||||
VIP_USER_CACHE = {} # user 路径按 cookie 哈希的 5 分钟缓存
|
||||
VIP_CACHE: _VipCache = {'data': None, 'ts': 0.0}
|
||||
# user 路径按 cookie 哈希的 5 分钟缓存
|
||||
VIP_USER_CACHE: dict[str, _VipEntry] = {}
|
||||
Reference in new issue
Block a user