a2a-sin-code-command / app /utils /validators.py
SIN-Deploy-Bot
Deploy via automated script [skip ci]
8e2543b
Raw
History Blame Contribute Delete
3.3 kB
"""Validation utilities for generated code."""
import ast
import os
from pathlib import Path
from typing import List, Optional
def validate_python_syntax(file_path: Path) -> tuple[bool, Optional[str]]:
"""Check if a Python file has valid syntax."""
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
ast.parse(content)
return True, None
except SyntaxError as e:
return False, f"Syntax error at line {e.lineno}: {e.msg}"
except Exception as e:
return False, str(e)
def validate_required_files_exist(repo_dir: Path, required_files: List[str]) -> List[str]:
"""Check that required files exist in the repository."""
missing = []
for file in required_files:
if not (repo_dir / file).exists():
missing.append(file)
return missing
def validate_imports(file_path: Path) -> List[str]:
"""Check for likely missing imports (basic heuristic)."""
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
tree = ast.parse(content)
defined_names = set()
used_names = set()
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
defined_names.add(node.name)
elif isinstance(node, ast.Name) and isinstance(node.ctx, ast.Load):
used_names.add(node.id)
elif isinstance(node, ast.Attribute):
# Capture attribute access like os.path
if isinstance(node.value, ast.Name):
used_names.add(f"{node.value.id}.{node.attr}")
undefined = used_names - defined_names - set(__builtins__.keys())
# Filter out likely imports from standard library and common packages
common_imports = {
"os",
"sys",
"json",
"logging",
"typing",
"Path",
"Optional",
"List",
"Dict",
"Any",
"Union",
"Callable",
"subprocess",
"requests",
"fastapi",
"gradio",
"uvicorn",
}
possibly_undefined = [n for n in undefined if n not in common_imports]
return possibly_undefined
except Exception:
return []
def validate_file_not_empty(file_path: Path) -> bool:
"""Check that a file has non-empty content."""
return file_path.exists() and file_path.stat().st_size > 10
def validate_has_main_block(file_path: Path) -> bool:
"""Check if Python file has a main execution block."""
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
tree = ast.parse(content)
for node in ast.walk(tree):
if isinstance(node, ast.If):
if (
isinstance(node.test, ast.Compare)
and any(isinstance(op, ast.Eq) for op in node.test.ops)
and any(
isinstance(comp, ast.Name) and comp.id == "__name__"
for comp in node.test.comparators
)
):
return True
return False
except Exception:
return False