Python Patterns System
Battle-tested skill for python, development, principles, decision. Includes structured workflows, validation checks, and reusable patterns for development.
Python Development Patterns Skill
A Claude Code skill for writing production-quality Python ā covering idiomatic patterns, type hints, async programming, testing strategies, project structure, and performance optimization.
When to Use This Skill
Choose this skill when:
- Writing Python code following modern best practices (3.10+)
- Implementing async patterns with asyncio
- Structuring Python projects for maintainability
- Adding type hints and runtime validation
- Optimizing Python performance
- Writing tests with pytest
Consider alternatives when:
- You need Django or Flask-specific guidance (use framework skills)
- You need data science patterns (use a data science skill)
- You need machine learning (use a ML/AI skill)
Quick Start
# Set up a Python project python -m venv .venv source .venv/bin/activate pip install ruff mypy pytest
# Modern Python patterns (3.10+) from dataclasses import dataclass, field from typing import TypeAlias # Type aliases for clarity UserId: TypeAlias = str Email: TypeAlias = str @dataclass class User: id: UserId name: str email: Email tags: list[str] = field(default_factory=list) def is_admin(self) -> bool: return "admin" in self.tags # Pattern matching (3.10+) def handle_response(status: int) -> str: match status: case 200: return "OK" case 404: return "Not Found" case 500: return "Server Error" case _: return f"Unknown: {status}"
Core Concepts
Python Idioms
| Pattern | Pythonic | Not Pythonic |
|---|---|---|
| List comprehension | [x*2 for x in items] | map(lambda x: x*2, items) |
| Dictionary building | {k: v for k, v in pairs} | Manual loop with d[k] = v |
| Context manager | with open(f) as fp: | fp = open(f); fp.close() |
| Unpacking | a, b, *rest = items | a = items[0]; b = items[1] |
| Truthiness | if items: | if len(items) > 0: |
| EAFP | try: x[key] | if key in x: x[key] |
Async Patterns
import asyncio from aiohttp import ClientSession async def fetch_all(urls: list[str]) -> list[dict]: async with ClientSession() as session: tasks = [fetch_one(session, url) for url in urls] return await asyncio.gather(*tasks) async def fetch_one(session: ClientSession, url: str) -> dict: async with session.get(url) as response: return await response.json() # Run async code results = asyncio.run(fetch_all(["https://api.example.com/1", "https://api.example.com/2"]))
Project Structure
myproject/
āāā src/myproject/
ā āāā __init__.py
ā āāā models.py # Data models
ā āāā services.py # Business logic
ā āāā api.py # API endpoints
ā āāā utils.py # Utilities
āāā tests/
ā āāā conftest.py # Shared fixtures
ā āāā test_models.py
ā āāā test_services.py
āāā pyproject.toml # Project config
āāā .python-version # Python version
āāā ruff.toml # Linter config
Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
python_version | string | "3.12" | Minimum Python version |
type_checker | string | "mypy" | Type checker: mypy, pyright |
linter | string | "ruff" | Linter: ruff, flake8, pylint |
formatter | string | "ruff" | Formatter: ruff, black |
test_framework | string | "pytest" | Test framework: pytest, unittest |
async_framework | string | "asyncio" | Async: asyncio, trio |
package_manager | string | "pip" | Package manager: pip, uv, poetry |
Best Practices
-
Use type hints on all public functions ā type hints serve as documentation and enable static analysis; use
mypy --strictorpyrightto catch type errors before runtime. -
Prefer
dataclassorpydantic.BaseModelover plain dicts ā structured data types provide validation, IDE autocompletion, and self-documenting code; dicts are error-prone and hard to refactor. -
Use
rufffor both linting and formatting ā ruff is 10-100x faster than flake8 + black combined and covers both linting and formatting in a single tool. -
Write fixtures in
conftest.pyfor shared test setup ā pytest fixtures provide dependency injection for tests; shared fixtures inconftest.pyare auto-discovered by all tests in the directory. -
Use
asyncio.gatherfor concurrent I/O operations ā when making multiple HTTP requests or database queries, gather them for concurrent execution instead of awaiting sequentially.
Common Issues
Circular imports between modules ā Two modules importing each other causes ImportError. Break the cycle by moving shared types to a separate types.py module or using TYPE_CHECKING guard for type-only imports.
asyncio.run() fails with "event loop already running" ā This happens inside Jupyter notebooks or frameworks that already have an event loop. Use await directly or nest_asyncio.apply() as a workaround.
Type checker reports false positives on library code ā Some libraries lack type stubs. Install types-* packages from PyPI (e.g., types-requests) or add # type: ignore[import] for untyped libraries.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.