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.
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
---
|
||||
applyTo: "**/*.py"
|
||||
---
|
||||
|
||||
# Project general coding standards
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
- Use snake_case for variable and function names.
|
||||
- Use CamelCase for class names.
|
||||
- Follow PEP 8 style guidelines.
|
||||
- Prefix private class members with underscore (\_).
|
||||
- Use ALL_CAPS for constants.
|
||||
|
||||
## Error Handling
|
||||
|
||||
- Use try/except blocks for async operations.
|
||||
- Always log errors with contextual information.
|
||||
|
||||
## Coding Guidelines
|
||||
|
||||
- Use type annotations / hints for function and method parameters, return types and variables. Follow PEP 484.
|
||||
- Use the modern built-in generics from the `typing` module, such as `list`, `dict`, and `set`, instead of the older `List`, `Dict`, and `Set` from `typing`.
|
||||
- Use newest coding style which is supported by the used Python version.
|
||||
- Use more blank lines to achieve better code organization and readability.
|
||||
- Follow PEP 492 – Coroutines with async and await syntax
|
||||
- Follow PEP 498 – Literal String Interpolation
|
||||
- Follow PEP 572 – Assignment Expressions
|
||||
|
||||
## Code Documentation
|
||||
|
||||
- Always write doc strings for all modules, classes, functions, and methods using google docstring style.
|
||||
- Use typing in doc strings.
|
||||
- Use line comments to explain complex logic.
|
||||
- If refactoring code, ensure to update or add doc strings accordingly.
|
||||
- If refactoring code to not remove existing line comments, but to update them to reflect the new code logic.
|
||||
@@ -0,0 +1,208 @@
|
||||
---
|
||||
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
|
||||
Reference in New Issue
Block a user