muse-agent-example/tests/架构/test_元数据不能跨模块写值.py
zizi 50a5522014 W01 落实合同与逐用例工作清单:合同与逐用例工作清单落实(接口契约、文件设计与用例页)。
按 R2 串行阶段整理提交;包内文件为该阶段交付(含后续小增量),状态以工作包清单为准。
2026-09-10 19:25:40 +08:00

32 lines
1.5 KiB
Python

"""S04 只能持久化自己的结构定义,实例值由具名业务 owner 保存。"""
import ast
import re
from pathlib import Path
def test_元数据仅访问自有定义且无动态表名__a40020() -> None:
根 = Path(__file__).resolve().parents[2] / "src/muse/元数据"
数据表 = set()
for 文件 in 根.glob("*.py"):
树 = ast.parse(文件.read_text())
for 节点 in ast.walk(树):
if isinstance(节点, ast.ImportFrom) and 节点.level:
assert 节点.level == 1, f"{文件.name} 跨入其他模块内部"
if isinstance(节点, ast.ImportFrom) and 节点.module and not 节点.level:
assert not 节点.module.startswith("muse.") or 节点.module.startswith("muse.共享.")
if isinstance(节点, ast.Call) and getattr(节点.func, "attr", None) == "Identifier":
raise AssertionError(f"{文件.name} 不得接受动态表列名")
if isinstance(节点, ast.Constant) and isinstance(节点.value, str):
表 = re.findall(
r"\b(?:FROM|JOIN|INSERT\s+INTO|UPDATE(?!\s+SET))\s+([\w.]+)",
节点.value,
flags=re.I,
)
if 表:
assert 文件.name == "存储.py", f"{文件.name} 绕过 S04 存储归属"
assert all(t.startswith("metadata.") for t in 表), 表
数据表.update(表)
assert "metadata.schema_version" in 数据表
assert "metadata.schema_binding" in 数据表