0827b2399c
引导器 UEFI.boot.py (纯 stdlib, 内核的管家) 体检 6 项 (解释器/venv/包/驱动目录/PG) / venv 重建 / 包台账 / 内核进程启停记账 / 参数原样透传 内核日志 / 引导器日志 / 内核 stdio 三条道的查看入口都归它 内核 内核/ (常驻调度 = 甲) 命令消费 (PG commands + LISTEN/NOTIFY) / 驱动调用仲裁六条 (越权·成环·无人提供·按需拉起·同锁排队·超时收权) 依赖链巡检 10s / 心跳 300s / 独一份调度锁 (pg_try_advisory_lock 0x65666901) 扫描: 9 条校验 + 契约匹配 + 拓扑排序; 状态: 快照原子写 + 断电收尸判定 db.py 是唯一碰 SQL 的文件 (drivers/driver_state/events/scans/commands/calls/kernel_env/kernel_runs) 日志系统 (2026-09-16 完整化, 设计/04-日志系统.md) 三条道一个文件一种内容: 内核.log (结构化行) / 内核.out.log (命令输出 + 崩溃原文) / 引导器.log (引导器动作) 驱动日志每轮启动前插分隔头; 门槛 log_level / 轮转 log_max_mb + log_keep / -n · -f · --级别 · -g · --json · --全部 实现 内核/日志.py (内核与引导器共用一份); 修掉"命令输出混进日志文件" (实证存档 归档/20260916-日志系统重做前/) 驱动样板 (也是写驱动的示范): Json解码 (oneshot) / 样板常驻 (provides 样板:心跳) / 样例消费器 (needs 只发契约名) 代码标点统一为 ASCII (保留界面用的框线 ─│◄▶ 与表格占位符 —); 已用 AST 等价对比证明逻辑零改动 自测 (真机, 不 mock): 进程 (真起进程真收子树) / 内核 58 项 / 配置 / db 182 项 / 日志 86 项 验收: 试跑引导器.py PASS 11 / FAIL 0 / 残留无; uvx pyright 与 uvx basedpyright 均 0 errors 0 warnings
77 lines
2.8 KiB
Python
77 lines
2.8 KiB
Python
"""AST 等价对比: 证明"只改了注释/docstring", 逻辑一行没动.
|
|
|
|
[什么时候用]
|
|
大改注释,重排文档串,批量扫标点之后, 拿改前改后的两份文件比一次 --
|
|
比"我觉得没改逻辑"可靠得多 (人工重抄 1000 行, 抄错一行很难自己发现).
|
|
|
|
用法:
|
|
python3 内核/自测AST等价.py 改前.py 改后.py
|
|
|
|
判据:
|
|
去掉 docstring (按 AST 摘) 之后, ast.unparse() 的文本逐字符相同 => 逻辑零改动.
|
|
输出里只剩"字符串常量里的标点差异"也算通过 (那是注释/文案的事, 不是逻辑).
|
|
|
|
退出码: 0 等价 / 1 有逻辑差异 / 2 函数与类定义序列都变了
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ast
|
|
import difflib
|
|
import sys
|
|
|
|
|
|
def 去docstring(树: ast.AST) -> ast.AST:
|
|
"""摘掉模块 / 函数 / 类体开头的字符串字面量 docstring; 摘空了补一个 pass 占位."""
|
|
for 节点 in ast.walk(树):
|
|
if isinstance(节点, (ast.Module, ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
|
|
体 = 节点.body
|
|
if (
|
|
体
|
|
and isinstance(体[0], ast.Expr)
|
|
and isinstance(体[0].value, ast.Constant)
|
|
and isinstance(体[0].value.value, str)
|
|
):
|
|
体.pop(0)
|
|
if not 体:
|
|
体.append(ast.Pass())
|
|
return 树
|
|
|
|
|
|
def 载入(路径: str) -> tuple[str, list[str]]:
|
|
"""读一个 .py, 返回 (去 docstring 后的规范化源码, 函数与类名序列)."""
|
|
with open(路径, encoding="utf-8") as 句柄:
|
|
文本 = 句柄.read()
|
|
树 = ast.parse(文本, filename=路径)
|
|
名称 = [
|
|
节点.name
|
|
for 节点 in ast.walk(树)
|
|
if isinstance(节点, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef))
|
|
]
|
|
return ast.unparse(去docstring(树)), 名称
|
|
|
|
|
|
def main(参数: list[str]) -> int:
|
|
if len(参数) != 2:
|
|
print(__doc__)
|
|
return 2
|
|
旧文本, 旧名 = 载入(参数[0])
|
|
新文本, 新名 = 载入(参数[1])
|
|
print(f"函数/类定义数量: 旧 {len(旧名)} -> 新 {len(新名)}")
|
|
if 旧名 != 新名:
|
|
print("[差异] 定义序列变了:")
|
|
print(" 只在新文件:", [x for x in 新名 if x not in 旧名] or "无")
|
|
print(" 只在旧文件:", [x for x in 旧名 if x not in 新名] or "无")
|
|
return 2
|
|
if 旧文本 == 新文本:
|
|
print("[OK] AST 完全等价 -- 除了注释和 docstring, 逻辑一行没动")
|
|
return 0
|
|
print("[差异] 去注释后 AST 不同, 逐行看下面的 diff:")
|
|
差异 = list(difflib.unified_diff(旧文本.splitlines(), 新文本.splitlines(), "改前", "改后", lineterm="", n=2))
|
|
print("\n".join(差异[:200]))
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main(sys.argv[1:]))
|