python-template
Reference

Configuration

The files that control the toolchain, and what each one owns

Each file below owns one concern. This page says which, and records the settings that are deliberate rather than default.

pyproject.toml

Project metadata, dependencies, and the configuration for ruff, ty and pytest.

The build backend is uv_build. [tool.uv.build-backend] module-name is required because uv_build derives the package directory from the distribution name — python-template normalises to python_template, but the package is pythontemplate. See Switch to hatchling to change backends.

SettingValue
requires-python>=3.11
ruff line-length100
ruff target-versionpy311
ruff selectE, F, I, UP, B, SIM, RUF, TID
ruff quote-styledouble
ban-relative-importsall
pytest addopts-ra --strict-markers --strict-config

ban-relative-imports = "all" is set explicitly because TID252 defaults to "parents", which flags .. but permits from .base import X.

[tool.ty.rules] is present but empty — ty is strict by default and the table exists as the place to relax a rule when you must.

A commented-out [tool.importlinter] block sits at the end of the file. See Add DDD layers.

mise.toml

Pins the toolchain — uv, task, node, pnpm — and exports UV_FROZEN=1 shell-wide so a stray uv run cannot silently rewrite uv.lock. The lockfile changes only via task uv:lock, or the release workflow's sync-lockfile job. Note that plain uv lock is not the escape hatch it looks like: with UV_FROZEN=1 set it becomes a no-op that still exits 0, as does uv lock --check. task uv:lock resolves past any mise shim and clears the variable for that one command.

.pre-commit-config.yaml

The hooks prek runs. ruff, ty and pytest are local hooks invoked through uv run --no-sync, so their versions come from uv.lock — there is no second rev: to keep aligned with the project's own pins.

pytest runs at pre-push rather than pre-commit, so a docs-only commit is not held up by the suite.

commitlint.config.mjs

Enforces Conventional Commits. The type list adds deps, which is not part of @commitlint/config-conventional: release-please routes deps commits to a visible Dependencies changelog section, where chore(deps) would be hidden.

subject-case is disabled so class names and acronyms survive in subjects.

release-please-config.json

Release automation. release-type is python; tags include a leading v; bump-minor-pre-major keeps pre-1.0 versions on minor bumps. The changelog-sections map decides which commit types reach the changelog — a visible section is also a releasable one.

Environment variables

VariableSet byEffect
UV_FROZENmise.toml, Taskfile.yml1 stops uv rewriting the lockfile. The release workflow unsets it for the one step that must — setting it to 0 would leave that step's uv lock --check assertion trusting the same variable it is meant to check.
BASE_PATHTaskfile.yml docs tasksEmpty strips the Pages basePath for local serving.
SITE_URLTaskfile.yml docs:serveOverrides the canonical site URL locally.

On this page