# How to change the Python version of a uv project

To change the Python version of a [uv](https://pydevtools.com/handbook/reference/uv.md) project, run `uv python pin 3.12` to update `.python-version`, then `uv sync` to rebuild the virtual environment against the new interpreter. If you also want to change which versions the project *supports*, edit `requires-python` in `pyproject.toml` and run `uv lock && uv sync`.

A uv project tracks Python versions in two places: the [.python-version file](https://pydevtools.com/handbook/explanation/what-is-a-python-version-file.md) pins the development interpreter (e.g., `3.12`), and `requires-python` in [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) declares which versions the project supports (e.g., `>=3.11`). The pinned version must satisfy the `requires-python` constraint, or uv will report an [incompatibility error](https://pydevtools.com/handbook/how-to/how-to-fix-python-version-incompatibility-errors-in-uv.md).

## See what Python versions are available

Before you switch or upgrade, check what uv can install:

```console
$ uv python list
```

This shows every CPython and PyPy build uv can download, along with the interpreters already on your system. Pick a version from this list.

## Pin a different development interpreter

```console
$ uv python pin 3.12
```

This writes `3.12` to `.python-version`, which uv reads on every command.

Then re-sync so the virtual environment picks up the new interpreter:

```console
$ uv sync
```

If `3.12` isn't already installed, uv downloads it during the sync. `uv sync` recreates `.venv` against the pinned version when the interpreter changes, so you usually don't need to delete the virtual environment by hand. If a sync fails partway through or the venv ends up in an inconsistent state, force a clean rebuild:

```console
$ uv venv --python 3.12 --clear
$ uv sync
```

## Change the supported Python versions

Edit `requires-python` in `pyproject.toml`:

```toml
[project]
requires-python = ">=3.11"
```

Then regenerate the lockfile and re-sync:

```console
$ uv lock
$ uv sync
```

`uv lock` re-resolves all dependencies against the new constraint. `uv sync` updates the virtual environment to match.

> [!TIP]
> Raising the minimum Python version can unlock newer dependencies and drop compatibility workarounds, but it excludes users on older interpreters.

## Use a different version for a single command

`--python` selects which interpreter to use for a single invocation, overriding the `.python-version` pin. The flag works on most uv commands, not just `uv run`:

```console
$ uv run --python 3.10 python -c "import sys; print(sys.version)"
$ uv sync --python 3.13
$ uv add --python 3.13 httpx
```

This is useful for quick compatibility checks without editing project files.

## Keep CI on the same Python version

CI systems and Docker images should honor the same `.python-version` pin so local and remote builds agree. In GitHub Actions, install uv with [`astral-sh/setup-uv`](https://github.com/astral-sh/setup-uv) and then let `uv sync` install the pinned interpreter on demand, or call `uv python install` explicitly. In Docker, copy the `.python-version` file into the image before running `uv sync` so the build uses the same pinned Python version as local development. See [how to install Python with uv](https://pydevtools.com/handbook/how-to/how-to-install-python-with-uv.md) for interpreter management details.

## Frequently asked questions

### Do I need to delete `.venv` when switching Python versions?

No. `uv sync` rebuilds the virtual environment against the pinned interpreter. Only use `uv venv --clear` if a sync fails partway through or the venv gets into an inconsistent state.

### Does changing the Python version break my lockfile?

Usually not. `uv.lock` is resolved against `requires-python`, not the pinned development version. Changing `.python-version` inside that range leaves the lockfile valid. Editing `requires-python` itself triggers a re-resolve on the next `uv lock`.

### What if the Python version isn't installed on my machine?

uv downloads managed Python builds on demand: running `uv sync` or `uv run` with a version that isn't installed will fetch it automatically the first time it's needed. To install a specific version up front, run `uv python install 3.13`.

### How do I upgrade a uv project to a newer Python release?

Pin the new version with `uv python pin 3.13`, bump `requires-python` in `pyproject.toml` if you also want to raise the minimum supported version, then run `uv lock && uv sync`.

## Related

- [What is a .python-version file?](https://pydevtools.com/handbook/explanation/what-is-a-python-version-file.md)
- [How to install Python with uv](https://pydevtools.com/handbook/how-to/how-to-install-python-with-uv.md)
- [How to fix Python version incompatibility errors in uv](https://pydevtools.com/handbook/how-to/how-to-fix-python-version-incompatibility-errors-in-uv.md)
- [How do pyenv and uv compare for Python interpreter management?](https://pydevtools.com/handbook/explanation/how-do-pyenv-and-uv-compare-for-python-interpreter-management.md)
