# Python Dev

> Python development guidance with code quality standards, error handling, testing practices, and environment management. Use when writing, reviewing, or modifying Python code (.py files) or Jupyter notebooks (.ipynb files).

- Skill: `databricks-solutions/python-dev` (Agent Skill)
- Install (CLI): `npx skillmds@latest add databricks-solutions/python-dev`
- Raw SKILL.md: https://api.skillmd.com/api/skills/databricks-solutions/python-dev/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: databricks-solutions (https://skillmd.com/u/databricks-solutions)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/databricks-solutions/python-dev

---


# Python Development Rules

## Overview
Python development guidance focused on code quality, error handling, testing, and environment management. Apply when working with Python code or Jupyter notebooks.

## When to Use This Skill

Use this skill when:
- Writing new Python code or modifying existing Python files
- Creating or updating Jupyter notebooks
- Setting up Python development environments
- Writing or updating tests
- Reviewing Python code for quality and best practices

## Code Quality

### Principles
- **DRY (Don't Repeat Yourself)**: Avoid code duplication
- **Composition over inheritance**: Prefer composition patterns
- **Pure functions when possible**: Functions without side effects
- **Simple solutions over clever ones**: Prioritize readability and maintainability
- **Design for common use cases first**: Solve the primary problem before edge cases

### Style & Documentation
- **Type hints required**: All functions must include type annotations
- **snake_case naming**: Use snake_case for variables, functions, and modules
- **Google-style docstrings**: Document functions, classes, and modules using Google-style docstrings
- **Keep functions small**: Single responsibility principle - one function, one purpose
- **Preserve existing comments**: Maintain and update existing code comments

### Example

```python
def calculate_total(items: list[dict[str, float]], tax_rate: float = 0.08) -> float:
    """Calculate total cost including tax.
    
    Args:
        items: List of items with 'price' key
        tax_rate: Tax rate as decimal (default 0.08)
        
    Returns:
        Total cost including tax
        
    Raises:
        ValueError: If tax_rate is negative or items list is empty
    """
    if not items:
        raise ValueError("Items list cannot be empty")
    if tax_rate < 0:
        raise ValueError("Tax rate cannot be negative")
    
    subtotal = sum(item['price'] for item in items)
    return subtotal * (1 + tax_rate)
```

## Error Handling & Efficiency

### Error Handling
- **Specific exception types**: Catch specific exceptions, not bare `except`
- **Validate inputs early**: Check inputs at function entry
- **No bare except**: Always specify exception types

### Efficiency Patterns
- **f-strings**: Use f-strings for string formatting
- **Comprehensions**: Prefer list/dict/set comprehensions over loops when appropriate
- **Context managers**: Use `with` statements for resource management

### Example

```python
def process_file(file_path: str) -> list[str]:
    """Process file and return lines.
    
    Args:
        file_path: Path to file
        
    Returns:
        List of non-empty lines
        
    Raises:
        FileNotFoundError: If file doesn't exist
        PermissionError: If file cannot be read
    """
    if not file_path:
        raise ValueError("File path cannot be empty")
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return [line.strip() for line in f if line.strip()]
    except FileNotFoundError:
        raise FileNotFoundError(f"File not found: {file_path}")
    except PermissionError:
        raise PermissionError(f"Permission denied: {file_path}")
```

## Testing (Critical)

### Framework & Structure
- **pytest only**: Use pytest exclusively (no unittest)
- **Test location**: All tests in `./tests/` directory
- **Test package**: Include `__init__.py` in tests directory
- **TDD approach**: Write/update tests for all new/modified code
- **All tests must pass**: Ensure all tests pass before task completion

### Test Structure Example

```
project/
├── src/
│   └── my_module.py
└── tests/
    ├── __init__.py
    └── test_my_module.py
```

### Example Test

```python
# tests/test_calculations.py
import pytest
from src.calculations import calculate_total

def test_calculate_total_basic():
    """Test basic total calculation."""
    items = [{'price': 10.0}, {'price': 20.0}]
    result = calculate_total(items, tax_rate=0.1)
    assert result == 33.0

def test_calculate_total_empty_list():
    """Test error handling for empty list."""
    with pytest.raises(ValueError, match="Items list cannot be empty"):
        calculate_total([])

def test_calculate_total_negative_tax():
    """Test error handling for negative tax rate."""
    items = [{'price': 10.0}]
    with pytest.raises(ValueError, match="Tax rate cannot be negative"):
        calculate_total(items, tax_rate=-0.1)
```

## Environment Management

### Dependency Management
- **Use uv exclusively**: All packaging, environment, and script execution via [uv](https://github.com/astral-sh/uv)
- **No pip/venv/conda**: Do not use `pip`, `python3 -m venv`, or `conda` — `uv` handles all of this
- **pyproject.toml is the source of truth**: Define all dependencies in `pyproject.toml` (not `requirements.txt`)

### Environment Setup Example

```bash
# Install dependencies from pyproject.toml
uv sync

# Install with optional dev dependencies
uv sync --extra dev

# Run a script (no activation needed)
uv run python script.py

# Run pytest
uv run pytest

# Add a new dependency
uv add requests

# Remove a dependency
uv remove requests
```

### Running Python Code
- Use `uv run` to execute scripts — no manual venv activation needed
- Use `uv run <tool>` for dev tools (pytest, ruff, etc.)
- Dependencies are defined in `pyproject.toml` (not requirements.txt)

### Linting & Formatting (Ruff)
- **Ruff**: Use Ruff for linting AND formatting (replaces flake8, black, isort)

```bash
# Lint code
uv run ruff check .

# Lint and auto-fix
uv run ruff check --fix .

# Format code
uv run ruff format .

# Check formatting without changes
uv run ruff format --check .
```

### Type Checking (Pyright)

```bash
# Check types
uv run pyright
```

Note: Use `pyright` for type checking — do not use `mypy`.

## Best Practices Summary

1. **Code Quality**: DRY, composition, pure functions, simple solutions
2. **Style**: Type hints, snake_case, Google docstrings, small functions
3. **Errors**: Specific exceptions, early validation, no bare except
4. **Efficiency**: f-strings, comprehensions, context managers
5. **Testing**: pytest only, TDD, tests in `./tests/`, all must pass
6. **Environment**: Use `uv` exclusively for dependencies and execution, Ruff for linting/formatting, Pyright for type checking


