CLAUDE.md — Python Project
Project Basics
This is a Python 3.10+ project. Type hints are required on all functions. Use async/await for I/O-bound operations where the framework supports it.
Environment
- Use
poetryfor dependency management (alternatives:uv,pip+venv) - Always pin dependency versions — no floating ranges in production
- Virtual environment must be active before running any commands
pyproject.tomlis the single source of truth for project metadata and dependencies
Type Hints
- Type hints required on all function signatures (parameters and return types)
- Use
mypyin strict mode for type checking - Avoid
Anyunless absolutely necessary — document why if used - Use
TypedDictfor structured dictionaries,dataclassorpydanticfor data models - Import types from
typingfor Python 3.10 compatibility, or use native syntax for 3.10+
Testing
pytestfor all tests- Fixtures for test setup — prefer fixtures over setUp/tearDown
@pytest.mark.parametrizefor testing variants of the same behavior- Mock external services only (APIs, databases, file systems) — never mock internal modules
- Test error paths and edge cases, not just the happy path
- Run tests with:
pytest -v
Code Style
rufffor linting (replaces flake8, isort, pyflakes, and more)blackfor formatting (orruff format)- Import order: stdlib, third-party, local (enforced by ruff/isort)
- Line length: 88 characters (black default)
- Run checks with:
ruff check . && black --check .
Docstrings
- Google-style docstrings on all public functions and classes
- Include: one-line summary, Args, Returns, Raises sections
- Skip docstrings on obvious methods (getters, simple properties)
- Example:
def calculate_total(items: list[Item], tax_rate: float) -> Decimal: """Calculate the total price including tax. Args: items: List of items to total. tax_rate: Tax rate as a decimal (e.g., 0.08 for 8%). Returns: Total price including tax, rounded to 2 decimal places. Raises: ValueError: If tax_rate is negative. """
Error Handling
- Specific exceptions over generic ones (
ValueErrornotException) - Never use bare
except:— always specify the exception type - Log errors with structured data (not just the message)
- Use custom exception classes for domain-specific errors
- Let unexpected exceptions propagate — don’t silently swallow them
Common Pitfalls
- Mutable default arguments:
def f(items=[])shares the list across calls — useNoneand create inside - Circular imports: restructure modules or use local imports
- GIL limitations: use multiprocessing for CPU-bound work, asyncio for I/O-bound
- f-string injection: never use f-strings for SQL queries or shell commands
- Late binding closures in loops:
lambda x=x: xto capture loop variable
Verification
Before claiming work is done:
- Run
pytest -v— all tests pass - Run
mypy .— zero type errors - Run
ruff check .— zero lint errors - Run
black --check .— formatting is clean