home / skills / wdm0006 / python-skills / code-quality
This skill helps you improve Python library code quality by applying ruff linting, mypy typing, and clean refactoring across projects.
npx playbooks add skill wdm0006/python-skills --skill code-qualityReview the files below or copy the command above to add this skill to your agents.
---
name: improving-python-code-quality
description: Improves Python library code quality through ruff linting, mypy type checking, Pythonic idioms, and refactoring. Use when reviewing code for quality issues, adding type hints, configuring static analysis tools, or refactoring Python library code.
---
# Python Code Quality
## Quick Reference
| Tool | Purpose | Command |
|------|---------|---------|
| ruff | Lint + format | `ruff check src && ruff format src` |
| mypy | Type check | `mypy src` |
## Ruff Configuration
Minimal config in pyproject.toml:
```toml
[tool.ruff]
line-length = 88
target-version = "py310"
[tool.ruff.lint]
select = ["E", "W", "F", "I", "B", "C4", "UP"]
```
For full configuration options, see **[RUFF_CONFIG.md](RUFF_CONFIG.md)**.
## MyPy Configuration
```toml
[tool.mypy]
python_version = "3.10"
disallow_untyped_defs = true
warn_return_any = true
```
For strict settings and overrides, see **[MYPY_CONFIG.md](MYPY_CONFIG.md)**.
## Type Hints Patterns
```python
# Basic
def process(items: list[str]) -> dict[str, int]: ...
# Optional
def fetch(url: str, timeout: int | None = None) -> bytes: ...
# Callable
def apply(func: Callable[[int], str], value: int) -> str: ...
# Generic
T = TypeVar("T")
def first(items: Sequence[T]) -> T | None: ...
```
For protocols and advanced patterns, see **[TYPE_PATTERNS.md](TYPE_PATTERNS.md)**.
## Common Anti-Patterns
```python
# Bad: Mutable default
def process(items: list = []): # Bug!
...
# Good: None default
def process(items: list | None = None):
items = items or []
...
```
```python
# Bad: Bare except
try:
...
except:
pass
# Good: Specific exception
try:
...
except ValueError as e:
logger.error(e)
```
## Pythonic Idioms
```python
# Iteration
for item in items: # Not: for i in range(len(items))
for i, item in enumerate(items): # When index needed
# Dictionary access
value = d.get(key, default) # Not: if key in d: value = d[key]
# Context managers
with open(path) as f: # Not: f = open(path); try: finally: f.close()
# Comprehensions (simple only)
squares = [x**2 for x in numbers]
```
## Module Organization
```
src/my_library/
├── __init__.py # Public API exports
├── _internal.py # Private (underscore prefix)
├── exceptions.py # Custom exceptions
├── types.py # Type definitions
└── py.typed # Type hint marker
```
## Checklist
```
Code Quality:
- [ ] ruff check passes
- [ ] mypy passes (strict mode)
- [ ] Public API has type hints
- [ ] Public API has docstrings
- [ ] No mutable default arguments
- [ ] Specific exception handling
- [ ] py.typed marker present
```
## Learn More
This skill is based on the [Code Quality](https://mcginniscommawill.com/guides/python-library-development/#code-quality-the-foundation) section of the [Guide to Developing High-Quality Python Libraries](https://mcginniscommawill.com/guides/python-library-development/) by [Will McGinnis](https://mcginniscommawill.com/).
This skill improves Python library code quality by applying ruff linting, mypy type checking, Pythonic idioms, and targeted refactors. It focuses on making public APIs typed and documented, removing common anti-patterns, and configuring static analysis for consistent results. Use it when reviewing or hardening library code for distribution and long-term maintenance.
The skill runs ruff to enforce linting and formatting rules and runs mypy for static type checking. It identifies mutable-defaults, bare excepts, untyped public functions, and other common anti-patterns, then suggests idiomatic rewrites and refactors. It also recommends minimal pyproject.toml configurations and module layout changes to support a clean, typed public API.
Will this skill change application logic while refactoring?
No. The goal is to preserve behavior while improving style, types, and safety. Any behavioral changes are flagged and reviewed before applying.
What minimal configs are recommended for ruff and mypy?
Use a pyproject.toml with ruff line-length and target-version plus a select lint list. For mypy, set python_version and enable disallow_untyped_defs and warn_return_any for stricter checks.