| name | python-styleguide |
| description | Use when writing, editing, or reviewing Python (.py) source in a dexpace project — enforces the dexpace Python styleguide (full type hints, dataclasses + Protocols, structured asyncio, 50-line function cap). Also use before committing Python, or when asked to review Python against the styleguide. |
Python styleguide
Extends PEP 8 / PEP 20 / PEP 484+604 / PEP 695 plus the Google Python Style Guide; where they conflict, the PEPs win, except the deviations below. Target Python 3.12+.
When this applies
Editing *.py, or reviewing Python. Priority: correctness > performance > developer experience.
Non-negotiables
- Data + functions:
@dataclass for state, plain functions and Protocol for behavior. No inheritance for code reuse, no deep hierarchies.
- Explicit over implicit: every dependency in the signature or constructor, every error raised. No module-level side effects on import. Library options follow documented defaults.
- Immutable by default:
frozen=True dataclasses, tuple/frozenset over mutable collections, no mutable default arguments.
- Errors are values, handled explicitly: custom exception hierarchies, no bare
except:, no silent pass. Chain with raise ... from cause.
- Composition over inheritance:
Protocol seams and mixins where reuse is needed without an "is-a"; ABCs only for genuine shared implementation.
- Transform, don't mutate: pure helpers in, new output out; push I/O and state changes to the boundary.
- Always say why: comments and docstrings explain reasoning, not mechanics.
- Assert aggressively: ≥2 checks per function on average; validate at every public boundary, split compound checks, fail fast.
- Limits on everything: bound every loop, queue, retry, timeout, task list, cache. No unbounded
while True, no recursion where iteration works.
- Small functions: one thing each; 50-line hard cap, aim 10–25; blank lines between logical sections.
- Performance from the outset: optimize the slowest resource first (network > disk > memory > CPU); profile before tuning.
- Zero technical debt:
__all__ declares the surface, semver is a promise, do it right the first time.
Language hard rules
- Type every public signature, return included;
| over Optional, list[X] over List[X], PEP 695 type aliases and def f[T](...) generics. No Any in public APIs — use object, a Protocol, or a type variable. mypy strict is the gate.
@dataclass(frozen=True, slots=True) value types plus Protocol contracts; no inheritance for reuse. Validate invariants in __post_init__, multi-source construction through @classmethod factories returning Self.
- Model sealed sets as
Literal-discriminated unions or StrEnum; match over them stays exhaustive with assert_never so mypy flags a missing variant.
- Errors: raise specific exceptions, never bare
Exception; custom domain hierarchies; chain with raise ... from; contextlib.suppress for the deliberate ignore; assert for internal invariants only (stripped under -O), if not ...: raise for input validation. Don't return None/bool to signal failure.
- Assertion density is an explicit overlay the language doesn't ask for — Python culture is "validate at the boundary, trust internally". Keep the density: validate at every public boundary, split compound checks, fail fast with a clear message.
- Structured concurrency:
asyncio.TaskGroup over bare gather, asyncio.timeout on every external call, hold task references, re-raise CancelledError. threading/multiprocessing only when forced, justified against the decision tree.
- Idioms used deliberately: context managers, generators, comprehensions (≤2 lines, one
if), EAFP, pathlib, f-strings, match/case, collections.abc hints.
- Resources:
with/async with on every paired lifecycle, never __del__ for cleanup; bounded pools and queues; secrets/os.urandom for cryptographic randomness; timeouts on external I/O.
- Ruff is lint + format; mypy strict;
pyproject.toml is the single source of config.
Before you finish — verify
ruff format .
ruff check .
mypy --strict .
pytest
Full guide
Deep review
For a full audit (not a quick edit), read reference/checklist.md in this skill and walk every chapter.