mypy 并行报 No status file,检查插件导入是否挡住最后一次轮询
mypy 并行协调器被插件导入阻塞时,旧轮询可能漏读已写出的状态文件。采用修复版本,保留原插件和输入验证,并区分连接等待与实际 worker 启动失败。
mypy 加上 -n 2 后报 Failed to establish connection with worker: No status file found,串行检查或稍后重跑却正常,先看协调器是否在导入插件时被阻塞。状态文件真的没写出,与文件已写出却没被最后一次轮询读到,需要分别定位。
一条已确认路径涉及 mypy 2.3.1、Python 3.14.0/3.14.5、macOS 26.6.2 arm64。插件导入二进制模块时,首次加载可能受 XProtect 扫描影响并长时间持有 GIL;worker 已经启动并写出状态,协调器负责轮询的线程却无法及时运行。后续导入变快,所以同一命令第二次正常,不能据此认定第一次只是文件系统偶发失败。
旧 connect() 把时间条件放在循环入口。线程恢复执行时,如果期限已经过去,会直接退出,不再读取那份已经存在的状态文件。mypy 2.4.0 的正式修补改为先尝试读取,只有遇到 BadStatus 后才检查期限和继续等待。
该版本还将 macOS 上 worker 等待协调器连接的时间扩至 30 秒。这是另一处保护:如果导入阻塞超过 worker 自己的等待期,状态文件即使被读到,连接目标也可能已经退出。启动状态轮询与 worker 连接等待不是同一个计时器,修补不能简单概括为把一个数字改大。
可以在同一个检查环境中采用正式版本,保留原插件配置和检查输入:
python -m pip install "mypy==2.4.0"
python -m mypy --version
python -m mypy -n 2 --show-traceback path/to/module.py
路径换成原来的模块或项目入口。插件必须继续按原配置加载;为了让命令退出成功而删掉插件,会同时改变类型检查结果,不能作为这条故障的验收。
诊断时分别记录第一次与后续检查:错误出现前是否正在导入插件、worker 是否已经写出状态、最后错误是 No status file found 还是连接端点不存在。必要时按当前工具的帮助关闭并行,比较相同插件和输入;串行结果只能帮助缩小范围,不能代替并行路径已经修复。
验证原首次运行条件,确认协调器不再因为迟到的轮询漏读有效状态,随后检查类型诊断与预期一致。不要只连续执行几次直到成功:已加载过的二进制模块可能使后续运行不再遇到原来的长阻塞。
这项修补不保证任意慢插件都能完成。worker 本身未启动、状态内容损坏、连接目标已退出,或阻塞超过相应等待边界,仍可能失败。若仍有异常,保留插件版本、原环境与完整错误,继续区分启动、状态读取和连接三个阶段;不应无限增加等待时间来掩盖真实进程错误。


