Claude-code-setup standards-python
This skill provides Python coding standards and is automatically loaded for Python projects. It includes naming conventions, best practices, and recommended tooling.
install
source · Clone the upstream repo
git clone https://github.com/b33eep/claude-code-setup
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/b33eep/claude-code-setup "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/standards-python" ~/.claude/skills/b33eep-claude-code-setup-standards-python && rm -rf "$T"
manifest:
skills/standards-python/SKILL.mdsource content
Python Coding Standards
Core Principles
- Simplicity: Simple, understandable code
- Readability: Readability over cleverness
- Maintainability: Code that's easy to maintain
- Testability: Code that's easy to test
- DRY: Don't Repeat Yourself - but don't overdo it
General Rules
- Early Returns: Use early returns to avoid nesting
- Descriptive Names: Meaningful names for variables and functions
- Minimal Changes: Only change relevant code parts
- No Over-Engineering: No unnecessary complexity
- Minimal Comments: Code should be self-explanatory. No redundant comments!
Naming Conventions
| Element | Convention | Example |
|---|---|---|
| Variables/Functions | snake_case | , |
| Classes | PascalCase | , |
| Constants | UPPER_SNAKE_CASE | |
| Private | Prefix with | |
| Files/Modules | snake_case | |
Project Structure
myproject/ ├── src/ │ ├── __init__.py │ ├── main.py # Entry point │ ├── config.py # Settings, env vars │ ├── models.py # Domain models (dataclasses/Pydantic) │ ├── schemas.py # Request/response DTOs │ ├── services/ │ │ ├── __init__.py │ │ └── user_service.py # Business logic │ └── repositories/ │ ├── __init__.py │ └── user_repo.py # Data access ├── tests/ │ ├── __init__.py │ ├── test_services.py │ └── test_repositories.py ├── pyproject.toml └── README.md
Code Style (PEP 8 + PEP 484)
from dataclasses import dataclass @dataclass class User: id: str name: str email: str age: int | None = None # Python 3.10+ union syntax def get_user_by_id(user_id: str) -> User | None: if not user_id: raise ValueError("user_id cannot be empty") # implementation...
Best Practices
# Type hints everywhere def process_items(items: list[str]) -> dict[str, int]: return {item: len(item) for item in items} # Pydantic v2 for validation from pydantic import BaseModel, Field, field_validator, EmailStr class UserCreate(BaseModel): name: str = Field(..., min_length=2, max_length=50) email: EmailStr age: int | None = Field(None, ge=0, le=150) @field_validator('name') @classmethod def name_must_be_alphanumeric(cls, v: str) -> str: if not v.replace(' ', '').isalnum(): raise ValueError('Name must be alphanumeric') return v.strip() # Context managers with open('file.txt', 'r') as f: content = f.read() # Prefer pathlib over os.path from pathlib import Path config_path = Path(__file__).parent / 'config.yaml'
Async/Await
# Async function with proper typing async def fetch_user(user_id: str) -> User | None: async with httpx.AsyncClient() as client: response = await client.get(f"/users/{user_id}") return User(**response.json()) if response.status_code == 200 else None # Don't block async functions async def process_data(): # BAD - blocks the event loop time.sleep(1) # GOOD - async sleep await asyncio.sleep(1) # Gather for concurrent operations async def fetch_all_users(user_ids: list[str]) -> list[User]: tasks = [fetch_user(uid) for uid in user_ids] return await asyncio.gather(*tasks)
Exception Handling
# Custom exceptions for domain errors class UserNotFoundError(Exception): def __init__(self, user_id: str): self.user_id = user_id super().__init__(f"User not found: {user_id}") # Raise vs Return None def get_user_strict(user_id: str) -> User: """Raises if not found - use when user MUST exist.""" user = repository.get(user_id) if not user: raise UserNotFoundError(user_id) return user def get_user_optional(user_id: str) -> User | None: """Returns None if not found - use when absence is expected.""" return repository.get(user_id)
Comments - Less is More
# BAD - redundant comment # Get the user from database user = repository.get_user(user_id) # GOOD - self-explanatory code, no comment needed user = repository.get_user(user_id) # GOOD - comment explains WHY (not obvious) # Rate limit: Azure API allows max 1000 requests/min await rate_limiter.acquire()
Recommended Tooling
| Tool | Purpose |
|---|---|
| Package manager (faster than pip/poetry) |
| Linting (replaces flake8, isort, black) |
or | Type checking |
| Testing with , |
Production Best Practices
- Type hints everywhere - Parameters, return types, variables where helpful
- Pydantic for validation - Don't validate manually, use Pydantic models
- Async for I/O - Use async/await for network, database, file operations
- No blocking in async - Never use
or sync I/O in async functionstime.sleep() - Structured logging - Use
module with JSON format, not print()logging - Environment variables - Use
for config, never hardcode secretspydantic-settings - Dependency injection - Pass dependencies explicitly, makes testing easier
- Custom exceptions - Domain-specific errors, not generic Exception
- Connection pooling - Reuse database/HTTP connections, don't create per request
- Graceful shutdown - Handle SIGTERM, close connections properly