Files
Jyotisha/tests/test_python_hygiene_budget.py
T
jesse-uxGrok (agent loop)Cursor
2130682d43
Independent Staging Quality Gate / validate (push) Successful in 14m30s
Independent Staging Quality Gate / publish (push) Successful in 3m54s
fix(reading): hold Niryaana Shoola and drop the root helper
The two upstream files stay verbatim in scripts/. The path helper moved into a subdirectory so the root file budget rises by only those two. Niryaana Shoola is a placeholder until its rule is corrected. Targeted tests passed.

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 00:19:57 +08:00

65 lines
2.6 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"
# 原值:446
# 新值:448
# 原因:产品 2026-10-18(issue #81 选 A):上游原样文件按上游路径放在 scripts/ 根目录,
# classical_astrology.py、unified_western_reading.py 两个;本地新写的文件仍不得增加。
ROOT_PY_BUDGET = 448
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