scripts/p5_ops_strict_modules.py
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env python3
"""P5 *_ops.py modules passing mypy --strict (--follow-imports=skip).
Regenerate: python3 scripts/p5_ops_strict_modules.py --refresh
Gate reads scripts/p5_ops_strict_modules.txt (committed).
"""
from __future__ import annotations
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
LIST_FILE = ROOT / "scripts" / "p5_ops_strict_modules.txt"
EXTRA_MODULES = ("butler/repo_paths.py",)
def _passes_strict(path: Path) -> bool:
r = subprocess.run(
[sys.executable, "-m", "mypy", str(path), "--follow-imports=skip", "--strict"],
cwd=ROOT,
capture_output=True,
text=True,
)
return r.returncode == 0
def _scan_paths() -> list[str]:
paths: list[str] = []
for p in sorted(ROOT.joinpath("butler").rglob("*_ops.py")):
if _passes_strict(p):
paths.append(str(p.relative_to(ROOT)).replace("\\", "/"))
for rel in EXTRA_MODULES:
p = ROOT / rel
if p.is_file() and _passes_strict(p):
paths.append(rel)
return sorted(set(paths))
def _load_committed() -> list[str]:
return [
ln.strip()
for ln in LIST_FILE.read_text(encoding="utf-8").splitlines()
if ln.strip() and not ln.startswith("#")
]
def path_to_module(rel: str) -> str:
return rel.removesuffix(".py").replace("/", ".")
def main() -> int:
if "--refresh" in sys.argv:
paths = _scan_paths()
LIST_FILE.write_text("\n".join(paths) + "\n", encoding="utf-8")
print(f"Wrote {len(paths)} paths to {LIST_FILE.relative_to(ROOT)}")
return 0
paths = _load_committed()
if "--modules" in sys.argv:
for rel in paths:
print(path_to_module(rel))
return 0
for rel in paths:
print(rel)
return 0
if __name__ == "__main__":
raise SystemExit(main())