From writing-python
Idiomatic Python 3.14+ — language style, type safety, design patterns, anti-patterns, error handling, resource management, configuration, CLI, and testing. Pydantic-first (no dataclasses). Use when writing or reviewing Python code, scaffolding services or CLI tools, designing validation/exception strategies, externalizing config, or establishing project conventions. NOT FOR system-reliability concerns like background jobs, retries, or observability (use `python-infrastructure`).
How this skill is triggered — by the user, by Claude, or both
Slash command
/writing-python:writing-pythonThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Language-level Python for this project: stdlib first, Pydantic for any structured data, `uv`/`ruff`/`ty` for tooling, type hints everywhere.
Language-level Python for this project: stdlib first, Pydantic for any structured data, uv/ruff/ty for tooling, type hints everywhere.
| If you need to… | Read |
|---|---|
| Configure ruff/ty, naming, imports, docstrings (Google style) | references/code-style.md |
| Add type annotations, generics, protocols, narrowing | references/type-safety.md |
| Decide between composition vs inheritance, layer code, inject dependencies | references/design-patterns.md |
| Audit code against a checklist of known bad patterns | references/anti-patterns.md |
| Validate inputs, design exception hierarchies, handle partial failures | references/error-handling.md |
| Manage connections/file handles/streams via context managers | references/resource-management.md |
Load env vars, set up pydantic-settings, validate config at boot | references/configuration.md |
| Look up everyday patterns (project layout, async, logging, pathlib) | references/patterns.md |
Build a CLI (typer, output formats, progress, exit codes) | references/cli.md |
Write tests with pytest (fixtures, async, parametrize, coverage) | references/testing.md |
BaseModel. Settings are pydantic-settings.BaseSettings. Don't reach for @dataclass.ty runs in CI; untyped code fails.uv for everything Python-level. Don't use pip/poetry/pyenv directly.ruff for lint + format. Don't add black/isort/flake8.ty for type checking. Don't add mypy/pyright. CI runs uvx ty check.httpx for async HTTP, pydantic for validation).references/code-style.md.# Type hints — all signatures, modern union syntax
def get_user(user_id: str) -> User | None: ...
async def fetch(url: str, timeout: float = 30.0) -> dict[str, object]: ...
# Pydantic model (instead of @dataclass)
from pydantic import BaseModel, Field
class Config(BaseModel):
host: str
port: int = Field(default=8080, ge=1, le=65535)
tags: list[str] = Field(default_factory=list)
# Pattern matching for shape dispatch
match event:
case {"type": "click", "x": x, "y": y}:
handle_click(x, y)
case {"type": "key", "code": code}:
handle_key(code)
case _:
raise ValueError(f"Unknown event: {event}")
uv sync # install deps from uv.lock
uv add <pkg> # add a runtime dep
uv add --dev <pkg> # add a dev dep
uvx ruff check --fix . # lint + autofix (isolated env, no install needed)
uvx ruff format . # format
uvx ty check # type-check
uv run pytest -v # tests (project-aware — pytest must import your package)
uv run pytest --cov=src # tests + coverage
uv run fastapi dev # FastAPI app, when applicable
Rule of thumb: uvx <tool> for tools that only need the file (ruff, ty); uv run <tool> for tools that need your project's environment (pytest, fastapi, anything that imports your code).
t"Hello {name}" returns a Template object (use for SQL/HTML where literal interpolation is unsafe).except without parens — except ValueError, TypeError: is valid.concurrent.interpreters — true parallelism via subinterpreters.compression.zstd — Zstandard in stdlib.python-infrastructure — what to do when the function above needs to retry across a network boundary, run in a worker, or be observable in prod.fastapi — HTTP routing, dependency injection, FastAPI/Pydantic conventions.astral:uv / astral:ruff / astral:ty — deep tool reference for the toolchain.async def vs def for FastAPI dependencies: async deps run on the event loop; sync deps run in a thread pool. Mixing without thought causes blocking or extra context-switch overhead.def f(x=[]): reuses the same list across calls. Use x: list | None = None and create inside.assert is stripped by python -O — never use for runtime validation; only for code-internal invariants.model_dump / model_validate / model_dump_json / model_validate_json, Field(alias=..., default_factory=...), model_config = {...}, @field_validator / @model_validator. Don't paste snippets using dict(), parse_obj(), Config class, or @validator — those are from an older API and won't work.functools.lru_cache on instance methods retains self forever — apply to module-level functions, or use methodtools.lru_cache.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
2plugins reuse this skill
First indexed Jun 18, 2026
npx claudepluginhub ai-riksarkivet/ra-skills --plugin writing-python