python-best-practices
alleneubank/claude-code
Type-safe Python patterns: immutable models, discriminated unions, and structured error handling.
What is python-best-practices?
Guidance for writing Python code with strong type safety and error handling. Use this skill when reading or writing Python files to apply type-first patterns, make illegal states unrepresentable, and follow functional idioms that prevent bugs at type-check time.
- Use frozen dataclasses and NewType to create immutable domain models that prevent invalid states
- Apply discriminated unions with Literal types and pattern matching for exhaustive state handling
- Chain exceptions with `from err` to preserve tracebacks and improve debugging
- Structure logging with module-level loggers and deferred string interpolation
- Choose appropriate type checkers (ty, pyright, mypy) based on speed and feature needs
- Use Protocol for structural typing without requiring inheritance
How to install python-best-practices
npx skills add https://github.com/alleneubank/claude-code --skill python-best-practicesHow to use python-best-practices
- 1.Apply frozen dataclasses for immutable domain models instead of mutable classes
- 2.Use NewType to distinguish between semantically different string/int types (UserId vs OrderId)
- 3.Replace if/else error handling with discriminated unions and pattern matching
- 4.Chain exceptions with `from err` when re-raising to preserve original tracebacks
- 5.Configure a module-level logger and use `%s` formatting for deferred interpolation
- 6.Choose a type checker (ty for speed, pyright for completeness, mypy for maturity) and add to pyproject.toml
Use cases
- Designing domain models that cannot enter invalid states at runtime
- Handling success/failure states with exhaustive pattern matching instead of error codes
- Debugging production issues by preserving exception chains and context
- Adding type safety to existing Python codebases without major refactoring
- Setting up CI pipelines with fast type checking using ty
- Python developers writing type-safe code
- Teams adopting strict type checking in CI/CD pipelines
- Backend engineers designing domain models and APIs
- Developers migrating from dynamic typing to type-first patterns
python-best-practices FAQ
Use NewType for simple domain primitives (UserId, OrderId) where you only need type safety without runtime behavior. Use dataclasses when you need fields, methods, or immutability.
Use discriminated unions with Literal types (Success | Failure) and pattern matching to represent both success and error states explicitly in the type system.
Use `ty` for fastest CI performance on large codebases, `pyright` for best type inference and IDE integration, or `mypy` if you need mature plugin support.
Chaining preserves the original traceback and context, making debugging easier. Without it, the original error is lost and you only see the re-raised exception.
Yes—Protocol enables structural typing, so any object with the required methods satisfies the type, even if it doesn't explicitly inherit from the Protocol.
Full instructions (SKILL.md)
Source of truth, from alleneubank/claude-code.
name: python-best-practices description: Use when reading or writing Python files (.py, pyproject.toml, requirements.txt).
Python Best Practices
Follows type-first, functional, and error handling patterns from CLAUDE.md. This skill covers language-specific idioms only.
Make Illegal States Unrepresentable
Use Python's type system to prevent invalid states at type-check time.
Frozen dataclasses for immutable domain models:
from dataclasses import dataclass
from datetime import datetime
@dataclass(frozen=True)
class User:
id: str
email: str
name: str
created_at: datetime
# Frozen dataclasses are immutable — no accidental mutation
Discriminated unions with Literal:
from dataclasses import dataclass
from typing import Literal
@dataclass
class Success:
status: Literal["success"] = "success"
data: str
@dataclass
class Failure:
status: Literal["error"] = "error"
error: Exception
RequestState = Success | Failure
def handle_state(state: RequestState) -> None:
match state:
case Success(data=data):
render(data)
case Failure(error=err):
show_error(err)
NewType for domain primitives:
from typing import NewType
UserId = NewType("UserId", str)
OrderId = NewType("OrderId", str)
def get_user(user_id: UserId) -> User:
# Type checker prevents passing OrderId here
...
Protocol for structural typing:
from typing import Protocol
class Readable(Protocol):
def read(self, n: int = -1) -> bytes: ...
def process_input(source: Readable) -> bytes:
# Accepts any object with a read() method — no inheritance required
return source.read()
Python-Specific Error Handling
Chain exceptions with from err to preserve the original traceback:
try:
data = json.loads(raw)
except json.JSONDecodeError as err:
raise ValueError(f"invalid JSON payload: {err}") from err
Structured Logging
Use a module-level logger with %s formatting (deferred string interpolation):
import logging
logger = logging.getLogger("myapp.widgets")
def create_widget(name: str) -> Widget:
logger.debug("creating widget: %s", name)
widget = Widget(name=name)
logger.debug("created widget id=%s", widget.id)
return widget
Optional: ty
For fast type checking, consider ty from Astral (creators of ruff and uv). Written in Rust, significantly faster than mypy or pyright.
uvx ty check # run directly, no install needed
uvx ty check src/ # check specific path
# pyproject.toml
[tool.ty]
python-version = "3.12"
When to choose:
ty— fastest, good for CI and large codebases (early stage, rapidly evolving)pyright— most complete type inference, VS Code integrationmypy— mature, extensive plugin ecosystem
Related skills
More from alleneubank/claude-code and the wider catalog.

react-best-practices
Essential patterns and anti-patterns for writing React components with TypeScript.

typescript-best-practices
TypeScript patterns for type-safe, error-resistant code using discriminated unions, branded types, and runtime validation.
stock-analysis
Generate a comprehensive sentiment analysis report for a single stock. Use when users want deep analysis of a specific ticker like NVDA, TSLA, or AAPL.

chatgpt-app-builder
Build and deploy ChatGPT apps with tools and custom UI views using the Skybridge framework.

skybridge
|

meticulous-cli
CLI tool to record user sessions and replay them to detect visual regressions.