Linting Guide
Code quality checks and linting for the Are You Not Entertained (AYNE) project using Ruff and other tools.
Quick Start
# Run all linting checks
uv run ruff check src/ scripts/ tests/
# Auto-fix issues where possible
uv run ruff check --fix src/ scripts/ tests/
# Type checking
uv run mypy src/ scripts/ tests/ --ignore-missing-imports
# Security scan
uv run bandit -r src/
Ruff Linter
Ruff is an extremely fast Python linter written in Rust, combining the functionality of multiple tools.
Basic Usage
# Lint all source code
uv run ruff check src/
# Lint specific files
uv run ruff check src/ayne/config/schema.py
# Show detailed output
uv run ruff check src/ --output-format=full
# Auto-fix safe issues
uv run ruff check --fix src/ scripts/ tests/
What Ruff Checks
Ruff implements rules from multiple linters:
- pycodestyle (E, W) - PEP 8 style violations
- pyflakes (F) - Logical errors and undefined names
- isort (I) - Import sorting
- pydocstyle (D) - Docstring conventions
- pylint (PL) - Advanced code analysis
- And many more - See Ruff rules
Configuration
Settings in pyproject.toml:
[tool.ruff]
line-length = 100
target-version = "py311"
fix = true
[tool.ruff.lint]
select = ["E", "W", "F", "I", "B", "C4", "D"]
ignore = [
"E501", # Line too long (handled by formatter)
"B008", # Function call in argument defaults
"D203", # 1 blank line before class (conflicts with D211)
"D213", # Multi-line docstring summary second line
]
[tool.ruff.lint.pydocstyle]
convention = "google"
Type Checking with Mypy
Static type checking catches bugs before runtime.
Mypy Usage
# Type check source code
uv run mypy src/
# Include scripts and tests
uv run mypy src/ scripts/ tests/
# Ignore missing imports
uv run mypy src/ --ignore-missing-imports
# Show error codes
uv run mypy src/ --show-error-codes
Mypy Configuration
Settings in pyproject.toml:
[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
no_implicit_optional = true
[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false
Type Hint Guidelines
Always use type hints for function signatures:
# Good
def process_data(year: int, month: int) -> pd.DataFrame:
"""Process data for period."""
pass
# Bad
def process_data(year, month):
"""Process data for period."""
pass
Use typing module for complex types:
from typing import Optional, List, Dict, Tuple
from pathlib import Path
def load_files(
directory: Path,
patterns: List[str],
limit: Optional[int] = None
) -> Dict[str, pd.DataFrame]:
"""Load files matching patterns."""
pass
Security Scanning with Bandit
Bandit finds common security issues in Python code.
Bandit Usage
# Scan source code
uv run bandit -r src/
# Exclude test files
uv run bandit -r src/ -x tests/
# Show only high severity
uv run bandit -r src/ -ll
# Generate detailed report
uv run bandit -r src/ -f html -o reports/security.html
Bandit Configuration
Settings in pyproject.toml:
Common Security Issues
Hardcoded passwords:
SQL injection:
# Bad
query = f"SELECT * FROM users WHERE id = {user_id}"
# Good
query = "SELECT * FROM users WHERE id = ?"
cursor.execute(query, (user_id,))
Import Sorting
Ruff handles import sorting automatically.
Manual Import Sorting
Import Order
- Standard library imports
- Third-party imports
- Local application imports
# Standard library
import os
import sys
from pathlib import Path
# Third-party
import pandas as pd
import numpy as np
from pydantic import BaseModel
# Local
from ayne.config.schema import Settings
from ayne.utils.calendar import get_days_in_month
Running All Checks
Individual Commands
# Lint with Ruff
uv run ruff check src/ scripts/ tests/
# Format check
uv run ruff format --check src/ scripts/ tests/
# Type check
uv run mypy src/ scripts/ tests/ --ignore-missing-imports
# Security scan
uv run bandit -r src/
Combined Script
Create lint.ps1:
# Run all linting checks
Write-Host "Running Ruff linter..." -ForegroundColor Cyan
uv run ruff check src/ scripts/ tests/
if ($LASTEXITCODE -ne 0) { exit 1 }
Write-Host "`nRunning type checker..." -ForegroundColor Cyan
uv run mypy src/ scripts/ tests/ --ignore-missing-imports
if ($LASTEXITCODE -ne 0) { exit 1 }
Write-Host "`nRunning security scanner..." -ForegroundColor Cyan
uv run bandit -r src/ -ll
if ($LASTEXITCODE -ne 0) { exit 1 }
Write-Host "`nAll checks passed!" -ForegroundColor Green
CI/CD Integration
Linting runs automatically in GitHub Actions:
- name: Run ruff linting
run: |
uv run ruff check src/ scripts/ tests/
- name: Run type checking
run: |
uv run mypy src/ scripts/ tests/ --ignore-missing-imports
- name: Run security scan
run: |
uv run bandit -r src/
See .github/workflows/python-lint.yml, .github/workflows/python-typecheck.yml, and .github/workflows/security-audit.yml for complete workflows.
IDE Integration
VS Code
Install extensions:
- Ruff (charliermarsh.ruff)
- Pylance (ms-python.vscode-pylance)
Settings in .vscode/settings.json:
{
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
}
},
"ruff.lint.enable": true,
"ruff.format.enable": true,
"python.linting.enabled": true,
"python.linting.mypyEnabled": true
}
PyCharm
- Install Ruff plugin from marketplace
- Enable Mypy in Settings → Tools → Python Integrated Tools
- Configure to run on save
Common Issues
Ruff Not Found
Type Errors with Third-Party Libraries
# Install type stubs
uv pip install types-boto3
uv pip install pandas-stubs
# Or ignore missing imports
uv run mypy src/ --ignore-missing-imports
Import Order Conflicts
Pre-commit Hooks
Automatically lint before commits:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.8
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.7.1
hooks:
- id: mypy
additional_dependencies: [types-all]
Install hooks:
Best Practices
- Lint early and often - Run checks before committing
- Fix issues immediately - Don't accumulate technical debt
- Use auto-fix - Let tools handle simple fixes
- Understand warnings - Don't blindly ignore issues
- Configure appropriately - Adjust rules for your project
- Integrate with IDE - Get real-time feedback
Related Documentation
- Testing Guide - Test practices and coverage
- Formatting Guide - Code formatting standards
- Security Guide - Security scanning and best practices
- Code Style - General style guidelines
- GitHub Actions Workflows - See
.github/workflows/for automated quality checks