plugins/python-dev/skills-codex/writing-python/SKILL.md
Idiomatic Python 3.12+ development. Use when writing Python code, CLI tools, scripts, or services. Emphasizes stdlib, type hints, uv/ruff/pyright toolchain, and minimal dependencies.
npx skillsauth add alexei-led/claude-code-config writing-pythonInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
X | Y, generics/Protocol where useful, and Any is not the default.argparse, pathlib, json, dataclasses, urllib, typing.pytest for the happy path and invalid input/error paths.uv run pytest, uv run ruff check ., uv run ruff format --check ., and uv run pyright when configured.Stdlib and Mature Libraries First
Type Hints Everywhere (No Any)
X | Y union syntax (3.10+), PEP 695 generics (3.12+)Protocol Over ABC
Flat Control Flow
Explicit Error Handling
except Exception)Structured Logging
structlog for structured, contextualized loggingprint() for operational outputfrom typing import Protocol
class UserStore(Protocol):
def get(self, id: str) -> User | None: ...
def save(self, user: User) -> None: ...
class UserService:
def __init__(self, store: UserStore):
self.store = store # accepts any matching impl
# NEW: type parameter syntax (no TypeVar boilerplate)
def first[T](items: list[T]) -> T | None:
return items[0] if items else None
type Vector = list[float] # type alias statement
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class StatusUpdate:
raw_text: str
display_label: str
is_interactive: bool = False
def process(user: User | None) -> Result:
if user is None:
raise ValueError("user required")
if not user.email:
raise ValueError("email required")
if not is_valid_email(user.email):
raise ValueError("invalid email")
return do_work(user) # happy path at end
import structlog
logger = structlog.get_logger()
logger.info("processing_started", user_id=user.id, count=len(items))
logger.error("operation_failed", error=str(e), context=ctx)
class NotFoundError(AppError):
def __init__(self, resource: str, id: str):
self.resource = resource
self.id = id
super().__init__(f"{resource} not found: {id}")
# Exception chaining
raise ProcessingError("failed") from original_error
def first[T](lst: list[T]) -> T (no TypeVar)from __future__ import annotations neededt"Hello {name}" returns Template (safe interpolation)except ValueError, TypeError: (PEP 758)uv sync # Install deps from pyproject.toml
uv add pkg # Add dependency
uv run python script.py # Run in project env
uv run --with pkg python script.py # Run with one-off dep
uv run --extra dev pytest -v # Run tests (dev group)
ruff check --fix . # Lint and autofix
ruff format . # Format
pyright src/ # Type check (preferred)
deptry src # Dependency check
make fmt # ruff format
make lint # ruff check
make typecheck # pyright
make deptry # dependency check
make test # unit tests only
make check # fmt + lint + typecheck + deptry + test
After generating or modifying code, run the full check loop:
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
Use the project's configured commands if different. If checks fail:
ruff check . && ruff format --check . && pyrighttools
Idiomatic shell development for POSIX sh, Bash, Zsh, Fish, hooks, CI shell steps, and scriptable CLI glue. Use when writing or changing `.sh`, `.bash`, `.zsh`, `.fish`, `.bats`, shell functions, shell pipelines, or command-runner recipes. Emphasizes portability, quoting, safe filesystem/process handling, non-TUI CLI tools, ShellCheck, shfmt, Bats, and ShellSpec. NOT for Python, TypeScript, Go, web code, or infrastructure operations.
tools
Use when planning, executing, checkpointing, finishing, or inspecting lightweight spec-driven work. Runs one task at a time using `.spec/` markdown files and the bundled `specctl` helper. NOT for broad product discovery beyond a short requirement interview.
testing
Author, inspect, troubleshoot, and review infrastructure across IaC, Kubernetes, cloud resources, containers, CI/CD, and Linux hosts. Use when changing Terraform/OpenTofu, Kubernetes, Helm, Kustomize, Dockerfiles, GitHub Actions, AWS, GCP, Cloud Run, BigQuery, IAM, logs, instances, or service health. NOT for deploy/apply/rollback workflows (see deploying-infra). NOT for shell scripts or generic command pipelines (see writing-shell).
development
Configure safe git workflow hygiene: pre-commit/pre-push hooks, Gitleaks secret scanning, .gitignore rules, local git config, and guardrails. Use when setting up git hooks, gitleaks/git leaks, staged pre-commit checks, pre-push validation, core.hooksPath, .gitignore, or git config best practices. NOT for creating commits (use committing-code), cleaning branches/worktrees (use cleanup-git), or creating worktrees (use using-git-worktrees).