# -*- coding: utf-8 -*- """用 pyflakes 静态检查所有 Python 源码。 为什么必须加这一层: 我加 check_code_available() 时用了 DEFAULT_RELAY_URL, 但那个常量定义在 server.py、run_agent.py 里没导入。 结果:安装到最后一步直接弹 NameError 崩溃。 自带的回归全绿、编码审计也过 —— 因为这是**运行到那行才炸**的问题。 pyflakes 是静态分析,扫一眼就能发现"用了没定义的名字"。 本机自带 pyflakes 4.0.2。没有的话就跳过(不阻塞)。 """ from __future__ import annotations import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent TARGETS = ( list((ROOT / "windows").glob("*.py")) + list((ROOT / "windows" / "lanremote").glob("*.py")) + list((ROOT / "relay").glob("*.py")) + list((ROOT / "_build").glob("*.py")) + list((ROOT / "_tests").glob("*.py")) ) def main() -> int: try: import pyflakes # noqa: F401 except ImportError: print(" (本机没有 pyflakes,跳过)") return 0 files = [str(p) for p in TARGETS if p.is_file()] print(f" 检查 {len(files)} 个 Python 文件…") proc = subprocess.run([sys.executable, "-m", "pyflakes"] + files, capture_output=True, text=True, encoding="utf-8", errors="replace") lines = [line for line in (proc.stdout or "").splitlines() if line.strip()] if not lines: print(" ✓ 没有未定义名 / 未使用导入等问题") return 0 # 分类:undefined name 是致命的,未使用导入是无害的 fatal = [line for line in lines if "undefined name" in line] minor = [line for line in lines if line not in fatal] if minor: print(f" {len(minor)} 条小问题(未使用的导入/变量,不影响运行):") for line in minor[:8]: print(f" {line}") if fatal: print() print(f" ✗ {len(fatal)} 条**未定义名**(运行到这行会 NameError):") for line in fatal: print(f" {line}") return 1 print(" ✓ 没有会导致崩溃的问题") return 0 if __name__ == "__main__": sys.exit(main())