Spaces:
Running
Running
| """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 | |