# -*- coding: utf-8 -*- """Самопроверка сгенерированного кода (безопасно, без исполнения). Возвращает (ok, message). Ловит синтаксические ошибки и неопределённые имена. """ import ast import io def check_python(code): """Проверяет Python-код. Безопасно — ничего не исполняет.""" if not code or not code.strip(): return False, "пустой код" # 1) синтаксис (ast) try: ast.parse(code) except SyntaxError as e: return False, f"SyntaxError: {e.msg} (строка {e.lineno})" # 2) компиляция в байткод (ловит чуть больше, всё ещё без исполнения) try: compile(code, "", "exec") except Exception as e: return False, f"CompileError: {type(e).__name__}: {e}" # 3) pyflakes — только неопределённые имена (типовые опечатки/пропущенные импорты) try: from pyflakes.api import check as _pf from pyflakes.reporter import Reporter buf = io.StringIO() _pf(code, "", Reporter(buf, buf)) undef = [ln.strip() for ln in buf.getvalue().splitlines() if "undefined name" in ln] if undef: return False, "Неопределённые имена: " + "; ".join(undef)[:400] except ImportError: pass except Exception: pass return True, "ок" def check_js(code): """Проверяет JS/TS синтаксис через node --check (если node установлен).""" import subprocess import tempfile import os if not code.strip(): return False, "пустой код" fd, path = tempfile.mkstemp(suffix=".js") try: with os.fdopen(fd, "w", encoding="utf-8") as f: f.write(code) r = subprocess.run(["node", "--check", path], capture_output=True, text=True, timeout=30) if r.returncode != 0: return False, "JS: " + (r.stderr or r.stdout).strip()[:300] return True, "ок" except FileNotFoundError: return True, "ок (node не установлен — проверка пропущена)" except Exception as e: return False, f"JS check: {e}" finally: try: os.remove(path) except OSError: pass