python-development

SKILL.md

Python Development

Guiding Principle

Apply features only when they add clarity, correctness, performance, or security. Prefer simple, intentional solutions (DRY, KISS, YAGNI, Fail Fast).

AI Assistant Guidelines

  • Avoid Over-Engineering: Don't recommend boto3 client caching, async/await, or concurrency patterns unless explicitly requested or bottlenecks are evident
  • Keep It Simple: Prefer stdlib over complex architectures
  • Respect Context: Don't transform a 20-line script into a 200-line framework

Standards Quick Reference

Aspect Standard
Python Version ≥ 3.12
Shebang #!/usr/bin/env -S uv run
Formatting 4-space indents, 120 char line length
Linting black, ruff, pylint (≥9.0)
Type Hints Strict typing required
Docstrings Google-style
Package Manager uv (preferred)

Type Hints (Python 3.12+)

Use built-in types instead of typing module:

# Modern Python 3.12+
def process(items: list[str], config: dict[str, int] | None = None) -> tuple[str, int]:
    ...

# Avoid (old style)
from typing import List, Dict, Optional, Tuple
def process(items: List[str], config: Optional[Dict[str, int]] = None) -> Tuple[str, int]:
    ...

Code Structure

#!/usr/bin/env -S uv run
"""
Module purpose and overview.

Workflow:
1. Load configuration
2. Validate inputs
3. Process data
"""

# Standard library
import logging

# Third-party
import requests

# Local
from utils import helper


def helper_function() -> None:
    """Helper functions first."""
    pass


def main() -> int:
    """Main function last."""
    return 0


if __name__ == "__main__":
    sys.exit(main())

Key Patterns

Defensive Programming

# Validate inputs early (fail-fast)
def process_user(user_id: str | None) -> User:
    if user_id is None:
        raise ValueError("user_id is required")
    # Continue processing...

No Mutable Defaults

# BAD
def foo(items: list[str] = []):
    ...

# GOOD
def foo(items: list[str] | None = None):
    items = items or []
    ...

Error Handling

# Re-raise with context at boundaries
try:
    data = load_database()
except Exception as e:
    raise RuntimeError(f"Failed to load database: {e}") from e

Logging Setup

import logging
import time

def setup_logger(name: str) -> logging.Logger:
    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)
    
    class UTCFormatter(logging.Formatter):
        converter = time.gmtime
    
    handler = logging.StreamHandler()
    handler.setFormatter(UTCFormatter("%(asctime)s - %(levelname)s - %(message)s"))
    logger.addHandler(handler)
    return logger

logger = setup_logger(__name__)

Package Management (uv)

# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Project setup
uv init my-project
uv add boto3 pydantic
uv add --dev pytest black ruff
uv sync

# Run script
uv run python main.py

Pydantic Validation

from pydantic import BaseModel, field_validator

class User(BaseModel):
    name: str
    age: int
    
    @field_validator("age")
    @classmethod
    def valid_age(cls, v: int) -> int:
        if v < 0 or v > 150:
            raise ValueError("Invalid age")
        return v

Quick Checklist

  • Shebang line with uv
  • Type hints on all functions
  • Google-style docstrings
  • Imports grouped and sorted
  • if __name__ == "__main__": guard
  • Logging configured
  • Input validation
  • Specific exception handling
  • black and ruff pass
  • pylint score ≥ 9.0

Detailed References

Weekly Installs
3
GitHub Stars
9
First Seen
Feb 26, 2026
Installed on
opencode3
claude-code3
github-copilot3
codex3
kimi-cli3
gemini-cli3