diff --git a/scripts/security/mutation_check.py b/scripts/security/mutation_check.py index 91d30d9..f91d86f 100644 --- a/scripts/security/mutation_check.py +++ b/scripts/security/mutation_check.py @@ -22,11 +22,24 @@ Format (Pfade relativ zur TOML-Datei): from __future__ import annotations +import os import subprocess # nosec B404 - Tests starten ist der Zweck des Skripts import sys import tomllib from pathlib import Path +# Python prüft .pyc nur über Quell-mtime (Sekunden) und Größe. Eine gleich lange Mutation, +# die in derselben Sekunde geschrieben oder zurückgesetzt wird, liefe sonst mit dem alten +# Bytecode: Mutation wirkt nicht bzw. bleibt nach dem Lauf aktiv (llm-server, 2026-10-17). +TEST_ENV = {**os.environ, "PYTHONDONTWRITEBYTECODE": "1"} + + +def _write(target: Path, text: str) -> None: + target.write_text(text, encoding="utf-8") + if target.suffix == ".py": + for pyc in (target.parent / "__pycache__").glob(f"{target.stem}.*.pyc"): + pyc.unlink(missing_ok=True) + def run(config_path: Path) -> int: base = config_path.parent @@ -39,7 +52,7 @@ def run(config_path: Path) -> int: return 1 # Vorbedingung: ohne Mutation muss alles grün sein, sonst beweist Rot nichts. - baseline = subprocess.run(test_cmd, cwd=workdir, capture_output=True, text=True) # noqa: S603 # nosec B603 + baseline = subprocess.run(test_cmd, cwd=workdir, capture_output=True, text=True, env=TEST_ENV) # noqa: S603 # nosec B603 if baseline.returncode != 0: print("Tests sind schon ohne Mutation rot – erst reparieren.\n") print(baseline.stdout[-3000:]) @@ -55,10 +68,10 @@ def run(config_path: Path) -> int: survivors.append(mutation["name"]) continue try: - target.write_text(original.replace(mutation["old"], mutation["new"]), encoding="utf-8") - result = subprocess.run(test_cmd, cwd=workdir, capture_output=True, text=True) # noqa: S603 # nosec B603 + _write(target, original.replace(mutation["old"], mutation["new"])) + result = subprocess.run(test_cmd, cwd=workdir, capture_output=True, text=True, env=TEST_ENV) # noqa: S603 # nosec B603 finally: - target.write_text(original, encoding="utf-8") + _write(target, original) if result.returncode == 0: print(f"[ÜBERLEBT] {mutation['name']}: Tests bleiben grün") survivors.append(mutation["name"])