#!/usr/bin/env python3 """Quick email validation utility. Validates email format without external dependencies.""" import re from typing import NamedTuple class EmailValidationResult(NamedTuple): """Result of email validation.""" is_valid: bool normalized: str | None error: str | None = None def validate_email(email: str) -> EmailValidationResult: """Validate email address format. Args: email: Email address to validate Returns: EmailValidationResult with validation status """ if not email: return EmailValidationResult(False, None, "Email is empty") email = email.strip().lower() # Basic RFC 5322-inspired pattern pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' if not re.match(pattern, email): return EmailValidationResult(False, None, "Invalid email format") local, _, domain = email.rpartition('@') if len(local) > 64: return EmailValidationResult(False, None, "Local part too long (>64 chars)") if len(domain) > 253: return EmailValidationResult(False, None, "Domain part too long (>253 chars)") # Check for consecutive dots if '..' in email: return EmailValidationResult(False, None, "Consecutive dots not allowed") return EmailValidationResult(True, email) if __name__ == "__main__": test_emails = [ "test@example.com", " USER@Example.COM ", "invalid-email", "bad..email@example.com", "", "valid.email+tag@subdomain.example.org" ] print("Email Validation Results:") print("-" * 60) for email in test_emails: result = validate_email(email) status = "✓ VALID" if result.is_valid else f"✗ INVALID: {result.error}" print(f"{email!r:45} -> {status}")