Files
Robert Honz 554a42860e chore: 📝 add comprehensive coding standards and guidelines
* Introduced a new `AGENTS.md` file containing detailed coding standards for the project.
* Covers topics such as Python version support, naming conventions, type annotations, error handling, and best practices.
* Aims to improve code quality, maintainability, and team consistency.
2025-11-12 14:18:41 +01:00

209 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
applyTo: "**/*.py"
---
# Project General Coding Standards
## Python Version Support
- Target Python 3.12 and 3.13
- Use modern Python features supported by the minimum version (3.12)
- Avoid deprecated features and use future-proof syntax
## Naming Conventions
- Use snake_case for variable and function names
- Use CamelCase for class names
- Follow PEP 8 style guidelines strictly
- Prefix private class members with underscore (\_)
- Use ALL_CAPS for constants
- Use descriptive names that clearly indicate purpose and content
- Avoid single-letter variable names except for loop counters or mathematical contexts
## Type Annotations
- Use type annotations for ALL function and method parameters, return types, and variables (PEP 484)
- Use modern built-in generics: `list`, `dict`, `set`, `tuple` instead of `List`, `Dict`, `Set`, `Tuple` from `typing`
- Use `None` type for optional parameters: `str | None` instead of `Optional[str]`
- Use union types with `|` operator: `int | str` instead of `Union[int, str]`
- For complex types, import from `collections.abc`: `Callable`, `Iterable`, etc.
- Always specify generic types: use `list[str]` not just `list`
- Use `pathlib.Path` for file paths, not `str`
## Error Handling
- Use try/except blocks for operations that may fail
- Always log errors with contextual information using the project's logger
- Catch specific exceptions, avoid bare `except:` clauses
- Use `finally` blocks for cleanup operations
- For HTTP operations with requests library:
- Use timeout parameter (default: `REQUESTS_TIMEOUT_SEC`)
- Implement retry logic with `requests.adapters.Retry` for network operations
- Always close response objects in `finally` blocks or use context managers
- For file operations:
- Use context managers (`with` statement) for file handling
- Use `pathlib.Path` methods for path operations
- Handle `OSError` and its subclasses appropriately
## Code Style and Formatting
- Line length: maximum 120 characters (as configured in Black and Ruff)
- Use Black formatting style with preview features enabled
- Follow isort configuration for import ordering:
1. FUTURE
2. TYPING
3. STDLIB
4. THIRDPARTY
5. FIRSTPARTY
6. LOCALFOLDER
- Include trailing commas in multi-line constructs
- Use more blank lines to achieve better code organization and readability
- Use 4 spaces for indentation (no tabs)
## Modern Python Features
- Follow PEP 492 – Coroutines with async and await syntax (when applicable)
- Follow PEP 498 – Literal String Interpolation (f-strings)
- Follow PEP 572 – Assignment Expressions (walrus operator `:=` when it improves readability)
- Use structural pattern matching (match/case) for Python 3.10+ when appropriate
- Prefer pathlib.Path over os.path for file operations
- Use Enum and StrEnum for constants with related values
- Use dataclasses or dataclasses-json for structured data
## Concurrency and Threading
- Use `concurrent.futures.ThreadPoolExecutor` for I/O-bound parallel operations
- Always use context managers with executors
- Set appropriate `max_workers` based on operation type (use configuration values)
- Handle futures with `futures.as_completed()` for better responsiveness
- Implement abort/cancellation mechanisms using `threading.Event`
- Cancel pending futures when aborting operations
- Use thread-safe data structures when sharing data between threads
- Avoid blocking operations in GUI threads
## Resource Management
- Always use context managers (`with` statements) for:
- File operations
- Network connections
- Thread pools and executors
- Temporary directories and files
- Use `tempfile.TemporaryDirectory` with `ignore_cleanup_errors=True` for temp operations
- Close network responses explicitly in `finally` blocks or use context managers
- Clean up temporary files after processing
- Use `pathlib.Path.unlink(missing_ok=True)` for safe file deletion
## File and Path Handling
- Use `pathlib.Path` exclusively for path operations
- Sanitize file paths using `pathvalidate.sanitize_filename` and project's `path_file_sanitize`
- Use `.expanduser()` for paths that may contain `~`
- Use `.absolute()` to get absolute paths
- Use `.resolve()` to resolve symlinks
- Check file existence with `Path.exists()`, `Path.is_file()`, `Path.is_dir()`
- Use `os.makedirs(path, exist_ok=True)` or `Path.mkdir(parents=True, exist_ok=True)`
- Handle cross-platform path differences automatically with pathlib
## Code Documentation
- Write docstrings for ALL modules, classes, functions, and methods using Google docstring style
- Include type information in docstrings even when type hints are present
- Document all parameters with their types and descriptions
- Document return values with type and description
- Document raised exceptions
- Use line comments to explain complex logic, algorithms, or non-obvious decisions
- When refactoring code:
- Update or add docstrings to reflect new behavior
- Update existing line comments rather than removing them
- Add TODO comments for known limitations or future improvements
## Logging
- Use the project's logger (via `fn_logger` or similar)
- Log levels:
- `debug`: Detailed diagnostic information
- `info`: General informational messages (e.g., download completion)
- `error`: Error conditions with context
- `exception`: Errors with full traceback
- Include relevant context in log messages (file names, IDs, URLs, etc.)
- Use f-strings for log message formatting
## GUI Development (PySide6/Qt)
- Follow Qt naming conventions for slots and signals
- Use type hints for signal parameters
- Emit signals for cross-thread communication (never call GUI methods directly from worker threads)
- Use Qt's threading mechanisms appropriately
- Handle GUI progress updates via signals
- Implement proper cleanup in close events
- Use `QThread` or `ThreadPoolExecutor` for background operations, never block the GUI thread
## API Integration (TIDAL)
- Always check if media is available before processing (`media.available`)
- Handle `tidalapi.exceptions.TooManyRequests` gracefully
- Implement retry logic for transient failures
- Use sessions appropriately
- Handle stream manifests and encryption properly
- Respect API rate limits and implement delays when configured
## Testing
- Place tests in the `tests/` directory
- Use pytest as the testing framework
- Use descriptive test function names: `test_<functionality_being_tested>`
- Test edge cases: empty lists, None values, invalid inputs
- Mock external dependencies (API calls, file system when appropriate)
- Use fixtures for common test setup
- Aim for meaningful test coverage, not just high percentages
## Security
- Never hardcode credentials (use configuration or environment variables)
- Use base64 encoding only for obfuscation, not security
- Handle sensitive data (tokens, keys) carefully
- Use secure temporary file creation
- Validate and sanitize all user inputs, especially file paths
- Handle decryption keys securely (don't log them)
## Performance
- Use generators for large datasets when possible
- Implement streaming for large file downloads
- Use appropriate chunk sizes for file I/O (use `CHUNK_SIZE` constant)
- Cache expensive computations when safe to do so
- Use batch operations where applicable
- Profile code before optimizing
- Consider memory usage for large collections
## Configuration and Settings
- Use the Settings class for all configuration
- Access settings via `self.settings.data.*`
- Validate configuration values
- Provide sensible defaults
- Use type-safe configuration access
- Document configuration options
## Code Quality Tools
- Run Ruff for linting before committing
- Run Black for formatting before committing
- Run mypy for type checking
- Use pre-commit hooks to automate checks
- Address all linting warnings and errors
- Keep code complexity low (avoid deep nesting, long functions)
## Best Practices Summary
1. **Type Safety**: Always use type hints, enable strict mypy checks
2. **Error Handling**: Catch specific exceptions, log with context, clean up resources
3. **Readability**: Write self-documenting code with clear names and structure
4. **Documentation**: Comprehensive docstrings and comments for complex logic
5. **Testing**: Test edge cases and error conditions
6. **Performance**: Use efficient algorithms and data structures
7. **Maintainability**: Keep functions focused, avoid code duplication
8. **Security**: Validate inputs, handle credentials safely
9. **Compatibility**: Support Python 3.12-3.13, handle cross-platform differences
10. **Standards**: Follow PEP 8, PEP 484, and project-specific configurations