uv python pin 3.13: set the project's Python version (.python-version)
- tool
- uv
- versions
- uv 0.4+
- os
- any
uv python pin 3.13 writes 3.13 to a .python-version file in the current directory. From then on, uv run, uv sync, uv venv and uv python find in that directory (and its subdirectories) use a Python 3.13 interpreter, downloading a managed build if none is installed. Commit .python-version so everyone on the project gets the same version.
Pin and check
uv python pin 3.13
cat .python-version
echo "--- current pin"
uv python pinOutput
Pinned `.python-version` to `3.13` 3.13 --- current pin 3.13
uv python pin without an argument prints the version currently pinned for the directory.
Accepted formats
| Command | .python-version contains | Matches |
|---|---|---|
| uv python pin 3.13 | 3.13 | Any 3.13.x |
| uv python pin 3.13.5 | 3.13.5 | Exactly that patch release |
| uv python pin pypy@3.10 | pypy@3.10 | PyPy implementing Python 3.10 |
| uv python pin --rm | (file removed) | Back to requires-python or the default interpreter |
| uv python pin --resolved 3.13 | The interpreter path | Exactly one installation on this machine (not portable) |
| uv python pin --global 3.13 | 3.13, in the user config directory | Default for directories without their own pin |
How it interacts with pyproject.toml
The pin must satisfy requires-python in pyproject.toml. uv checks it and refuses an incompatible pin (--no-project skips the check):
cat > pyproject.toml <<'EOF'
[project]
name = "app"
version = "0.1.0"
requires-python = ">=3.12"
EOF
uv python pin 3.13 && cat .python-version
uv python pin 3.11Output · exit 2
Pinned `.python-version` to `3.13` 3.13 error: The requested Python version `3.11` is incompatible with the project `requires-python` value of `>=3.12`.
Without a .python-version file, uv picks an interpreter that satisfies requires-python. Use the pin for "the version we develop on" and requires-python for "the versions we support".
How uv finds the pin
uv looks for .python-version in the working directory and then in each parent directory, but not beyond the boundary of the current project or workspace. If none is found it falls back to the global pin in the user configuration directory. --no-config turns off .python-version discovery for one command.
The file holds a version request, so any format uv accepts works, but plain version numbers keep it readable for other tools such as pyenv. When a command finds no installed interpreter that matches, uv downloads a managed CPython build, unless automatic downloads are disabled with the python-downloads setting or --no-python-downloads.
Typical workflow
uv python pin 3.13in the project root, then commit.python-version.uv sync(oruv venv) creates.venvwith Python 3.13, downloading it if needed.- To move the project to a new version, run
uv python pin 3.14, thenuv syncagain: uv recreates the environment for the new interpreter. - In CI, nothing extra is needed: the same file selects the same version.
Pitfalls
- Pin outside requires-python. uv refuses it with the error shown above; widen
requires-pythonfirst or pick a supported version. - Pinned version not available. With downloads disabled and no matching interpreter,
uv runanduv syncstop witherror: No interpreter found for Python 3.6 in ...followed by the places uv searched; install it withuv python installor enable downloads. - Old .venv after changing the pin.
uv runanduv syncnotice the mismatch and recreate the project environment, but a manually activated old.venvin your shell keeps the old interpreter until you activate it again.
FAQ
Does uv python pin install Python?
It can. When no matching interpreter is installed, current uv versions download a managed build while pinning. With downloads disabled, uv prints a warning that no interpreter was found and writes the pin anyway; uv python install with no argument installs the pinned version later.
Should I pin a minor version or an exact patch release?
A minor version such as 3.13 is the usual choice: everyone gets the same language version and patch updates still apply. Pin an exact release only when a bug or a binary dependency requires it.
Why does uv ignore the .python-version in my parent folder?
uv searches the working directory and its parents but stops at the project or workspace boundary, so a file above the project root is not used. Put the file in the project root.