Python Engineering
Use this skill for project-neutral Python implementation, review, tests,
packaging, dependency management, and quality gates. Prefer repository recipes
when they encode the supported Python version, uv workflow, test services, or
CI policy.
Use When
- Editing
.py files, Python package layout, pyproject.toml, uv.lock,
requirements files, tests, type-checker config, Ruff config, or build metadata.
- Adding behavior, fixing bugs, refactoring Python modules, reviewing Python
code, or modernizing package/dependency workflows.
- Working with
uv, pytest, unittest, Ruff, ty, mypy, Pyright, packaging, or
Python CLIs.
Do not use this skill for non-Python package managers, browser E2E test design,
or database-native design except where Python code owns the adapter boundary.
Use sqlite-sql-engineering,
postgresql-sql-engineering, or
mysql-mariadb-sql-engineering
for schema, transaction, query-plan, and database-specific behavior. Use
css-scss-styling when Python web work changes
stylesheets, template class conventions, static CSS/SCSS assets, responsive
layout, or design tokens.
PySpark Execution Handoff
Load data-platform-engineering and its
PySpark notebook evidence
when Python code changes or evaluates distributed Spark SQL/DataFrame execution,
schemas at data boundaries, plans, partitions, shuffles, skew, driver
materialization, cache lifecycle, distributed writes/retries, Structured
Streaming, or notebook/cluster behavior. That skill owns Spark runtime discovery,
data-contract safety, distributed execution reasoning, and representative-cluster
evidence. Do not use local Python output, an ordinary unit test, or a notebook
rerun as proof of those distributed claims.
Keep ordinary Python mechanics here: module and package design, typing, pure
transformation-test structure, pytest/unittest wiring, pyproject.toml and
uv.lock, package and local test environments, dependency workflow, and local
async/concurrency behavior. For a PySpark source-file change, use both skills:
apply this skill to the Python implementation and the data-platform skill to its
actual Spark execution and target-runtime validation.
Async And Concurrency Handoff
Load the asyncio concurrency reference only
when queues, workers, task supervision, cancellation, backpressure, retries,
rate limits, ordering, shared state, or recovery after process restart are
primary risks. Routine await usage, sequential async I/O, and ordinary async
context-manager use do not need the reference.
For concurrency-heavy work, give every task a supervising owner and bounded
lifetime; bound fan-out and queues; define overload behavior; specify
cancellation, cleanup, timeout, retry, and rate-limit policy; decide whether
failures are fail-fast or reported as partial success; test time-dependent policy
with injected clocks or sleepers; and coordinate scheduling states with explicit
events, queues, or barriers. Use
python-design-patterns only for the
task-group, queue, and resource-lifetime pattern; this skill and its reference
own implementation and execution workflow.
Use ci-release-engineering when changing
checked-in hosted workflow or automated release configuration, and
container-engineering when changing
Dockerfile, OCI image, or Compose behavior. Keep Python build, test, packaging,
and executable-generation commands in this skill.
Local CPU Parallelism Routing
Compose with parallelism-engineering
when a local CPU-bound Python workload needs data or task decomposition,
partition sizing, bounded worker-pool design, deterministic reduction,
cancellation, or nested-parallelism control. That skill owns the cross-language
parallel design; this skill owns Python executor, process/thread, typing,
packaging, and test mechanics.
Do not route ordinary asyncio event-loop work, async I/O, queues, task
supervision, or coroutine concurrency to parallelism-engineering; keep it in
this skill and its asyncio reference. Distributed PySpark execution, shuffles,
and Structured Streaming remain with
data-platform-engineering, not local
parallelism engineering.
WebAssembly Routing
Compose with webassembly-engineering
when Python work includes a general WebAssembly decision: a WAT or .wasm
artifact, WASI or WIT, the Component Model, host/guest contract, runtime or
target selection, capability grants, or Wasm packaging and deployment. That
skill owns those Wasm boundary and compatibility decisions. This skill retains
Python source, package, compiler or binding-tool, host-integration, and test
mechanics; the Wasm skill does not establish Python toolchain or binding support.
MCP SDK Composition
For MCP implementation, load
mcp-server-engineering and its dated
SDK selection record.
The selection record is the canonical source for the selected Python lane's
retrieval-time authority, package/version, tier, core-revision, transport, and
conformance caveats. It is not a target-repository pin or local test result.
MCP Python Mechanics
Use this section only after loading
mcp-server-engineering and its dated
SDK selection record.
They own MCP revision, capability, and transport rules; keep this section to
Python package, async, typing, and test mechanics.
- Discover and resolve packages: inspect
pyproject.toml, uv.lock,
dependency groups, supported Python versions, extras, and CI policy before
selecting mcp and any companion types package. Keep mcp/mcp-types in the
lockstep combination resolved for the project, and consult the resolved
version's API docs rather than treating the dated record as a pin or installing
a package to inspect it.
- Keep SDK wiring at an async boundary: build the SDK server/client and
selected transport in an application factory, CLI entry point, or framework
lifespan hook. Register typed handlers that delegate to transport-independent
application services; keep client/session objects out of domain models. Use
the selected SDK's documented stdio, ASGI/HTTP, or client transport adapter
rather than implementing protocol framing in Python code.
- Use Python lifecycle idioms: supervise background tasks with a clear
owner, pass cancellation deliberately, and use
async with, try/finally,
and the framework's lifespan/context-manager hooks to close resources. Do not
rely on interpreter exit or a cancelled coroutine to clean up a client,
transport, task, or stream; resolve the SDK's selected close semantics from
its versioned API.
- Make schemas executable at the boundary: give handler arguments and
structured outputs explicit annotations/models; use the resolved SDK's typed
schema derivation path where supported. Validate untrusted runtime values and
test generated/declared schemas and serialized results with valid, invalid,
optional, and nested examples. Python annotations alone are not runtime
validation.
- Test both application and adapter behavior: use the repository's pytest or
unittest and configured async support. Unit-test transport-independent
handlers with fakes; integration-test the SDK adapter, schema conversion,
cancellation, and cleanup using an SDK-supported in-memory/local fixture when
available. Reserve actual transport/process runs for an authorized repository
lane, with protocol coverage selected by the parent MCP skill.
Workflow
- Inspect the local project first:
pyproject.toml, uv.lock,
.python-version, requirements*.txt, tox.ini, noxfile.py, CI, README,
tests, package layout, and existing commands.
Use local code navigation, direct reads, and search for symbols, references,
implementations, exact strings, docs, config, logs, fixtures, and generated
assets; use repository commands for tests, builds, and other validation.
- Define the behavior before editing. Use TDD for new behavior and regressions;
use BDD-style examples for externally observable workflows.
- Keep boundaries clear. Use DDD language where domain rules matter; keep I/O,
framework, database, and CLI parsing at adapters instead of leaking into core
domain logic. Load
hexagonal-architecture for
ports/adapters and external actors, clean-architecture
for use-case and interface-adapter boundaries, or
onion-architecture for domain/application
rings.
- Implement small, typed, testable units. Prefer simple functions/classes,
explicit data models, narrow exceptions, and dependency injection at
boundaries over global state and broad mocks.
- Run a narrow feedback loop first, then broaden to the repository's quality
gate.
uv And Packaging
- Use
uv project commands when the repo has pyproject.toml and uv.lock.
Use legacy uv pip ... only when the project is intentionally
requirements-driven.
- Keep dependency changes intentional: add runtime dependencies with
uv add,
dev/test dependencies with the repo's configured dependency group, and remove
unused packages with the corresponding uv remove.
- Keep lockfiles reproducible. Do not edit
uv.lock by hand.
- Use
uv run for project commands so the environment and lockfile are
respected.
- For distributable packages, ensure
pyproject.toml has an appropriate
[build-system], package metadata, and importable package layout before
relying on builds.
Useful commands:
uv sync
uv sync --locked
uv lock
uv lock --check
uv add <package>
uv add --dev <package>
uv remove <package>
uv run python -m pytest
uv run ruff check .
uv run ruff format --check .
uv run ty check
uv run mypy .
uv run pyright
uv build
Adapt type-check and test commands to the tools actually configured. Use ty
when the repository has adopted it; otherwise use the configured type checker.
Python Design Checklist
- Public functions and methods have meaningful parameter and return types.
Avoid
Any unless the boundary is genuinely untyped and the reason is clear.
- Use built-in generics and unions (
list[T], dict[K, V], T | None) when
supported by the repo's Python version.
- Use dataclasses,
TypedDict, protocols, enums, or small value objects when
they clarify data shape or domain invariants.
- Exceptions are specific, preserve cause with
raise ... from exc, and carry
enough context for diagnosis without leaking secrets.
- Public docstrings explain caller-relevant behavior, parameters, return values,
raised exceptions, and examples only when type hints and names are not enough.
- Async code uses non-blocking libraries, awaits coroutines, manages async
context managers with
async with, and avoids blocking file/network/sleep
calls in the event loop.
- Module names and package boundaries follow cohesive behavior, not arbitrary
utility buckets.
- Avoid mutable defaults, hidden import-time side effects, implicit global
configuration, broad monkeypatching, and print-based observability in
application code.
Pattern Routing
- Load
python-design-patterns when the
change needs Python-specific pattern choices: dataclasses, value objects,
protocols, context managers, factories, adapters, repositories, application
services, or pytest fixture design.
- Load
python-antipatterns when reviewing or
refactoring Python smells: mutable defaults, import-time side effects, global
state, broad Any, broad exceptions, framework/ORM leakage, async blocking,
monkeypatch-heavy tests, or over-mocking.
API and Observability Routing
- Load
api-design when Python work defines or changes
HTTP/RPC/GraphQL/webhook, SDK, CLI, request/response/error, pagination,
versioning, or generated-client contracts. Keep this skill focused on Python
implementation, typing, serializers, and tests.
- Load
observability-engineering when
adding or changing structured logging, metrics, traces, correlation IDs, audit
events, or production diagnostics.
- For public API docs, examples, or migration guides, load
api-design first if the contract is still being
shaped; otherwise use
documentation-engineering.
Styling Routing
- Load
css-scss-styling when Django, Flask, or
other Python web work touches .css, .scss, .sass, static asset paths,
template class hooks, CSS modules through a frontend build, utility classes,
responsive layout, or accessibility-related visual states.
- Keep this skill focused on Python routes, templates, packaging, tests, and
framework configuration. Let the styling skill own CSS-vs-SCSS decisions,
stylesheet build behavior, cascade/layout maintainability, and migration
validation.
Security Review Routing
Load security-review when Python work touches
implemented auth, sessions, crypto, credentials, secrets or .env,
deserialization, template rendering, subprocess or command execution, path
handling, uploads/downloads, or other trust boundaries. Use
dependency-supply-chain-review
for dependency bumps, uv.lock or requirements churn, package/install/build
hooks, generated clients, vendored code, registry trust, provenance, or advisory
questions. Use threat-modeling before or during
new auth flows, request/API boundaries, background jobs, external-service calls,
tenant changes, or sensitive data flows. Pair security-sensitive reviews with
security-review-evidence so examples
stay sanitized.
Testing Guidance
- Unit tests cover pure domain logic, validation, parsing, error mapping, and
edge cases.
- Integration tests cover filesystems, databases, services, framework wiring,
subprocesses, and package/CLI behavior.
- Use pytest fixtures for shared setup with explicit cleanup; keep mutable
fixtures function-scoped unless sharing is intentional and safe.
- Parametrize real behavior variants instead of duplicating similar tests.
- Mock external boundaries, not the domain logic being specified. Patch where
the symbol is used, use
AsyncMock for awaited collaborators, and verify
important calls.
- Async tests must use the configured async test plugin or framework support and
await all async work.
- Regression tests should fail on the old bug for the expected reason before the
fix.
Review Checklist
- Correctness: behavior matches the request, edge cases are handled, exceptions
are specific, and resource cleanup is reliable.
- Typing and API: type hints describe the contract, optional values are handled,
public APIs are stable enough, and data shapes are explicit.
- Maintainability: modules have cohesive ownership, names use domain language,
abstractions remove real duplication, and refactors preserve behavior.
- Performance: hot paths avoid accidental O(n^2) work, repeated I/O, import-time
cost, unnecessary serialization, and blocking work in async contexts.
- Security: input is validated at trust boundaries, secrets are not logged,
subprocesses and paths are safe, and dependency changes are reviewed.
- Tests: new behavior has unit or integration coverage at the narrowest useful
level, and broad mocks do not make tests meaningless.
- Workflow:
pyproject.toml, lockfiles, format/lint/type/test commands, docs,
and CI remain synchronized.
Pydoc and Docstrings
- Use module, class, function, and method docstrings for public APIs, extension
points, CLIs, and non-obvious behavior. Do not restate obvious names.
- Keep examples deterministic and runnable through the repository's doctest,
pytest, or documentation lane when one exists.
- Document
Raises only for exceptions callers can intentionally handle.
- Prefer type hints for ordinary parameter and return shape; use prose for
semantics, side effects, units, invariants, and security constraints.
Anti-Patterns
- Running tools outside the project environment and then reporting confidence.
- Replacing domain behavior with mocks.
- Leaking framework, ORM, SDK, request, response, or row types into core domain
APIs without an intentional adapter boundary.
- Catching
Exception broadly without a recovery policy and context.
- Adding dependencies for trivial standard-library behavior.
- Treating formatting, linting, type checking, and tests as interchangeable.
- Shipping Python package changes without checking lockfile and build metadata.
Successful Use
The final handoff states the behavior changed, tests or quality gates run, lock
or packaging changes made, and residual risk if type checks, tests, or builds
could not run.
TypeScript Zod Interoperability
For a real TypeScript/backend JSON crossing, load zod-engineering. Python independently validates and maps models; make extra/null/date/decimal/error policy explicit and test shared wire fixtures.
1---2name: python-engineering3description: Python engineering guidance with uv. Use when adding, changing, reviewing, testing, packaging, linting, formatting, typing, dependency-managing, or refactoring Python code, pyproject.toml, uv.lock, pytest/unittest tests, Python scripts, Python web templates, or Python project workflows. Do not use as the primary skill for distributed PySpark SQL/DataFrame execution, execution plans, shuffles, Structured Streaming, or notebook/cluster lifecycle; use data-platform-engineering. Do not use as the primary skill for smell-focused Python audits; use python-antipatterns. Do not use for checked-in hosted CI/release-provider or Docker/OCI/Compose configuration except the Python commands they invoke; use ci-release-engineering or container-engineering. Use api-design for public service/SDK/CLI contracts, observability-engineering for telemetry/logging signal design, and css-scss-styling for CSS/SCSS/template styling decisions.4---56# Python Engineering78Use this skill for project-neutral Python implementation, review, tests,9packaging, dependency management, and quality gates. Prefer repository recipes10when they encode the supported Python version, `uv` workflow, test services, or11CI policy.1213## Use When1415- Editing `.py` files, Python package layout, `pyproject.toml`, `uv.lock`,16 requirements files, tests, type-checker config, Ruff config, or build metadata.17- Adding behavior, fixing bugs, refactoring Python modules, reviewing Python18 code, or modernizing package/dependency workflows.19- Working with `uv`, pytest, unittest, Ruff, ty, mypy, Pyright, packaging, or20 Python CLIs.2122Do not use this skill for non-Python package managers, browser E2E test design,23or database-native design except where Python code owns the adapter boundary.24Use [`sqlite-sql-engineering`](../sqlite-sql-engineering/SKILL.md),25[`postgresql-sql-engineering`](../postgresql-sql-engineering/SKILL.md), or26[`mysql-mariadb-sql-engineering`](../mysql-mariadb-sql-engineering/SKILL.md)27for schema, transaction, query-plan, and database-specific behavior. Use28[`css-scss-styling`](../css-scss-styling/SKILL.md) when Python web work changes29stylesheets, template class conventions, static CSS/SCSS assets, responsive30layout, or design tokens.3132## PySpark Execution Handoff3334Load [`data-platform-engineering`](../data-platform-engineering/SKILL.md) and its35[PySpark notebook evidence](../data-platform-engineering/references/pyspark-notebooks.md)36when Python code changes or evaluates distributed Spark SQL/DataFrame execution,37schemas at data boundaries, plans, partitions, shuffles, skew, driver38materialization, cache lifecycle, distributed writes/retries, Structured39Streaming, or notebook/cluster behavior. That skill owns Spark runtime discovery,40data-contract safety, distributed execution reasoning, and representative-cluster41evidence. Do not use local Python output, an ordinary unit test, or a notebook42rerun as proof of those distributed claims.4344Keep ordinary Python mechanics here: module and package design, typing, pure45transformation-test structure, pytest/unittest wiring, `pyproject.toml` and46`uv.lock`, package and local test environments, dependency workflow, and local47async/concurrency behavior. For a PySpark source-file change, use both skills:48apply this skill to the Python implementation and the data-platform skill to its49actual Spark execution and target-runtime validation.5051## Async And Concurrency Handoff5253Load the [asyncio concurrency reference](references/asyncio-concurrency.md) only54when queues, workers, task supervision, cancellation, backpressure, retries,55rate limits, ordering, shared state, or recovery after process restart are56primary risks. Routine `await` usage, sequential async I/O, and ordinary async57context-manager use do not need the reference.5859For concurrency-heavy work, give every task a supervising owner and bounded60lifetime; bound fan-out and queues; define overload behavior; specify61cancellation, cleanup, timeout, retry, and rate-limit policy; decide whether62failures are fail-fast or reported as partial success; test time-dependent policy63with injected clocks or sleepers; and coordinate scheduling states with explicit64events, queues, or barriers. Use65[`python-design-patterns`](../python-design-patterns/SKILL.md) only for the66task-group, queue, and resource-lifetime pattern; this skill and its reference67own implementation and execution workflow.6869Use [`ci-release-engineering`](../ci-release-engineering/SKILL.md) when changing70checked-in hosted workflow or automated release configuration, and71[`container-engineering`](../container-engineering/SKILL.md) when changing72Dockerfile, OCI image, or Compose behavior. Keep Python build, test, packaging,73and executable-generation commands in this skill.7475## Local CPU Parallelism Routing7677Compose with [`parallelism-engineering`](../parallelism-engineering/SKILL.md)78when a local CPU-bound Python workload needs data or task decomposition,79partition sizing, bounded worker-pool design, deterministic reduction,80cancellation, or nested-parallelism control. That skill owns the cross-language81parallel design; this skill owns Python executor, process/thread, typing,82packaging, and test mechanics.8384Do not route ordinary `asyncio` event-loop work, async I/O, queues, task85supervision, or coroutine concurrency to `parallelism-engineering`; keep it in86this skill and its asyncio reference. Distributed PySpark execution, shuffles,87and Structured Streaming remain with88[`data-platform-engineering`](../data-platform-engineering/SKILL.md), not local89parallelism engineering.9091## WebAssembly Routing9293Compose with [`webassembly-engineering`](../webassembly-engineering/SKILL.md)94when Python work includes a general WebAssembly decision: a WAT or `.wasm`95artifact, WASI or WIT, the Component Model, host/guest contract, runtime or96target selection, capability grants, or Wasm packaging and deployment. That97skill owns those Wasm boundary and compatibility decisions. This skill retains98Python source, package, compiler or binding-tool, host-integration, and test99mechanics; the Wasm skill does not establish Python toolchain or binding support.100101## MCP SDK Composition102103For MCP implementation, load104[`mcp-server-engineering`](../mcp-server-engineering/SKILL.md) and its dated105[SDK selection record](../mcp-server-engineering/references/sdk-selection.md).106The selection record is the canonical source for the selected Python lane's107retrieval-time authority, package/version, tier, core-revision, transport, and108conformance caveats. It is not a target-repository pin or local test result.109110## MCP Python Mechanics111112Use this section only after loading113[`mcp-server-engineering`](../mcp-server-engineering/SKILL.md) and its dated114[SDK selection record](../mcp-server-engineering/references/sdk-selection.md).115They own MCP revision, capability, and transport rules; keep this section to116Python package, async, typing, and test mechanics.117118- **Discover and resolve packages:** inspect `pyproject.toml`, `uv.lock`,119 dependency groups, supported Python versions, extras, and CI policy before120 selecting `mcp` and any companion types package. Keep `mcp`/`mcp-types` in the121 lockstep combination resolved for the project, and consult the resolved122 version's API docs rather than treating the dated record as a pin or installing123 a package to inspect it.124- **Keep SDK wiring at an async boundary:** build the SDK server/client and125 selected transport in an application factory, CLI entry point, or framework126 lifespan hook. Register typed handlers that delegate to transport-independent127 application services; keep client/session objects out of domain models. Use128 the selected SDK's documented stdio, ASGI/HTTP, or client transport adapter129 rather than implementing protocol framing in Python code.130- **Use Python lifecycle idioms:** supervise background tasks with a clear131 owner, pass cancellation deliberately, and use `async with`, `try`/`finally`,132 and the framework's lifespan/context-manager hooks to close resources. Do not133 rely on interpreter exit or a cancelled coroutine to clean up a client,134 transport, task, or stream; resolve the SDK's selected close semantics from135 its versioned API.136- **Make schemas executable at the boundary:** give handler arguments and137 structured outputs explicit annotations/models; use the resolved SDK's typed138 schema derivation path where supported. Validate untrusted runtime values and139 test generated/declared schemas and serialized results with valid, invalid,140 optional, and nested examples. Python annotations alone are not runtime141 validation.142- **Test both application and adapter behavior:** use the repository's pytest or143 unittest and configured async support. Unit-test transport-independent144 handlers with fakes; integration-test the SDK adapter, schema conversion,145 cancellation, and cleanup using an SDK-supported in-memory/local fixture when146 available. Reserve actual transport/process runs for an authorized repository147 lane, with protocol coverage selected by the parent MCP skill.148149## Workflow1501511. Inspect the local project first: `pyproject.toml`, `uv.lock`,152 `.python-version`, `requirements*.txt`, `tox.ini`, `noxfile.py`, CI, README,153 tests, package layout, and existing commands.154 Use local code navigation, direct reads, and search for symbols, references,155 implementations, exact strings, docs, config, logs, fixtures, and generated156 assets; use repository commands for tests, builds, and other validation.1572. Define the behavior before editing. Use TDD for new behavior and regressions;158 use BDD-style examples for externally observable workflows.1593. Keep boundaries clear. Use DDD language where domain rules matter; keep I/O,160 framework, database, and CLI parsing at adapters instead of leaking into core161 domain logic. Load162 [`hexagonal-architecture`](../hexagonal-architecture/SKILL.md) for163 ports/adapters and external actors, [`clean-architecture`](../clean-architecture/SKILL.md)164 for use-case and interface-adapter boundaries, or165 [`onion-architecture`](../onion-architecture/SKILL.md) for domain/application166 rings.1674. Implement small, typed, testable units. Prefer simple functions/classes,168 explicit data models, narrow exceptions, and dependency injection at169 boundaries over global state and broad mocks.1705. Run a narrow feedback loop first, then broaden to the repository's quality171 gate.172173## uv And Packaging174175- Use `uv` project commands when the repo has `pyproject.toml` and `uv.lock`.176 Use legacy `uv pip ...` only when the project is intentionally177 requirements-driven.178- Keep dependency changes intentional: add runtime dependencies with `uv add`,179 dev/test dependencies with the repo's configured dependency group, and remove180 unused packages with the corresponding `uv remove`.181- Keep lockfiles reproducible. Do not edit `uv.lock` by hand.182- Use `uv run` for project commands so the environment and lockfile are183 respected.184- For distributable packages, ensure `pyproject.toml` has an appropriate185 `[build-system]`, package metadata, and importable package layout before186 relying on builds.187188Useful commands:189190```sh191uv sync192uv sync --locked193uv lock194uv lock --check195uv add <package>196uv add --dev <package>197uv remove <package>198uv run python -m pytest199uv run ruff check .200uv run ruff format --check .201uv run ty check202uv run mypy .203uv run pyright204uv build205```206207Adapt type-check and test commands to the tools actually configured. Use `ty`208when the repository has adopted it; otherwise use the configured type checker.209210## Python Design Checklist211212- Public functions and methods have meaningful parameter and return types.213 Avoid `Any` unless the boundary is genuinely untyped and the reason is clear.214- Use built-in generics and unions (`list[T]`, `dict[K, V]`, `T | None`) when215 supported by the repo's Python version.216- Use dataclasses, `TypedDict`, protocols, enums, or small value objects when217 they clarify data shape or domain invariants.218- Exceptions are specific, preserve cause with `raise ... from exc`, and carry219 enough context for diagnosis without leaking secrets.220- Public docstrings explain caller-relevant behavior, parameters, return values,221 raised exceptions, and examples only when type hints and names are not enough.222- Async code uses non-blocking libraries, awaits coroutines, manages async223 context managers with `async with`, and avoids blocking file/network/sleep224 calls in the event loop.225- Module names and package boundaries follow cohesive behavior, not arbitrary226 utility buckets.227- Avoid mutable defaults, hidden import-time side effects, implicit global228 configuration, broad monkeypatching, and print-based observability in229 application code.230231## Pattern Routing232233- Load [`python-design-patterns`](../python-design-patterns/SKILL.md) when the234 change needs Python-specific pattern choices: dataclasses, value objects,235 protocols, context managers, factories, adapters, repositories, application236 services, or pytest fixture design.237- Load [`python-antipatterns`](../python-antipatterns/SKILL.md) when reviewing or238 refactoring Python smells: mutable defaults, import-time side effects, global239 state, broad `Any`, broad exceptions, framework/ORM leakage, async blocking,240 monkeypatch-heavy tests, or over-mocking.241242## API and Observability Routing243244- Load [`api-design`](../api-design/SKILL.md) when Python work defines or changes245 HTTP/RPC/GraphQL/webhook, SDK, CLI, request/response/error, pagination,246 versioning, or generated-client contracts. Keep this skill focused on Python247 implementation, typing, serializers, and tests.248- Load [`observability-engineering`](../observability-engineering/SKILL.md) when249 adding or changing structured logging, metrics, traces, correlation IDs, audit250 events, or production diagnostics.251- For public API docs, examples, or migration guides, load252 [`api-design`](../api-design/SKILL.md) first if the contract is still being253 shaped; otherwise use254 [`documentation-engineering`](../documentation-engineering/SKILL.md).255256## Styling Routing257258- Load [`css-scss-styling`](../css-scss-styling/SKILL.md) when Django, Flask, or259 other Python web work touches `.css`, `.scss`, `.sass`, static asset paths,260 template class hooks, CSS modules through a frontend build, utility classes,261 responsive layout, or accessibility-related visual states.262- Keep this skill focused on Python routes, templates, packaging, tests, and263 framework configuration. Let the styling skill own CSS-vs-SCSS decisions,264 stylesheet build behavior, cascade/layout maintainability, and migration265 validation.266267## Security Review Routing268269Load [`security-review`](../security-review/SKILL.md) when Python work touches270implemented auth, sessions, crypto, credentials, secrets or `.env`,271deserialization, template rendering, subprocess or command execution, path272handling, uploads/downloads, or other trust boundaries. Use273[`dependency-supply-chain-review`](../dependency-supply-chain-review/SKILL.md)274for dependency bumps, `uv.lock` or requirements churn, package/install/build275hooks, generated clients, vendored code, registry trust, provenance, or advisory276questions. Use [`threat-modeling`](../threat-modeling/SKILL.md) before or during277new auth flows, request/API boundaries, background jobs, external-service calls,278tenant changes, or sensitive data flows. Pair security-sensitive reviews with279[`security-review-evidence`](../security-review-evidence/SKILL.md) so examples280stay sanitized.281282## Testing Guidance283284- Unit tests cover pure domain logic, validation, parsing, error mapping, and285 edge cases.286- Integration tests cover filesystems, databases, services, framework wiring,287 subprocesses, and package/CLI behavior.288- Use pytest fixtures for shared setup with explicit cleanup; keep mutable289 fixtures function-scoped unless sharing is intentional and safe.290- Parametrize real behavior variants instead of duplicating similar tests.291- Mock external boundaries, not the domain logic being specified. Patch where292 the symbol is used, use `AsyncMock` for awaited collaborators, and verify293 important calls.294- Async tests must use the configured async test plugin or framework support and295 await all async work.296- Regression tests should fail on the old bug for the expected reason before the297 fix.298299## Review Checklist300301- Correctness: behavior matches the request, edge cases are handled, exceptions302 are specific, and resource cleanup is reliable.303- Typing and API: type hints describe the contract, optional values are handled,304 public APIs are stable enough, and data shapes are explicit.305- Maintainability: modules have cohesive ownership, names use domain language,306 abstractions remove real duplication, and refactors preserve behavior.307- Performance: hot paths avoid accidental O(n^2) work, repeated I/O, import-time308 cost, unnecessary serialization, and blocking work in async contexts.309- Security: input is validated at trust boundaries, secrets are not logged,310 subprocesses and paths are safe, and dependency changes are reviewed.311- Tests: new behavior has unit or integration coverage at the narrowest useful312 level, and broad mocks do not make tests meaningless.313- Workflow: `pyproject.toml`, lockfiles, format/lint/type/test commands, docs,314 and CI remain synchronized.315316## Pydoc and Docstrings317318- Use module, class, function, and method docstrings for public APIs, extension319 points, CLIs, and non-obvious behavior. Do not restate obvious names.320- Keep examples deterministic and runnable through the repository's doctest,321 pytest, or documentation lane when one exists.322- Document `Raises` only for exceptions callers can intentionally handle.323- Prefer type hints for ordinary parameter and return shape; use prose for324 semantics, side effects, units, invariants, and security constraints.325326## Anti-Patterns327328- Running tools outside the project environment and then reporting confidence.329- Replacing domain behavior with mocks.330- Leaking framework, ORM, SDK, request, response, or row types into core domain331 APIs without an intentional adapter boundary.332- Catching `Exception` broadly without a recovery policy and context.333- Adding dependencies for trivial standard-library behavior.334- Treating formatting, linting, type checking, and tests as interchangeable.335- Shipping Python package changes without checking lockfile and build metadata.336337## Successful Use338339The final handoff states the behavior changed, tests or quality gates run, lock340or packaging changes made, and residual risk if type checks, tests, or builds341could not run.342343## TypeScript Zod Interoperability344345For a real TypeScript/backend JSON crossing, load [`zod-engineering`](../zod-engineering/SKILL.md). Python independently validates and maps models; make extra/null/date/decimal/error policy explicit and test shared wire fixtures.