Python Handbook

Python Handbook

Tools and patterns for modern Python development with package management, type checking, formatting, and testing.

Python Handbook

Quick reference for modern Python tools and workflows. This page covers package management, type checking, formatting, testing, and validationโ€”everything needed for production-grade Python code.

๐Ÿ› ๏ธ Environment Management

Mise (Multi-language Version Manager)

Replace pyenv with Mise. It manages multiple Python versions and other languages in one tool. Set up project-specific Python versions in .mise.toml:

[tools]
python = "3.12"

๐Ÿ“ฆ Package Management

UV (Rust-based Python Package Manager)

UV replaces pip, pipenv, and poetry. Itโ€™s faster, more reliable, and has no Python-based dependencies.

uv pip install requests
uv pip freeze > requirements.txt

Legacy alternatives: Poetry (slower) and pip (basic).

๐Ÿ”ง Code Quality Tools

Formatter: Ruff

Ruff (from the UV creators) formats and lints Python code fast.

ruff format .
ruff check . --fix

Type Checkers

ToolMaintainerUse Case
PyrightMicrosoftStrict, fast type checking
MypyCommunityTraditional type checking
TYUV creatorsModern Python type checking

Start with Pyright for strict mode:

pyright .

Testing: Pytest

Pytest is the standard testing framework. Structure tests alongside source code or in a separate tests/ directory.

# test_math.py
import pytest
from mymodule import add

def test_add():
    assert add(2, 3) == 5

@pytest.mark.parametrize("a,b,expected", [
    (1, 2, 3),
    (0, 0, 0),
    (-1, 1, 0),
])
def test_add_values(a, b, expected):
    assert add(a, b) == expected

โœ”๏ธ Validation: Pydantic

Pydantic is the Python equivalent of Zod (TypeScript validation library). Use it for API request validation and data transformation.

from pydantic import BaseModel, Field

class User(BaseModel):
    name: str
    email: str
    age: int = Field(gt=0, lt=150)

# Validates on instantiation
user = User(name="John", email="john@example.com", age=30)

# Fails with validation error
try:
    User(name="John", email="invalid", age=200)
except ValidationError as e:
    print(e.errors())

๐Ÿ“‹ Workflow Automation

Docker for Dependency Isolation

Use Docker to avoid Python version conflicts and system dependency issues:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN uv pip install -r requirements.txt
COPY . .
CMD ["python", "main.py"]

Pre-commit Hooks

Pre-commit runs linters, formatters, and tests before commits:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.1.0
    hooks:
      - id: ruff
        args: ['--fix']
      - id: ruff-format

  - repo: https://github.com/microsoft/pyright
    rev: v1.1.0
    hooks:
      - id: pyright

  - repo: local
    hooks:
      - id: pytest
        name: pytest
        entry: pytest
        language: system
        pass_filenames: false

Install in any repo:

pre-commit install

Now every git commit runs all checks automatically.

๐Ÿ’ก Best Practices

  1. Version all Python environments: Use Mise for reproducible builds across machines.
  2. Use UV for speed: Itโ€™s 10-100x faster than pip. No reason to use pip anymore.
  3. Type everything: Pydantic for input validation, pyright for type checking. Catches bugs early.
  4. Automate code quality: Pre-commit hooks enforce standards without thinking.
  5. Test before deployment: Pytest + parametrized tests catch edge cases before production.

๐Ÿ“š Resources