Google Python Style Guide
Announce
Using the python-google-style-guide skill for Python write/review/format.
Read order
- Tier-A checklist below — enforce on every edit.
- Topic detail only as needed:
- language-rules.md — §2 language decisions
- style-rules.md — §3 formatting, docs, naming, main
- typing.md — §2.21 + §3.19
- examples.md — Yes/No pairs when writing or correcting a pattern
- references.md — naming table, import order, TODO, formatter commands
Workflow (this repo)
- Format first — Black + isort via root
pyproject.toml(line-length = 80), run with uv. Do not hand-fight Black on cosmetics. - Lint —
uv run pylint --rcfile=.pylintrc <paths>(existing Google-style rc; do not replace it). - 80-column exceptions — long imports, URLs/paths in comments, long no-whitespace constants, pylint disables. If Black cannot bring a line under 80, exceeding is allowed; break manually when sensible.
- Local consistency — match surrounding style for non-cosmetic conflicts; prefer modern guide rules for new code.
uv sync --group dev
uv run black .
uv run isort .
uv run pylint --rcfile=.pylintrc <paths>
Tier A — enforce every edit
- Imports — packages/modules only; full package paths; no relative imports;
typing/collections.abc/typing_extensionssymbol imports OK; groups:__future__→ stdlib → third-party → project; lex sort within groups - Defaults — no mutable default args (
[],{}); no call-time defaults liketime.time() - Exceptions — no bare
except:; catchExceptiononly to re-raise or isolate; noassertfor production validation (pytest OK) - Resources — close files/sockets via
with(orcontextlib.closing) - Types — annotate public APIs; use
X | None; parameterize generics (Sequence[str], not bareSequence) - Naming —
snake_casemodules/functions,CapWordsclasses/exceptions,CAPSconstants,_for internal - Docstrings — public / nontrivial / non-obvious; sections
Args:/Returns:orYields:/Raises:as needed; summary ≤80 chars ending.?! - Logging — literal pattern + args (
logger.info('x=%s', x)), not f-string as first arg - Main — executable logic in
main()behindif __name__ == '__main__' - Comprehensions — simple only; no multiple
for/ filter clauses - pylint —
# pylint: disable=symbol(+ reason if unclear); unused args:del x # Unused.
Tier B — flag in review
- Properties only for cheap, unsurprising access; plain attrs when get/set is trivial
- Never
staticmethod(prefer module function);classmethodonly for named constructors / class-global state - Implicit truthiness OK; always
is None/is not None; never== False; careful with ints / Numpy - Avoid power features (metaclasses, import hacks, custom
__del__cleanup, etc.) - No string
+=in loops — list +joinorStringIO - Soft rethink at ~40 lines per function
- TODO:
# TODO: <bug-or-context> - explanation. @override: docstring optional unless contract changes; without@override, docstring required
Additional resources
- references.md
- language-rules.md
- style-rules.md
- typing.md
- examples.md