# Python Code Quality
Overview of Python code quality tools. Many legacy tools have been replaced by [[Ruff]] and [[ty]].
## Modern Stack
```bash
ruff check --fix . # lint + fix (replaces flake8, isort, pycln, pylint)
ruff format . # format (replaces Black)
ty check . # type check (replaces mypy) — see [[ty]]
```
For most projects, this is all you need. See [[Ruff]] for full configuration.
## Still-Useful Tools
### docformatter
Formats docstrings to PEP 257. Ruff handles code formatting but `docformatter` provides more control over docstring wrapping.
```bash
docformatter --config pyproject.toml --in-place --recursive .
```
```toml
[tool.docformatter]
recursive = true
wrap-summaries = 88
wrap-descriptions = 88
in-place = true
```
## Tool Comparison
| Tool | Type | Speed | Status |
|------|------|-------|--------|
| **[[Ruff]]** | Linter + Formatter | Very Fast | Active — replaces most tools below |
| **[[ty]]** | Type Checker | Very Fast | Active — replacing mypy |
| docformatter | Formatter | Fast | Active — docstring formatting |
| mypy | Type Checker | Medium | Being replaced by [[ty]] |
| pycln | Cleaner | Fast | Replaced by Ruff (`F401`) |
| isort | Formatter | Fast | Replaced by Ruff (`I`) |
| Black | Formatter | Fast | Replaced by `ruff format` |
| pylint | Linter | Slow | Mostly replaced by Ruff |
| flake8 | Linter | Fast | Replaced by Ruff |
## Configuration
### pyproject.toml (modern)
```toml
[tool.ruff]
line-length = 88
target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP", "SIM"]
[tool.ruff.format]
docstring-code-format = true
[tool.docformatter]
recursive = true
wrap-summaries = 88
wrap-descriptions = 88
in-place = true
```
## Pre-commit Hooks
```yaml
repos:
# Get latest version: https://github.com/astral-sh/ruff-pre-commit/releases
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/PyCQA/docformatter
rev: v1.7.5
hooks:
- id: docformatter
args: [--in-place, --config, pyproject.toml]
```
---
## Archive — Legacy Tools
Tools below are superseded by Ruff but documented for reference with older codebases.
### pycln — replaced by Ruff
Removes unused imports. Ruff's `F401` rule covers this.
```bash
pycln .
```
### isort — replaced by Ruff
Sorts imports. Ruff's `I` rules handle import sorting.
```bash
isort .
```
```toml
[tool.isort]
profile = "black"
line_length = 88
```
### Black — replaced by Ruff
Opinionated formatter. `ruff format` is a drop-in replacement.
```bash
black .
```
### pylint — replaced by Ruff
Comprehensive linter. Slower but very thorough. Most rules covered by Ruff's extended rule set.
```bash
pylint .
```
### flake8 — replaced by Ruff
PEP 8 enforcement. Fully covered by Ruff's `E`/`W` rules.
```ini
# .flake8
[flake8]
max-line-length = 88
extend-ignore = E203, E266, E501, W503
exclude = .git,__pycache__,build,dist,.venv
```
### mypy — replaced by ty
Static type checker. Being replaced by [[ty]], which is significantly faster.
```bash
mypy --config pyproject.toml .
```
```toml
[tool.mypy]
disallow_untyped_calls = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
```
---
See also: [[Ruff]], [[ty]], [[uv]], [[Python]]