# GLM Code Quality Instructions ## 1. Error Handling Requirements ### Rule 1.1: Never Use Bare Except ❌ WRONG: ``` except: pass ``` ✓ CORRECT: ``` except (ValueError, TypeError) as e: raise ValueError(f"Invalid input: {e}") ``` ### Rule 1.2: Use Specific Exception Types - ValueError: Invalid input values or parameters - TypeError: Wrong type provided - RuntimeError: Runtime operation failures - KeyError: Missing dictionary keys - IndexError: List index out of range - FileNotFoundError: File operations - ConnectionError: Network/API failures ### Rule 1.3: Provide Detailed Error Messages Include context in every error: - Parameter name and value - What was expected - What was received - How to fix it Example: ``` if not url.startswith(('http://', 'https://')): raise ValueError( f"Invalid URL protocol. " f"Expected HTTP/HTTPS, got URL: {url}" ) ``` ### Rule 1.4: Re-raise with Context When catching exceptions, add context before re-raising: ``` try: result = process_data(input_data) except ValueError as e: raise ValueError( f"Failed to process data for user {user_id}: {e}" ) from e ``` ## 2. Documentation Standards ### Rule 2.1: Comprehensive Docstrings ALL public functions, methods, and classes MUST include complete docstrings: ``` """Brief one-line summary (ends with period). Detailed description explaining the purpose, behavior, and any important implementation details. Include algorithm complexity if relevant. Args: param1 (type): Description of param1, including valid values param2 (type): Description of param2, including defaults if any param3 (Optional[type]): Optional parameter description Returns: type: Description of return value, including possible values or None Raises: ValueError: When param1 is invalid or out of range TypeError: When param2 has wrong type RuntimeError: When operation fails Examples: Basic usage: >>> function_name(arg1, arg2) expected_output Edge case: >>> function_name(None, arg2) Traceback (most recent call last): ... ValueError: param1 cannot be None """ ``` ### Rule 2.2: Class Docstrings Classes must include: - Purpose and responsibility - Main attributes with types - Usage examples - Thread-safety notes (if applicable) - Relationship to other classes Example: ``` """URL shortener service with collision handling. This class provides URL shortening functionality with automatic collision detection and resolution using counter suffixes. Attributes: url_to_code (Dict[str, str]): Maps long URLs to short codes code_to_url (Dict[str, str]): Maps short codes to long URLs code_length (int): Length of generated short codes Example: >>> shortener = URLShortener() >>> code = shortener.shorten_url('https://example.com') >>> original = shortener.expand_url(code) >>> assert original == 'https://example.com' Note: This implementation is not thread-safe. Use locking for concurrent access. """ ``` ### Rule 2.3: Inline Comments - Explain WHY, not WHAT (code shows what) - Document non-obvious business logic - Explain algorithm choices - Note performance considerations - Mark TODOs and FIXMEs Good comment: ``` # Use counter suffix instead of random retry to guarantee uniqueness # and avoid potential infinite loops in high-collision scenarios code = base_code[:4] + str(attempt).zfill(2) ``` Bad comment: ``` # Add suffix to code code = base_code[:4] + str(attempt).zfill(2) ``` ## 3. Input Validation ### Rule 3.1: Validate at Entry Points Check ALL inputs immediately at function entry: ``` def process_url(url: str, timeout: int = 30) -> str: """Process and validate URL.""" # Type validation if not isinstance(url, str): raise TypeError( f"URL must be string, got {type(url).__name__}" ) # Content validation if not url or not url.strip(): raise ValueError("URL cannot be empty or whitespace") # Format validation if not url.startswith(('http://', 'https://')): raise ValueError( f"Invalid URL protocol. Expected HTTP/HTTPS, got: {url}" ) # Parameter range validation if not isinstance(timeout, int) or timeout <= 0: raise ValueError( f"Timeout must be positive integer, got: {timeout}" ) ``` ### Rule 3.2: Handle Edge Cases Always validate and handle: - None values - Empty strings, lists, dictionaries - Boundary values (0, negative numbers, max int) - Special characters and Unicode - Whitespace-only strings - Case sensitivity ### Rule 3.3: Protocol and Format Validation For URLs: - ONLY accept HTTP/HTTPS (unless explicitly requested otherwise) - Validate domain format - Check for malformed URLs - Handle missing schemes gracefully For file paths: - Check existence before operations - Validate permissions - Handle path traversal attempts For numeric inputs: - Validate ranges - Check for NaN and infinity - Handle division by zero ## 4. Type Hints (Python 3.5+) ### Rule 4.1: Use Type Hints Everywhere ALL function signatures MUST include type hints: ``` from typing import Optional, List, Dict, Union, Any, Tuple def parse_data( data: Dict[str, Any], options: Optional[List[str]] = None, strict: bool = False ) -> Union[str, None]: """Parse data with optional settings.""" pass ``` ### Rule 4.2: Complex Type Annotations Use typing module for complex types: ``` from typing import Callable, TypeVar, Generic T = TypeVar('T') def retry( func: Callable[..., T], max_attempts: int = 3 ) -> T: """Retry a function with exponential backoff.""" pass ``` ### Rule 4.3: Return Type Annotations Always specify return types, including None: ``` def find_user(user_id: int) -> Optional[Dict[str, Any]]: """Find user by ID, returns None if not found.""" pass ``` ## 5. Code Quality Best Practices ### Rule 5.1: PEP 8 Compliance (Python) - 4 spaces for indentation (never tabs) - Max line length: 79 characters (88 for Black formatter) - 2 blank lines between top-level functions and classes - 1 blank line between methods in a class - snake_case for functions and variables - PascalCase for classes - UPPER_CASE for constants ### Rule 5.2: Single Responsibility Principle Each function should do ONE thing well: ❌ BAD: ``` def process_user(user_data): # Validates, saves, sends email, logs - too many responsibilities validate(user_data) save_to_db(user_data) send_welcome_email(user_data['email']) log_action('user_created', user_data['id']) ``` ✓ GOOD: ``` def create_user(user_data: Dict[str, Any]) -> User: """Orchestrate user creation process.""" validated_data = validate_user_data(user_data) user = save_user(validated_data) send_welcome_email(user) log_user_creation(user) return user ``` ### Rule 5.3: DRY (Don't Repeat Yourself) Extract common logic into helper functions: ❌ BAD: ``` def func1(data): x = validate_input(data) y = transform_data(x) return y def func2(data): x = validate_input(data) # Duplicated z = other_transform(x) return z ``` ✓ GOOD: ``` def _validate_and_prepare(data): """Common validation and preparation.""" return validate_input(data) def func1(data): x = _validate_and_prepare(data) return transform_data(x) def func2(data): x = _validate_and_prepare(data) return other_transform(x) ``` ### Rule 5.4: Early Returns Reduce nesting with guard clauses and early returns: ❌ BAD: ``` def process(x): if x is not None: if x > 0: if x < 100: result = x * 2 return result return None ``` ✓ GOOD: ``` def process(x): if x is None: return None if x <= 0: return None if x >= 100: return None return x * 2 ``` ### Rule 5.5: Meaningful Names Use clear, descriptive names: ❌ BAD: `def f(x, y)`, `data`, `temp`, `var1` ✓ GOOD: `def calculate_discount(price, discount_rate)`, `user_data`, `validated_email` ## 6. Security Considerations ### Rule 6.1: Input Sanitization NEVER trust user input: - Validate types and formats - Sanitize strings (remove/escape special chars) - Limit input sizes - Escape for context (SQL, HTML, shell commands) ### Rule 6.2: Avoid Hardcoded Secrets ALWAYS use environment variables for sensitive data: ❌ BAD: ``` API_KEY = "sk_live_1234567890abcdef" DB_PASSWORD = "mypassword123" ``` ✓ GOOD: ``` import os API_KEY = os.getenv('API_KEY') if not API_KEY: raise ValueError("API_KEY environment variable not set") DB_PASSWORD = os.getenv('DB_PASSWORD') if not DB_PASSWORD: raise ValueError("DB_PASSWORD environment variable not set") ``` ### Rule 6.3: Safe File Operations - Validate file paths (prevent directory traversal) - Check file permissions - Use context managers for automatic cleanup - Handle encoding explicitly ``` import os def safe_read_file(file_path: str) -> str: """Safely read file with validation.""" # Prevent directory traversal normalized_path = os.path.normpath(file_path) if not normalized_path.startswith(ALLOWED_DIR): raise ValueError("Access to file path denied") # Check existence and permissions if not os.path.exists(normalized_path): raise FileNotFoundError(f"File not found: {file_path}") # Safe reading with explicit encoding with open(normalized_path, 'r', encoding='utf-8') as f: return f.read() ``` ## 7. Language-Specific Guidelines ### Python - Use context managers (`with` statements) for resource management - Prefer list/dict comprehensions for simple transformations - Use f-strings for string formatting (Python 3.6+) - Leverage standard library (don't reinvent the wheel) - Use `pathlib` for file path operations - Use `logging` module instead of print statements - Follow PEP 8 style guide Example: ``` from pathlib import Path import logging logger = logging.getLogger(__name__) def process_files(directory: str) -> List[str]: """Process all text files in directory.""" dir_path = Path(directory) # List comprehension for simple filtering text_files = [ f for f in dir_path.glob('*.txt') if f.is_file() ] results = [] for file_path in text_files: # Context manager for safe file handling with file_path.open('r', encoding='utf-8') as f: content = f.read() results.append(content) logger.info(f"Processed {file_path.name}") return results ``` ### JavaScript/TypeScript - Use `const` by default, `let` when reassignment needed, NEVER `var` - Prefer `async/await` over promise chains - Use optional chaining (`?.`) and nullish coalescing (`??`) - Add JSDoc comments for complex functions - Use strict equality (`===`) instead of loose (`==`) - Use template literals for string interpolation - Handle errors in async functions with try/catch Example: ``` /** * Fetch user data with error handling * @param {number} userId - The user ID to fetch * @returns {Promise} User object or null if not found * @throws {Error} If network request fails */ async function fetchUser(userId) { if (typeof userId !== 'number' || userId <= 0) { throw new TypeError(`Invalid user ID: ${userId}`); } try { const response = await fetch(`/api/users/${userId}`); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const user = await response.json(); return user ?? null; } catch (error) { console.error(`Failed to fetch user ${userId}:`, error); throw error; } } ``` ### Rust - Use Result for error handling - Leverage pattern matching - Use borrowing instead of cloning when possible - Follow Rust naming conventions - Add doc comments (///) for public items ### Go - Use error values, not exceptions - Follow Go naming conventions (MixedCaps) - Use `defer` for cleanup - Add godoc comments - Use interfaces for abstraction ## 8. Testing Considerations ### Rule 8.1: Write Testable Code - Use pure functions when possible (no side effects) - Inject dependencies (don't hardcode) - Avoid global state - Keep functions small and focused ### Rule 8.2: Include Usage Examples in Docstrings Provide realistic, runnable examples: ``` def calculate_discount(price: float, discount_percent: float) -> float: """Calculate final price after discount. Args: price: Original price in dollars discount_percent: Discount percentage (0-100) Returns: Final price after applying discount Raises: ValueError: If price is negative or discount is invalid Examples: Basic usage: >>> calculate_discount(100.0, 20.0) 80.0 No discount: >>> calculate_discount(100.0, 0.0) 100.0 Invalid input: >>> calculate_discount(-100.0, 20.0) Traceback (most recent call last): ... ValueError: Price cannot be negative """ if price < 0: raise ValueError("Price cannot be negative") if not 0 <= discount_percent <= 100: raise ValueError("Discount must be between 0 and 100") return price * (1 - discount_percent / 100) ``` ## 9. Performance Guidelines ### Rule 9.1: Choose Appropriate Data Structures - List: Sequential access, ordered collection - Set: O(1) membership testing, unique items - Dict: O(1) key-value lookup - Deque: O(1) operations at both ends - Tuple: Immutable, slightly faster than list ### Rule 9.2: Avoid Premature Optimization Follow this order: 1. Make it work (correct implementation) 2. Make it right (clean, maintainable code) 3. Make it fast (optimize only if needed and profiled) ### Rule 9.3: Common Performance Patterns ``` # Bad: Repeated lookups for item in items: if item in long_list: # O(n) for each item process(item) # Good: Use set for O(1) lookup long_set = set(long_list) for item in items: if item in long_set: # O(1) for each item process(item) ``` ## 10. Logging and Debugging ### Rule 10.1: Use Appropriate Log Levels ``` import logging logger = logging.getLogger(__name__) # DEBUG: Detailed diagnostic information logger.debug(f"Processing item {i} of {total}") # INFO: General informational messages logger.info(f"Started processing {filename}") # WARNING: Warning messages for unexpected but handled situations logger.warning(f"Rate limit approaching: {current}/{limit}") # ERROR: Error messages for failures logger.error(f"Failed to process {filename}: {error}") # CRITICAL: Critical issues requiring immediate attention logger.critical(f"Database connection lost, shutting down") ``` ### Rule 10.2: Include Context in Logs ❌ BAD: ``` logger.error("Processing failed") ``` ✓ GOOD: ``` logger.error( f"Failed to process URL {url} for user {user_id}: {str(e)}", exc_info=True, # Include stack trace extra={'user_id': user_id, 'url': url} ) ``` ## Summary Checklist Before submitting code, verify: ✅ **Error Handling** - [ ] No bare `except:` clauses - [ ] Specific exception types used - [ ] Detailed error messages with context - [ ] Proper error propagation ✅ **Documentation** - [ ] All public functions have comprehensive docstrings - [ ] Args, Returns, Raises sections present - [ ] Usage examples included - [ ] Inline comments explain WHY, not WHAT ✅ **Input Validation** - [ ] All inputs validated at entry - [ ] Type checking performed - [ ] Edge cases handled (None, empty, boundaries) - [ ] Protocol/format validation for URLs, paths, etc. ✅ **Type Hints** - [ ] All function signatures have type hints - [ ] Return types specified - [ ] Complex types use typing module ✅ **Code Quality** - [ ] PEP 8 compliant (Python) or language standard - [ ] Single Responsibility Principle followed - [ ] No code duplication (DRY) - [ ] Early returns used to reduce nesting - [ ] Meaningful variable and function names ✅ **Security** - [ ] Input sanitization performed - [ ] No hardcoded secrets - [ ] Safe file operations - [ ] SQL injection prevention (if applicable) ✅ **Testing** - [ ] Code is testable (pure functions, dependency injection) - [ ] Docstring examples are runnable - [ ] Edge cases considered ✅ **Performance** - [ ] Appropriate data structures chosen - [ ] No obvious inefficiencies - [ ] Not prematurely optimized ✅ **Logging** - [ ] Appropriate log levels used - [ ] Contextual information included - [ ] No sensitive data in logs