ZuperAI-14B / toolkit /verify_util.py
Tyesee's picture
toolkit: verify_util.py
828e1e7 verified
Raw History Blame Contribute Delete
2.29 kB
# -*- coding: utf-8 -*-
"""Общие утилиты исполняемой самопроверки (используют verify.py и webui.py)."""
import os
import subprocess
import sys
TEST_SYSTEM = ("Ты — инженер по тестированию. Пиши исчерпывающие юнит-тесты на стандартной "
"библиотеке unittest. Тесты должны реально проверять корректность решения, "
"включая крайние случаи. Не пиши реализацию — только тесты.")
VERIFY_ATTEMPTS = 5
VERIFY_TIMEOUT = 30
def run_tests(code, tests, workdir, timeout=VERIFY_TIMEOUT):
"""Пишет код и тесты в песочницу и гоняет unittest. Возвращает (ok, вывод)."""
with open(os.path.join(workdir, "solution.py"), "w", encoding="utf-8") as f:
f.write(code)
with open(os.path.join(workdir, "test_solution.py"), "w", encoding="utf-8") as f:
f.write(tests)
try:
r = subprocess.run(
[sys.executable, "-m", "unittest", "test_solution", "-v"],
cwd=workdir, capture_output=True, text=True, timeout=timeout,
)
out = (r.stdout or "") + "\n" + (r.stderr or "")
return r.returncode == 0, out.strip()
except subprocess.TimeoutExpired:
return False, f"ТЕСТЫ ЗАВИСЛИ (таймаут {timeout}с)"
def looks_like_tests(text):
"""Эвристика: ответ модели — это тесты или код?"""
return ("import unittest" in text or "unittest" in text
or "class Test" in text or "def test_" in text
or ("assert" in text and "def " not in text))
def tail(s, n=900):
"""Хвост вывода — самое важное (финальный трейсбек)."""
s = s.strip()
return s if len(s) <= n else "…\n" + s[-n:]
def ensure_unittest_header(tests):
"""Если модель забыла импорт unittest — добавляем заглушку-заголовок."""
if "import unittest" not in tests and "unittest" not in tests:
return "import unittest\nfrom solution import *\n\n" + tests
return tests