# Python Best Practices

Pythonic code with modern type hints, dataclasses, async patterns, packaging, and testing

- Repository: https://github.com/rohitg00/awesome-claude-code-toolkit (2800 stars)
- Category: Testing
- License: Apache-2.0
- Last updated: 2026-05-12
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add rohitg00/awesome-claude-code-toolkit --skill python-best-practices -g -a claude-code -y`
Codex: `npx skills add rohitg00/awesome-claude-code-toolkit --skill python-best-practices -g -a codex -y`
Cursor: `npx skills add rohitg00/awesome-claude-code-toolkit --skill python-best-practices -g -a cursor -y`
Gemini CLI: `npx skills add rohitg00/awesome-claude-code-toolkit --skill python-best-practices -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add rohitg00/awesome-claude-code-toolkit`

## Description

Pythonic code with modern type hints, dataclasses, async patterns, packaging, and testing

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Python Best Practices

## Type Hints (3.12+ Syntax)

```python
# Use built-in generics (3.9+), no need for typing.List, typing.Dict
def process_items(items: list[str]) -> dict[str, int]:
    return {item: len(item) for item in items}

# Union with | syntax (3.10+)
def find_user(user_id: int) -> User | None:
    ...

# Type parameter syntax (3.12+)
type Vector[T] = list[T]
type Matrix[T] = list[Vector[T]]

def first[T](items: list[T]) -> T:
    return items[0]

# TypedDict for structured dicts
from typing import TypedDict

class UserResponse(TypedDict):
    id: int
    name: str
    email: str
    active: bool
```

Always type function signatures. Use `mypy --strict` or `pyright` in CI. Use `type: ignore` comments sparingly with justification.

## Dataclasses vs Pydantic

### Dataclasses (internal data, no validation needed)
```python
from dataclasses import dataclass, field

@dataclass(frozen=True, slots=True)
class Point:
    x: float
    y: float

    def distance_to(self, other: "Point") -> float:
        return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5

@dataclass
class Config:
    host: str = "localhost"
    port: int = 8080
    tags: list[str] = field(default_factory=list)
```

Use `frozen=True` for immutable value objects. Use `slots=True` for memory efficiency.

### Pydantic (external input, validation required)
```python
from pydantic import BaseModel, Field, field_validator

class CreateUserRequest(BaseModel):
    model_config = {"strict": True}

    email: str = Field(max_length=255)
    name: str = Field(min_length=1, max_length=100)
    age: int = Field(ge=13, le=150)

    @field_validator("email")
    @classmethod
    def validate_email(cls, v: str) -> str:
        if "@" not in v:
            raise ValueError("Invalid email format")
        return v.lower()
```

Rule: Use dataclasses for domain models and internal structs. Use Pydantic for API boundaries, config files, and external data parsing.

## Async Patterns

The rest: https://github.com/rohitg00/awesome-claude-code-toolkit/blob/HEAD/skills/python-best-practices/SKILL.md
