# Python Reference Use this file only when deeper guidance is needed. `SKILL.md` is the default operating contract. ## When To Consult This File - You are choosing between multiple Python design options. - You need stronger guidance for typing, validation, async, or testing. - You are creating new modules or new project structure rather than making a local edit. - You are reviewing code and want a more complete checklist. ## Stronger Typing Guidance - Prefer `collections.abc` and `typing` abstractions such as `Sequence`, `Mapping`, `Callable`, and `Iterator`. - Use `Protocol` for behavioral contracts when inheritance is not required. - Use `TypedDict` for structured dictionary payloads when a dataclass or Pydantic model is not appropriate. - Use `Final` for constants and `ClassVar` for class-level attributes when helpful. - Keep `Any` rare, local, and justified. - If the project supports it, use `@override` on overriding methods. ## Architecture Heuristics - Domain layer: pure business rules, no framework or persistence code. - Repository or data layer: database and external service access. - Service or use-case layer: orchestration across domain rules and collaborators. - Interface layer: HTTP, CLI, events, serialization, request and response shaping. - Infrastructure layer: configuration, logging setup, DB sessions, clients. Use this split when it fits the repository. Do not impose it mechanically on smaller scripts or simpler codebases. ## Data Modeling - Use Pydantic for request payloads, config, and data from untrusted sources. - Use dataclasses for internal value objects and simple structured state. - Use `frozen=True` for values that should not change after creation. - Use `slots=True` where the codebase already prefers it or where many instances are created. ## Error Handling - Prefer project-specific exception types over generic `ValueError` or `RuntimeError` when a domain concept exists. - Wrap lower-level exceptions with domain context when crossing layers. - Keep exception handling near boundaries unless recovery is local and explicit. ## Logging - Prefer structured logging when the project supports it. - Log important operational events at service or interface boundaries. - Do not log secrets, credentials, or sensitive user data. - Avoid `print()` for operational behavior unless the program is explicitly a simple script or CLI output path. ## Async Guidance - Use async for I/O-bound workflows, not CPU-bound work. - Keep blocking calls out of coroutines; use thread or process offloading where appropriate. - Prefer `asyncio.TaskGroup` over ad hoc task orchestration when available. - Be explicit about sync-to-async boundaries. ## Security Guidance - Never hardcode secrets or credentials. - Validate all external input before it enters core logic. - Avoid dangerous calls unless explicitly justified and safely constrained: - `eval`, `exec` - `pickle.loads` - `yaml.load` - `subprocess` with `shell=True` - `os.system` - Do not interpolate raw user input into SQL, shell commands, or file-system-sensitive operations. ## Testing Guidance - Update tests whenever behavior changes. - Prefer unit tests for pure logic and integration tests for boundaries. - Use parametrization to improve coverage without duplicating setup. - Test behavior and observable outcomes rather than implementation details. - Mock external boundaries selectively; avoid mocking the core logic you actually want to verify. ## Review Heuristics When reviewing Python changes, prioritize: - correctness and regressions - incomplete or misleading typing - invalid assumptions at trust boundaries - misplaced logic between layers - unnecessary abstraction or indirection - missing tests for changed behavior - risky calls, secret handling, or unsafe subprocess use ## Common Verification Flow If the repository uses `uv`, the usual flow is: 1. `uv run ruff format ` 2. `uv run ruff check --fix ` 3. `uv run ruff check ` 4. `uv run mypy ` 5. `uv run pytest ` If the repository uses different commands or tools, follow the repository.