Background for the python-project-setup skill. The exact file contents are not
repeated here — they live in templates/ and are rendered by scaffold.py
(__PROJECT__ → project name, __PACKAGE__ → package name). Change what gets scaffolded by
editing the templates, not by copying snippets out of this doc.
Some violations are deliberate. Suppress them narrowly and explain why — a blanket
# noqa or untagged # type: ignore hides real bugs and trips the "unused ignore" warnings
(warn_unused_ignores = true makes a stale ignore its own error, so they self-clean).
- Broad
except Exceptionin resilient loops (e.g. a network reconnect loop) is sometimes correct. Tag it:except Exception: # noqa: BLE001— otherwise bugbear'sBLE001flags it. # type: ignore[<code>]must carry a reason comment explaining the deviation (defense-in-depth, JSON-scalar duck typing, a third-party stub gap, …). Always pin the specific error code —# type: ignore[arg-type], not bare# type: ignore.- Adding a new top-level module? Add it to both
[tool.mypy].filesand[tool.pyright].includeso the two type gates keep covering the same surface. - Add a test for every new pure-logic unit. Tests pin behavior, not just shape.
Run one gate directly while iterating, instead of the whole check.sh:
uv run ruff format . # reformat
uv run ruff check --fix . # lint + auto-fix
uv run ruff check --explain B008 # what does a rule mean?
uv run pytest tests/test_foo.py -q
uv run mypy
uv run pyright- Commit
uv.lockfor reproducible installs (uv sync --frozenreproduces it exactly); never commit.env,secrets/,*.pem. - One Python version, everywhere.
requires-python, ruff'starget-version, mypy'spython_version, and pyright'spythonVersionmust all agree (the templates pin 3.13);.python-versiontellsuvwhich interpreter to provision. To change it, update the templates in one pass. - The
[build-system]+[tool.hatch.build.targets.wheel]blocks are what make the project installable — without them the[project.scripts]entry points won't be created. uvdoes not auto-load.env. Pass--env-file .env(orexport UV_ENV_FILE=.env). Usepython -u(unbuffered) when piping so stdout flushes promptly.- To distribute as a standalone tool:
uv tool install .putsmyproj-cmdon PATH;uvx --from . myproj-cmdruns it ephemerally.