From coding-standards
Review Python code against team conventions — type safety, data modelling, testing, linting, configuration, and code structure. Auto-invoked when reviewing .py files.
npx claudepluginhub hpsgd/turtlestack --plugin coding-standardsThis skill is limited to using the following tools:
Review Python code against team standards covering type safety, data modeling, testing, linting, configuration, and code structure. Every check has a concrete grep pattern. Every finding requires evidence.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Designs, implements, and audits WCAG 2.2 AA accessible UIs for Web (ARIA/HTML5), iOS (SwiftUI traits), and Android (Compose semantics). Audits code for compliance gaps.
Review Python code against team standards covering type safety, data modeling, testing, linting, configuration, and code structure. Every check has a concrete grep pattern. Every finding requires evidence.
Execute all seven passes. Do not skip.
The project runs mypy --strict. Code must pass without exceptions.
Any usage — grep for explicit Any in type annotations:
grep -rn '\bAny\b' --include='*.py' [changed files]
Every hit is a finding unless it meets one of these conditions:
# type: ignore[import] with comment)The fix: define a Protocol, use object, use a generic TypeVar, or create a specific type.
# type: ignore audit — grep for all type ignore comments:
grep -rn '# type: ignore' --include='*.py' [changed files]
Each must specify the error code: # type: ignore[attr-defined] not bare # type: ignore. Each must have a justification comment on the same or preceding line.
Missing return types — every function must have a return type annotation. Read each function definition in changed files and verify:
grep -rn 'def ' --include='*.py' [changed files]
Functions without -> ReturnType: are findings. This includes __init__ (should be -> None).
Missing parameter types — every parameter must have a type annotation. Only exception: self and cls.
cast() usage — grep for cast(:
grep -rn 'cast(' --include='*.py' [changed files]
Each is a finding unless the alternative is worse (wrapping a poorly-typed library). Prefer type narrowing with isinstance, TypeGuard, or assert.
String annotations — use from __future__ import annotations at the top of every file, or use modern syntax. Quoted forward references ("ClassName") are acceptable only in files without the future import.
Domain models use frozen dataclasses. Not mutable classes. Not dicts. Not NamedTuples (unless there is a specific reason).
Dataclass detection — find all dataclasses in changed files:
grep -rn '@dataclass' --include='*.py' [changed files]
Every @dataclass that represents a domain model must be @dataclass(frozen=True). Mutable dataclasses are acceptable only for configuration or builder patterns — and must have a comment explaining why.
Dict-as-model — grep for dict[str, or Dict[str, in function signatures. If a function passes around a dict that represents a structured entity, it should be a frozen dataclass instead:
grep -rn 'dict\[str\|Dict\[str' --include='*.py' [changed files]
Pydantic models — if the project uses Pydantic, models should use model_config = ConfigDict(frozen=True) for domain objects. Mutable Pydantic models at API boundaries (request/response) are acceptable.
__post_init__ validation — frozen dataclasses should use __post_init__ for validation, not external validator functions. Keep the validation with the data.
The project uses Ruff. Code must be clean.
No lint suppressions without discussion — grep for # noqa:
grep -rn '# noqa' --include='*.py' [changed files]
Every # noqa must:
# noqa: E501 not bare # noqaImport sorting — Ruff handles import sorting (isort-compatible). Verify imports follow the convention:
Line length — default 88 characters (Black-compatible). Lines over this limit without a # noqa: E501 are findings. Long strings should use implicit concatenation or parenthesized line breaks.
f-string vs format — prefer f-strings. str.format() and % formatting are findings unless required for lazy logging (logger.info("msg %s", var) is acceptable for performance).
Config file naming — all configuration files (YAML, TOML, JSON, INI) must use kebab-case:
app-config.yaml, database-settings.tomlappConfig.yaml, app_config.yaml, AppConfig.yamlfind . -name '*.yaml' -o -name '*.toml' -o -name '*.json' -o -name '*.ini' | grep -v node_modules | grep -v __pycache__
Check each config file name against the convention.
Explicit references — all references to external resources (file paths, URLs, environment variables, config keys) must use the explicit {path: ...} form, not implicit string concatenation:
config.get(path="database.connection_string")config["database"]["connection_string"]This applies to the project's specific reference system. Check the codebase for the convention and verify new code follows it.
Environment variable access — grep for os.environ and os.getenv:
grep -rn 'os\.environ\|os\.getenv' --include='*.py' [changed files]
Environment variables should be read once in a configuration module, not scattered throughout the code. Direct os.getenv calls in business logic are findings.
Bare except — grep for except: without an exception type:
grep -rn 'except:' --include='*.py' [changed files]
Every hit is a critical finding. Always specify the exception type.
except Exception: pass — grep for pass in except blocks:
grep -rn 'except.*:' -A1 --include='*.py' [changed files] | grep 'pass'
Swallowed exceptions are critical findings. At minimum, log the exception.
Broad except — except Exception at a level where specific exceptions should be caught. Acceptable only at the top-level entry point (CLI main, web request handler).
Exception chaining — when catching and re-raising, use raise NewError() from original:
grep -rn 'raise.*Error\|raise.*Exception' --include='*.py' [changed files]
Re-raises without from lose the traceback context.
Custom exceptions — new exceptions should inherit from a project base exception, not directly from Exception or ValueError. Check the project for an exception hierarchy.
Tests follow a BDD-style hierarchy: describe the context, then the behavior.
Test naming — test functions must describe behavior, not implementation:
test_when_user_has_no_email_registration_failstest_register, test_1, test_email_validationgrep -rn 'def test_' --include='*.py' [changed test files]
Read each test name. It should tell you what scenario is being tested without reading the body.
Test hierarchy — use class grouping for related tests:
class TestUserRegistration:
class TestWhenEmailIsValid:
def test_creates_user_in_database(self): ...
def test_sends_welcome_email(self): ...
class TestWhenEmailIsDuplicate:
def test_returns_conflict_error(self): ...
Flat test files with 50 test_ functions are findings — group by scenario.
Testing preference — the hierarchy of test types, from most to least preferred:
Coverage targets:
No test logic — tests must not contain if, for, while, or try/except. A test that branches is testing multiple things.
Module organization — each module should have a clear responsibility. A module with 500+ lines needs review.
Import depth — imports from more than 3 levels deep (from a.b.c.d.e import X) suggest the module structure is too deep or the import should go through a public API.
Circular imports — if you see TYPE_CHECKING imports that seem to work around circular dependencies, trace the cycle and flag it.
Global state — module-level mutable state (lists, dicts, sets defined at module scope that get modified) is a finding:
grep -rn '^[a-z_].*= \[\]\|^[a-z_].*= {}\|^[a-z_].*= set()' --include='*.py' [changed files]
### [SEVERITY] [Pass]: [Short description]
**File:** `path/to/file.py:42`
**Evidence:** [grep output or code]
**Standard:** [which rule is violated]
**Fix:** [concrete code change]
## Python Review
### Summary
- Files reviewed: N
- Type safety: X findings
- Data modeling: X findings
- Linting: X findings
- Configuration: X findings
- Error handling: X findings
- Testing: X findings
- Code structure: X findings
### Findings
[grouped by severity: critical, important, suggestion]
### Clean Areas
[what was done well]
If everything passes: "No findings. Python review complete — all changed files comply with team standards." Do not invent issues to appear thorough.
/coding-standards:review-standards — cross-cutting quality and writing style checks that apply to all languages. Run alongside this review./coding-standards:review-git — commit message and PR conventions. Run when reviewing a PR.