pattern-engineer-python
Skill0 starsChanged 5 months agoMITView on GitHub
Modern idiomatic Python: `uv` only for env/deps; PEP 8 + 88-char lines; full type annotations on every signature; EAFP with narrow `except` + `raise ... from e`; modern type hints (PEP 604/695); `Protocol` for duck-typed seams; frozen-slots `@dataclass` DTOs (Pydantic only at boundaries); `with` for resources; no mutable default args; comprehensions over C-style loops; no `import *`; no MD5/SHA1 for security; Alembic chained to head + `pytest-alembic` round-trip. Activate on `.py` files.
In this repository74 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- create-bug-issueSkill
- create-enhancement-issueSkill
- create-feature-issuesSkill
- dream-summary-memorySkill
- memory-conventionSkill
- operation-gitSkill
- pattern-architect-api-endpointSkill
- pattern-architect-data-modelSkill
- pattern-architect-deep-moduleSkill
- pattern-e2e-coding-standardSkill
- pattern-engineer-apiSkill
- pattern-engineer-backend-standardSkill
- pattern-engineer-coding-standardSkill
- pattern-engineer-containerSkill
- pattern-engineer-databaseSkill
- pattern-engineer-fastapiSkill
- pattern-engineer-frontend-standardSkill
- pattern-engineer-goSkill
- pattern-engineer-javaSkill
- pattern-engineer-kotlinSkill
- pattern-engineer-nodeSkill
- pattern-engineer-non-functionalSkill
- pattern-engineer-observabilitySkill
- pattern-engineer-rustSkill
- pattern-engineer-securitySkill
- pattern-engineer-ssrSkill
- pattern-engineer-swiftSkill
- pattern-engineer-typescriptSkill
- pattern-engineer-viteSkill
- pattern-exploratory-testingSkill
- pattern-reviewer-apiSkill
- pattern-reviewer-backend-standardSkill
- pattern-reviewer-coding-standardSkill
- pattern-reviewer-containerSkill
- pattern-reviewer-contractSkill
- pattern-reviewer-databaseSkill
- pattern-reviewer-fastapiSkill
- pattern-reviewer-frontend-standardSkill
- pattern-reviewer-goSkill
- pattern-reviewer-javaSkill
- pattern-reviewer-kotlinSkill
- pattern-reviewer-nodeSkill
- pattern-reviewer-non-functionalSkill
- pattern-reviewer-observabilitySkill
- pattern-reviewer-pythonSkill
- pattern-reviewer-rustSkill
- pattern-reviewer-securitySkill
- pattern-reviewer-ssrSkill
- pattern-reviewer-swiftSkill
- pattern-reviewer-test-coverageSkill
- pattern-reviewer-typescriptSkill
- pattern-reviewer-viteSkill
- pattern-test-coverageSkill
- principle-engineer-tddSkill
- scaffold-projectSkill
- workflow-architect-interviewSkill
- workflow-designer-sample-pagesSkill
- workflow-design-interviewSkill
- workflow-e2e-authorSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 2 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 14
After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-python.md in the consuming project (resolve …
- Very specific: line 23
Commit uv.lock; never edit by hand.
- Very specific: line 24
Prefer uv run <cmd> over activating the venv in scripts.
- Very specific: line 46
Every function and method — including __init__, private helpers, and tests — fully annotated.
- Very specific: line 52
Always raise ... from e to preserve the cause.
- Distinctive: line 53
Don't swallow silently; either handle meaningfully or re-raise.
- Distinctive: line 71
No behavior beyond trivial derived properties.
- Very specific: line 76
Every acquired resource (files, sockets, locks, DB sessions, temp dirs, subprocess handles) released via with.
- Very specific: line 79
Never try with manual .close() when with would do.
- Very specific: line 88
Don't shadow builtins (list, dict, str, id, type, input) — pick a different name.
- Very specific: line 115
Run via uv run so it picks up the project env.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
pattern-engineer-python
When to activate
Activate when writing or editing any .py file, scaffolding a Python service, modifying pyproject.toml, working with FastAPI / Flask / Django / SQLAlchemy / Pydantic / pytest, or running mypy / ruff / bandit / pytest / uv. Skip for non-Python code.
Project memory overlay
After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-python.md in the consuming project (resolve MAIN_ROOT="$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")"). If present, load it as an additive overlay to the rules below; if absent, skip silently. See memory-convention for the full contract (additivity, severity floor, conflict surfacing).
Patterns
Environment — uv only
uvis the only supported environment / dependency manager.- No
pip,poetry,pipenv,conda,virtualenvworkflows. - Pin Python version in
pyproject.tomlviarequires-python. - Commit
uv.lock; never edit by hand. - Prefer
uv run <cmd>over activating the venv in scripts.
| Command | Purpose |
uv venv | Create .venv |
uv sync | Install from pyproject.toml + uv.lock |
uv add <pkg> | Add a runtime dep |
uv add --dev <pkg> | Add a dev dep |
uv run <cmd> | Run inside the project env |
PEP 8
- 4-space indentation, no tabs.
- Lines ≤ 88 chars (ruff default).
snake_casefor functions / methods / variables / modules.PascalCasefor classes.SCREAMING_SNAKE_CASEfor module-level constants.- Two blank lines between top-level defs; one between methods.
- Imports: stdlib → third-party → local; sorted by
ruff(Irules).
Type annotations on every signature
- Every function and method — including
__init__, private helpers, and tests — fully annotated. - Annotate parameters AND the return type.
-> Noneexplicitly for procedures.
EAFP over LBYL
- Try the operation; catch the narrowest exception that applies.
- Always
raise ... from eto preserve the cause. - Don't swallow silently; either handle meaningfully or re-raise.
Modern type hints
- Target Python ≥ 3.10.
- Built-in generics:
list[int],dict[str, X]— notList/Dictfromtyping. - PEP 604 unions:
int | None— notOptional[int]. - PEP 695 aliases + generics on 3.12+:
type UserId = int;def first[T](items: list[T]) -> T | None: ....
Protocol (duck typing)
typing.Protocolfor collaborator types crossing module boundaries (structural — anything with the right shape satisfies).- ABCs only when you need shared implementation, not just a shape.
Dataclasses as DTOs
@dataclass(frozen=True, slots=True)for plain data carriers — request/response payloads, config bundles, value objects.frozen=Truefor immutability;slots=Truefor memory + attribute safety.- No behavior beyond trivial derived properties.
- Pydantic only when parsing/validation is needed at a system boundary (FastAPI request bodies, config from env).
Context managers
- Every acquired resource (files, sockets, locks, DB sessions, temp dirs, subprocess handles) released via
with. - Author your own with
contextlib.contextmanageror__enter__/__exit__. contextlib.ExitStackto compose a dynamic set of context managers.- Never
trywith manual.close()whenwithwould do.
Pythonic idioms
- Mutable default arguments: NEVER
def f(x=[])/def f(x={})— the default is shared across calls. Usedef f(x: list[T] | None = None)and convert to[]inside. - List comprehensions / generator expressions over C-style accumulating loops (
result = []; for ...: result.append(...)→result = [... for ... if ...]). isinstance(x, T)overtype(x) == T—isinstancerespects subclassing;type==doesn't.x is None/x is not None— never== None(None is a singleton; identity comparison is both faster and the canonical idiom)."".join(parts)over+=in a loop —stris immutable;+=is quadratic.- Don't shadow builtins (
list,dict,str,id,type,input) — pick a different name. - No
from module import *— namespace pollution and breaks tooling that tracks symbol origins. - Weak crypto banned for security purposes: no
md5/sha1for signatures / fingerprints / passwords. Usehashlib.sha256(or stronger),bcrypt/argon2for passwords,hmac.compare_digestfor HMAC.
Banned APIs (bandit blocks these)
| Banned | Use instead |
urllib.request.urlopen | http.client.HTTPSConnection for stdlib-only; httpx otherwise. |
subprocess.Popen(..., shell=True) | shell=False (the default) with a list of args; if you genuinely need shell expansion, document the safe-input invariant and add # nosec B602. |
xml.etree.ElementTree on untrusted XML | defusedxml. |
yaml.load(...) without Loader | yaml.safe_load(...). |
assert for runtime invariants in production code | Raise an exception. Asserts in test code are fine. |
The pre-push hook runs uv run bandit -r . — anything above LOW severity blocks the push. (pattern-reviewer-python carries the per-API bandit codes and rationale.)
Backend layout (src/)
See templates/backend-layout.md. Source under src/<package>/, tests at the top level under tests/{database,unit,integration}/, single pyproject.toml.
src/layout avoids accidental imports from CWD.api/holds route/handler modules;models/holds dataclasses / ORM / DTOs;utils/holds cross-cutting helpers.- Shared fixtures live in
tests/conftest.py. - Tool configs (
[tool.ruff],[tool.ruff.format],[tool.mypy],[tool.pytest.ini_options]) live inpyproject.toml.
Tooling
Run via uv run so it picks up the project env.
uv run mypy . # Type checking
uv run ruff check . # Fast linting
uv run ruff format --check . # Format check
uv run bandit -r . # Static security analysis
uv run pytest # TestsAuto-fix before re-running checks:
uv run ruff format . # Auto-format
uv run ruff check --fix . # Auto-fix lint (includes import sorting)Enforced ruff rule set
[tool.ruff.lint] select in pyproject.toml pins the rule groups the pre-push hook and ci-checks.sh fail on. The scaffold ships this set; treat it as the baseline:
| Group | Covers |
E / W | pycodestyle errors / warnings |
F | pyflakes — undefined names, unused imports/vars |
I | isort — deterministic import ordering |
N | pep8-naming |
UP | pyupgrade — modern syntax + PEP 604/695 type hints |
B | flake8-bugbear — likely bugs (mutable defaults, etc.) |
C4 | flake8-comprehensions — comprehensions over C-style loops |
SIM | flake8-simplify |
ASYNC | flake8-async — blocking calls / un-awaited work in async defs |
RUF | ruff-specific — incl. RUF006 dangling asyncio.create_task |
- Security (
S) is intentionally NOT inselect—bandit -r .owns that gate (see Banned APIs); selectingStoo would double-report the same findings. FastAPI projects must whitelist the DI idiom so
B008(function-call-in-default) doesn't fire on everyDepends()/Query()/… route:[tool.ruff.lint.flake8-bugbear] extend-immutable-calls = ["fastapi.Depends", "fastapi.Query", "fastapi.Path", "fastapi.Header", "fastapi.Cookie", "fastapi.Body", "fastapi.Form", "fastapi.File", "fastapi.Security"]
Templates
| Asset | Purpose |
templates/backend-layout.md | Canonical src/-layout backend tree — package under src/<package>/{api,models,utils}/, tests mirrored under tests/{database,unit,integration}/, single pyproject.toml with tool configs. |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

