Python engineering
Skill nledford/engineering-review-board/skills/python-engineering
A collection of AI agent skills I have written
npx -y skills add nledford/engineering-review-board --skill python-engineeringAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
18.1 KB, ~3.8k tokens by cl100k_base, as published. Nobody here has run it
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
.pyfiles, 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 or
postgresql-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 selectingmcpand any companion types package. Keepmcp/mcp-typesin 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-architecturefor ports/adapters and external actors,clean-architecturefor use-case and interface-adapter boundaries, oronion-architecturefor 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
uvproject commands when the repo haspyproject.tomlanduv.lock. Use legacyuv 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 correspondinguv remove. - Keep lockfiles reproducible. Do not edit
uv.lockby hand. - Use
uv runfor project commands so the environment and lockfile are respected. - For distributable packages, ensure
pyproject.tomlhas 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
Anyunless 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-patternswhen the change needs Python-specific pattern choices: dataclasses, value objects, protocols, context managers, factories, adapters, repositories, application services, or pytest fixture design. - Load
python-antipatternswhen reviewing or refactoring Python smells: mutable defaults, import-time side effects, global state, broadAny, broad exceptions, framework/ORM leakage, async blocking, monkeypatch-heavy tests, or over-mocking.
API and Observability Routing
- Load
api-designwhen 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-engineeringwhen adding or changing structured logging, metrics, traces, correlation IDs, audit events, or production diagnostics. - For public API docs, examples, or migration guides, load
api-designfirst if the contract is still being shaped; otherwise usedocumentation-engineering.
Styling Routing
- Load
css-scss-stylingwhen 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
AsyncMockfor 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
Raisesonly 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
Exceptionbroadly 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.
Gives 0 of the 12 instructions most test skills give in ~3.8k tokens
Counted across 964 of the 1,571 authors here whose files we hold, read 2026-08-06
- close the browser when donein 55 of 964, across 12 files
- wait for network idle statein 51 of 964, across 6 files
- launch chromium in headless modein 49 of 964, across 6 files
- use descriptive selectors for elementsin 49 of 964, across 6 files
- run provided scripts with help flag firstin 49 of 964, across 6 files
- add appropriate explicit waitsin 48 of 964, across 5 files
- use bundled scripts as black boxesin 46 of 964, across 3 files
- do not read script source codein 46 of 964, across 3 files
- use sync playwright for scriptsin 46 of 964, across 3 files
- inspect dom before executing actionsin 46 of 964, across 3 files
- run the full test suitein 36 of 964, across 34 files
- write the failing test firstin 25 of 964, across 18 files
Said here and by no other author read
- define behavior before editing
- keep domain logic separate from IO and framework code
- implement small typed testable units
- use uv for project commands when applicable
- add or remove dependencies using uv commands
- give public functions meaningful parameter and return types
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.