# UV: Environment and Dependency Management

UV is a fast Python package and environment manager. We use UV to:

- Create and manage a local virtual environment at `.venv`.
- Install and sync dependencies from `pyproject.toml`, `uv.lock`, and existing `requirements*.txt`.
- Run tools (pytest, linters) via `uvx` for consistent execution.

## Quick Start (macOS/zsh)

```bash
# Install uv if not present
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create/refresh local venv at .venv with Python 3.11
uv venv --python 3.11 --clear

# Activate the venv
source .venv/bin/activate

# Sync project dependencies
uv sync

# Optional: install dev extras
uv pip install -r requirements-dev.txt
```

Notes:

- If `.venv` already exists, use `uv venv --python 3.11 --clear` or set `UV_VENV_CLEAR=1` to replace without prompt.
- `uv sync` uses `pyproject.toml` and `uv.lock` when present. It can also read `requirements.txt`.
- Prefer `uvx <tool>` to run tools consistently, e.g. `uvx pytest -q`, `uvx flake8`.

## Common Commands

```bash
# Create venv with a specific Python
uv venv --python 3.11

# Clear existing venv automatically
UV_VENV_CLEAR=1 uv venv --python 3.11

# Sync deps (prod)
uv sync

# Run tests
uvx pytest -q

# Lint
uvx flake8

# Format (if configured)
uvx black .

# Add runtime dependency
uv add <package>

# Add dev dependency
uv add --dev <package>

# Generate lock file
uv lock

# Install from requirements.txt
uv pip install -r requirements.txt
```

## Migration from pip/venv

- Previous instructions used `python3.11 -m venv env` and `pip install -r requirements*.txt`.
- We now standardize on `.venv` and UV:
  - `uv venv --python 3.11 --clear`
  - `uv sync`
- Keep `requirements.txt` and `requirements-dev.txt` for compatibility; UV can install from them with `uv pip install -r ...` if needed.

## Project Setup with UV

### pyproject.toml Configuration

```toml
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
    "requests>=2.28.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",
    "pytest-cov>=4.0.0",
    "flake8>=6.0.0",
    "black>=23.0.0",
]

[tool.uv]
python-preference = "managed"
```

### Lock File

```bash
# Generate lock file from pyproject.toml
uv lock

# Sync environment from lock file
uv sync
```

## Troubleshooting

### "prompt to replace .venv"
Add `--clear` or set `UV_VENV_CLEAR=1`:
```bash
UV_VENV_CLEAR=1 uv venv --python 3.11
```

### "wrong shell commands"
Ensure zsh; avoid PowerShell commands like `Set-Location`.

### "Python version mismatch"
Verify via `uv venv --python 3.11` and check output:
```bash
python --version  # Should show specified version
```

### "uv not found after install"
Open a new terminal or add UV to PATH according to installer output:
```bash
# Usually one of:
export PATH="$HOME/.local/bin:$PATH"
export PATH="$HOME/.cargo/bin:$PATH"
```

### "module not found" when running tools
Make sure venv is activated or use `uvx`:
```bash
source .venv/bin/activate
# or
uvx pytest  # runs without activation
```

## UV vs Other Tools

| Task | pip/venv | UV |
|------|----------|-----|
| Create venv | `python -m venv .venv` | `uv venv` |
| Install deps | `pip install -r requirements.txt` | `uv sync` or `uv pip install -r ...` |
| Run tool | `python -m pytest` | `uvx pytest` |
| Add package | Edit requirements.txt + pip install | `uv add <package>` |
| Lock versions | `pip freeze > requirements.txt` | `uv lock` |

## References

- [UV Documentation](https://docs.astral.sh/uv/)
- [UV GitHub](https://github.com/astral-sh/uv)
- [Migration Guide](https://docs.astral.sh/uv/guides/migration/)

---

**Version:** 1.0
