standards-python
Scannednpx machina-cli add skill b33eep/claude-code-setup/standards-python --openclawFiles (1)
SKILL.md
5.8 KB
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 | get_user_by_id, is_active |
| Classes | PascalCase | UserService, ApiClient |
| Constants | UPPER_SNAKE_CASE | MAX_RETRY_COUNT |
| Private | Prefix with _ | _internal_method |
| Files/Modules | snake_case | user_service.py |
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 |
|---|---|
uv | Package manager (faster than pip/poetry) |
ruff | Linting (replaces flake8, isort, black) |
mypy or pyright | Type checking |
pytest | Testing with pytest-cov, pytest-asyncio |
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
time.sleep()or sync I/O in async functions - Structured logging - Use
loggingmodule with JSON format, not print() - Environment variables - Use
pydantic-settingsfor config, never hardcode secrets - 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
Source
git clone https://github.com/b33eep/claude-code-setup/blob/main/skills/standards-python/SKILL.mdView on GitHub Overview
Standards-python provides a cohesive set of Python coding standards automatically loaded for Python projects. It codifies naming conventions, general rules, and best practices to improve readability, maintainability, and testability. It highlights recommended tooling like Pydantic v2 for validation and pathlib for filesystem paths.
How This Skill Works
The skill ships with core principles, general rules, naming conventions, and project structure guidance (mirroring typical Python layouts). It endorses code style through PEP 8 and PEP 484, with concrete examples for type hints, validation, and modern Python features. It also covers async/await usage and robust exception handling to keep code reliable.
When to Use It
- Starting a new Python project or module and want a consistent coding style.
- Enforcing naming conventions for variables, functions, classes, and files across a team.
- Building APIs or services (FastAPI, Django, Flask) that require typed interfaces and validation.
- Improving readability and maintainability by applying PEP 8/484, type hints, and Pydantic v2 validation.
- Implementing async I/O and proper exception handling in Python applications.
Quick Start
- Step 1: Enable standards-python in your Python project so it loads automatically.
- Step 2: Apply the conventions: snake_case for variables/functions, PascalCase for classes, UPPER_SNAKE for constants, and folder structure under src/.
- Step 3: Start using type hints, Pydantic v2 models, Pathlib, and async/await patterns in new code.
Best Practices
- Type hints everywhere (e.g., function signatures and return types).
- Use Pydantic v2 for data validation and parsing.
- Prefer context managers for resource handling (e.g., files).
- Prefer pathlib over os.path for filesystem paths.
- Follow descriptive names, early returns, and avoid over-engineering.
Example Use Cases
- A FastAPI app with Pydantic models, typed endpoints, and a service layer under src.
- A Django or Flask project organized with src/models.py, src/schemas.py, and src/services/.
- An async data-fetching service using httpx AsyncClient with proper type hints.
- A repository pattern implementation with clear data access under repositories/.
- A test suite like tests/test_services.py and tests/test_repositories.py validating logic.
Frequently Asked Questions
Add this skill to your agents