Python Linting with Ruff
Configure and use Ruff as the primary linter and formatter for Python projects. Ruff is an extremely fast Python linter and formatter written in Rust that replaces flake8, isort, pyupgrade, and many other tools.
When to Use This Skill
-
Setting up linting for new Python projects
-
Migrating from flake8/pylint/isort to Ruff
-
Configuring pyproject.toml for code quality
-
Fixing linting errors and warnings
-
Integrating linting into CI/CD pipelines
Standard Ruff Configuration
Add this configuration to pyproject.toml :
[tool.ruff] line-length = 120 target-version = "py311" lint.select = [ "A", # flake8-builtins "B", # flake8-bugbear "C4", # flake8-comprehensions "E", # pycodestyle - errors "F", # pyflakes "I", # isort "RUF", # ruff specific rules "S", # flake8-bandit (security) "UP", # pyupgrade "W", # pycodestyle - warnings ] lint.ignore = ["S603", "A005"] extend-exclude = ["src/generated/*"]
[tool.ruff.lint.per-file-ignores] "tests/*" = ["S101"] # Allow assert statements in tests
[tool.ruff.lint.isort] known-first-party = ["orchestrator"]
Rule Categories Explained
Rule Set Purpose Examples
A
Prevents shadowing Python builtins id , list , type as variable names
B
Catches likely bugs and design issues Mutable default arguments, except: without type
C4
Improves comprehension usage Unnecessary list() calls, better dict comprehensions
E
PEP 8 style errors Line length, whitespace issues
F
Pyflakes errors Undefined names, unused imports
I
Import sorting (isort replacement) Alphabetical, grouped imports
RUF
Ruff-specific rules Python-specific improvements
S
Security issues (bandit replacement) Hardcoded passwords, SQL injection
UP
Python upgrade suggestions Modern syntax, deprecated features
W
PEP 8 style warnings Trailing whitespace, blank lines
Common Ignored Rules
Rule Reason
S603
subprocess call without shell=True - often needed
A005
Module shadowing built-in - sometimes unavoidable
S101
Use of assert - allowed in tests only
Workflow Commands
Check for Issues
Check all files
uv run ruff check src/
Check specific file
uv run ruff check src/orchestrator/main.py
Show all issues with explanations
uv run ruff check src/ --explain
Auto-fix Issues
Fix auto-fixable issues
uv run ruff check src/ --fix
Fix and show what changed
uv run ruff check src/ --fix --diff
Fix unsafe fixes too (review changes!)
uv run ruff check src/ --fix --unsafe-fixes
Format Code
Format all files
uv run ruff format src/
Check formatting without changing
uv run ruff format src/ --check
Show formatting diff
uv run ruff format src/ --diff
Integration with Other Tools
Pyright (Type Checking)
[tool.pyright] reportMissingImports = true reportMissingTypeStubs = false pythonVersion = "3.12" venvPath = "." venv = ".venv"
Rope (Refactoring)
[tool.rope] py_version = "3.10" ignored_resources = [ ".pyc", "~", ".ropeproject", ".hg", ".svn", "_svn", ".git", ".tox", ".venv", "venv", "node_modules", ]
Codespell (Spell Checking)
[tool.codespell] count = true quiet-level = 3 ignore-words-list = "basf,BASF,NotIn" skip = "src/generated/**,package-lock.json,*.svg,CHANGELOG.md"
CI/CD Integration
GitHub Actions Workflow
name: Lint
on: [push, pull_request]
jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v3 - run: uv sync - run: uv run ruff check src/ - run: uv run ruff format src/ --check
Pre-commit Hook
.pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
- id: ruff args: [--fix]
- id: ruff-format
Adding Ruff to a Project
Install Ruff as dev dependency
uv add ruff --dev
Add configuration to pyproject.toml (See Standard Ruff Configuration above)
Run initial check
uv run ruff check src/
Fix auto-fixable issues
uv run ruff check src/ --fix
Format code
uv run ruff format src/
Troubleshooting
Too Many Errors Initially
Start with fewer rules and add more over time:
[tool.ruff] lint.select = ["E", "F", "I"] # Start minimal
Conflicting with Black
Ruff format is compatible with Black. If using both, let Ruff format handle everything:
Remove black, use ruff format
uv remove black
Import Sorting Issues
Configure first-party packages:
[tool.ruff.lint.isort] known-first-party = ["orchestrator", "mypackage"]
Resources
-
Ruff Documentation
-
Ruff Rules Reference
-
Ruff Configuration
-
Ruff vs Other Linters