skills/standards-python/SKILL.md
This skill provides Python coding standards and is automatically loaded for Python projects. It includes naming conventions, best practices, and recommended tooling.
npx skillsauth add b33eep/claude-code-setup standards-pythonInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| 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 |
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
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...
# 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 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)
# 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)
# 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()
| 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 |
time.sleep() or sync I/O in async functionslogging module with JSON format, not print()pydantic-settings for config, never hardcode secretsdevelopment
Guide users through creating, reviewing, and fixing custom skills for Claude — both command skills (invoked via /slash) and context skills (auto-loaded by tech stack). Use when the user asks to create a skill, build a skill, make a new slash command skill, add a coding standards skill, review an existing skill, update a skill, or fix a skill that doesn't trigger.
development
Build or edit Slidev (sli.dev) presentations for tech talks, workshops, conference sessions, and live-coding demos. Use when the user asks to create slides, a deck, a presentation, a workshop deck, a conference talk, or edit an existing slides.md.
documentation
Download YouTube video transcripts with automatic frame extraction for visual references. Use when analyzing YouTube videos, tutorials, or conference talks.
documentation
Write INVEST-compliant user stories with Given-When-Then acceptance criteria. Use when writing user stories, creating acceptance criteria, or during /design Step 4.