#!/usr/bin/env python3 """Python syntax checker - verifies .py files for syntax errors.""" import ast import sys from pathlib import Path def check_python_syntax(filepath: str) -> tuple[bool, str]: """Check if a Python file has valid syntax. Returns: tuple: (is_valid, error_message) """ try: with open(filepath, 'r', encoding='utf-8') as f: source = f.read() ast.parse(source, filename=filepath) return True, "" except SyntaxError as e: return False, f"{filepath}:{e.lineno}:{e.offset}: {e.msg}" except Exception as e: return False, f"{filepath}: {type(e).__name__}: {e}" def check_dir(directory: str, recursive: bool = False) -> dict: """Check all Python files in a directory. Returns: dict: {valid_count, invalid_count, errors: [...]} """ results = {"valid_count": 0, "invalid_count": 0, "errors": []} path = Path(directory) if recursive: files = path.rglob("*.py") else: files = path.glob("*.py") for f in files: is_valid, error = check_python_syntax(str(f)) if is_valid: results["valid_count"] += 1 else: results["invalid_count"] += 1 results["errors"].append(error) return results if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: python python_syntax_checker.py [--recursive]") sys.exit(1) target = sys.argv[1] recursive = "--recursive" in sys.argv if Path(target).is_file(): valid, error = check_python_syntax(target) if valid: print(f"OK: {target}") sys.exit(0) else: print(f"SYNTAX ERROR: {error}") sys.exit(1) else: results = check_dir(target, recursive) print(f"Valid: {results['valid_count']}, Invalid: {results['invalid_count']}") for err in results['errors']: print(f" {err}") sys.exit(0 if results['invalid_count'] == 0 else 1)