Files
Jyotisha/tests/test_python_hygiene_budget.py
T
Jesse_ChenandClaude Opus 5.5 0594afcd5c Remove 11 closure ledger scripts only their own tests used (issue #138, BUG-1481)
Batch 1 of the scripts/ root cleanup: the closure scripts no runtime entry,
other script, workflow, deploy file, ops doc or quality gate reaches, with
their 11 test files (30 cases). Their references/ outputs stay. Scripts still
imported elsewhere, named by the gate, or listed in archived reference indexes
are kept. Root budget 452 -> 441.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:43:08 +08:00

64 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Budgets that only allow the silent-except and scripts-root counts to fall."""
from __future__ import annotations
import ast
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SCRIPTS = ROOT / "scripts"
# Measured at the end of TASK-python-hygiene-20261013. New silent handlers
# must log or carry ``# noqa: BLE001`` with a reason. New research scripts
# belong in scripts/audit or scripts/research.
# 原值:0
# 新值:1
# 原因:产品 2026-10-18(issue #81 选 A)要求 classical_astrology.py 保持上游原文。
# 其中 scripts/classical_astrology.py:12558 是 except Exception: continue。本单不得改这个文件。
# 本地新写的静默处理仍不得出现;允许的命中只有这一处。
SILENT_EXCEPT_BUDGET = 1
UPSTREAM_SILENT_EXCEPT = "scripts/classical_astrology.py:12558"
# 原值:448 → 452(issue #94:上游原样文件按上游路径放根目录;本地新写的文件仍不得增加)
# 新值:441
# 原因:issue #138 删除 11 个只被自己的测试引用的 closure 类台账脚本,预算同步下调
ROOT_PY_BUDGET = 441
def _silent_handlers() -> list[str]:
hits: list[str] = []
paths = list(SCRIPTS.glob("*.py")) + [ROOT / "mcp_server.py"]
for path in paths:
source = path.read_text(encoding="utf-8")
lines = source.splitlines()
tree = ast.parse(source)
for node in ast.walk(tree):
if not isinstance(node, ast.ExceptHandler):
continue
typ = node.type
broad = typ is None or (isinstance(typ, ast.Name) and typ.id in {"Exception", "BaseException"})
if not broad or len(node.body) != 1:
continue
stmt = node.body[0]
silent = isinstance(stmt, (ast.Pass, ast.Continue)) or (
isinstance(stmt, ast.Return)
and (stmt.value is None or (isinstance(stmt.value, ast.Constant) and stmt.value.value is None))
)
if not silent:
continue
segment = "\n".join(lines[node.lineno - 1: node.end_lineno])
if "noqa: BLE001" in segment:
continue
hits.append(f"{path.relative_to(ROOT).as_posix()}:{node.lineno}")
return hits
def test_silent_except_budget_does_not_grow() -> None:
hits = _silent_handlers()
assert hits == [UPSTREAM_SILENT_EXCEPT]
assert len(hits) <= SILENT_EXCEPT_BUDGET, hits
def test_scripts_root_py_count_does_not_grow() -> None:
count = len(list(SCRIPTS.glob("*.py")))
assert count <= ROOT_PY_BUDGET, count