# Pathrule Pattern: Modern Python Tooling (uv + Ruff) (1.0.0)
# ::pathrule:package:python-tooling

### [RULE] Manage the project with uv and commit the lockfile  (path: /)
<!-- scope: project | priority: high | strict -->

uv is the base of the project: it creates the project, pins the Python version, manages the virtual environment, resolves and locks dependencies, and runs commands. Reaching around it with raw pip breaks reproducibility.

- Declare dependencies in `pyproject.toml` and manage them with `uv add` / `uv remove`. Do not hand-edit a `requirements.txt` or run `pip install` into the environment as the source of truth.
- Commit `uv.lock`. It is the exact, resolved, hashed dependency set. Install from it with `uv sync` so every machine and CI run gets the identical environment.
- Run project commands through uv (`uv run pytest`, `uv run python ...`) so they use the project's locked environment without manual `activate`. uv manages the venv for you.
- Pin the Python version for the project (`uv python pin`) so the interpreter is part of the reproducible setup, not whatever happens to be on the machine.

---

### [RULE] Lint, format, and type-check as a gate  (path: /)
<!-- scope: project | priority: high | advisory -->

Quality tools only hold a line if the build enforces them. Run them in CI and fail on violation, so style and type drift cannot accumulate.

- Use Ruff for both linting and formatting; it replaces Black, isort, and Flake8 with one fast tool. Run `ruff format` and `ruff check` (with `--fix` locally) and gate CI on a clean `ruff check` and `ruff format --check`.
- Run a type checker (mypy, or Astral's ty) in CI on the codebase, and treat new type errors as build failures. Types catch a whole class of bugs before runtime.
- Wire these into a pre-commit hook so violations are caught before they are pushed, and into CI so the gate is enforced regardless of local setup.
- Configure Ruff's selected rule set deliberately in `pyproject.toml` rather than enabling everything blindly; turn rules on as the team adopts them.

---

### [MEMORY] pyproject.toml is the single source of truth  (path: /)

Modern Python configuration lives in one file. `pyproject.toml` holds the project metadata, dependencies, and the configuration for uv, Ruff, pytest, and the type checker, so there is one place to look and edit.

- Keep project metadata and dependencies under `[project]`, and tool config under `[tool.uv]`, `[tool.ruff]`, `[tool.pytest.ini_options]`, etc. Delete the legacy scatter: `setup.py`, `setup.cfg`, `requirements.txt`, `.flake8`, `tox.ini`.
- uv, Ruff, and ty come from the same vendor (Astral) and are designed to read `pyproject.toml` and work together, which is why the stack composes cleanly.
- Separate dependency groups for dev vs runtime (`uv add --dev ruff pytest`) so production installs do not pull test/lint tooling.
- This pattern is the project-setup layer; an app framework like FastAPI sits on top of it. See the fastapi pattern for the application conventions.

See / for the uv-and-lockfile rule and the lint/format/type-check rule.

---

### [MEMORY] Testing and reproducible CI with uv  (path: /)

CI should run the exact environment the lockfile describes, fast, with no surprise resolution.

- Run tests with `uv run pytest`. Keep tests under `tests/`, name them so pytest discovers them, and use fixtures for shared setup. uv ensures pytest runs in the locked environment.
- In CI, install with `uv sync --frozen` (or `--locked`) so the pipeline fails if `uv.lock` is out of date rather than silently resolving new versions. This is the reproducibility guarantee.
- Cache uv's download/cache directory in CI to make installs fast; uv is already much faster than pip, and caching compounds it.
- Use the official `astral-sh/setup-uv` action (pinned) to install uv in GitHub Actions, then run lint, type-check, and test as gated steps.

See / for the uv-and-lockfile and lint/format/type-check rules; see the github-actions-cicd and supply-chain-security patterns for CI hardening.

---

### [SKILL] python-project-bootstrap  (path: /)

---
name: python-project-bootstrap
description: Checklist for setting up or modernizing a Python project with uv, Ruff, a type checker, and pytest. Run when starting a project or migrating off pip/venv/Black/Flake8.
---

# Python project bootstrap (uv + Ruff)

## Setup
- [ ] `uv init` the project; dependencies declared in `pyproject.toml`, managed with `uv add` / `uv remove`.
- [ ] Python version pinned with `uv python pin`.
- [ ] `uv.lock` committed; environments installed with `uv sync` (never raw `pip install` as source of truth).
- [ ] Dev tooling in a dev group (`uv add --dev ruff pytest ...`) separate from runtime deps.

## Quality gates
- [ ] Ruff configured in `pyproject.toml` for both lint and format; `ruff check` + `ruff format --check` gate CI.
- [ ] Type checker (mypy/ty) runs in CI; new type errors fail the build.
- [ ] pre-commit hook runs Ruff (and ideally the type checker) before push.

## Config & CI
- [ ] `pyproject.toml` is the single source of truth; legacy `setup.py`/`setup.cfg`/`requirements.txt`/`.flake8`/`tox.ini` removed.
- [ ] Tests run via `uv run pytest`; CI installs with `uv sync --frozen` and caches uv.
- [ ] `setup-uv` action pinned in CI; lint, type-check, and test are separate gated steps.
