Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

2.3 Managing Python Versions

When developing a Python project, there are two related but distinct questions about Python versions that you need to answer:

  1. Which Python versions does your project support for users who want to install it?

  2. Which Python version do you want to use for your work?

The answers to these questions are important because:

To capture the answers to these two questions, uv will use two different files:

In this section, we will see how to use uv to manage both of these aspects of Python versioning for your project.

Defining the Python Versions Supported by the Project

Even though you may use a specific Python version locally to develop your project, the project may support a range of versions. For example, the project may be compatible with Python 3.12 and newer, but you want to use Python 3.12 for your work.

In pyproject.toml, the requires-python field declares compatibility. For example, this project may support Python 3.12 or newer:

[project]
requires-python = ">=3.12"

That does not force every developer to use exactly the same patch release. It only says which versions are acceptable for the project. This separation is useful. The project can support a range of Python versions, while each developer can still pin one concrete version locally.

Defining the Python Version for Your Work

Suppose you want to work on a project with Python 3.12. You can pin that version for the project with:

uv python pin 3.12
Pinned `.python-version` to `3.12`

This creates a .python-version file in the current directory with the specified version. The next time you run uv run, uv will use that version to create the environment and run commands. To verify that the version is pinned correctly, run:

uv run python --version
warning: `VIRTUAL_ENV=/home/runner/work/msdp-book/msdp-book/.venv` does not match the project environment path `.venv` and will be ignored; use `--active` to target the active environment instead
Using CPython 3.12.3 interpreter at: /usr/bin/python3.12
Creating virtual environment at: .venv
Installed 1 package in 1ms
Python 3.12.3

You should see a Python 3.12 version string.

How uv Chooses a Python Interpreter

uv can work with two kinds of Python installations:

By default, uv looks for a compatible Python installation first. If it cannot find one, it can often download a managed version automatically.

That means you often do not need to install Python manually before creating the environment. If the pinned or requested version is missing, uv can often fetch it for you.

Requesting a Version Explicitly

Most uv commands accept a --python flag. Use this when you want to request a version directly in the command instead of relying on .python-version.

For example:

uv run --python 3.13 python --version
warning: `VIRTUAL_ENV=/home/runner/work/msdp-book/msdp-book/.venv` does not match the project environment path `.venv` and will be ignored; use `--active` to target the active environment instead
Using CPython 3.13.13
Removed virtual environment at: .venv
Creating virtual environment at: .venv
Installed 1 package in 3ms
Python 3.13.13

You should see a Python 3.13 version string.

If Python 3.13 is not already available, uv can download it and then create the virtual environment.

In practice, the most useful request formats are:

For day-to-day project work, pinning the version once is usually easier than passing --python repeatedly. The flag is most useful when you want to override the default behavior for a single command.

Inspecting What Is Available

If you want to see which Python versions uv can discover or install, use:

uv python list
cpython-3.15.0b1-linux-x86_64-gnu                 <download available>
cpython-3.15.0b1+freethreaded-linux-x86_64-gnu    <download available>
cpython-3.14.5-linux-x86_64-gnu                   <download available>
cpython-3.14.5+freethreaded-linux-x86_64-gnu      <download available>
cpython-3.13.13-linux-x86_64-gnu                  /home/runner/.local/share/uv/python/cpython-3.13-linux-x86_64-gnu/bin/python3.13
cpython-3.13.13+freethreaded-linux-x86_64-gnu     <download available>
cpython-3.12.13-linux-x86_64-gnu                  <download available>
cpython-3.12.3-linux-x86_64-gnu                   /usr/bin/python3.12
cpython-3.12.3-linux-x86_64-gnu                   /usr/bin/python3 -> python3.12
cpython-3.12.3-linux-x86_64-gnu                   /usr/bin/python -> python3
cpython-3.11.15-linux-x86_64-gnu                  <download available>
cpython-3.10.20-linux-x86_64-gnu                  <download available>
cpython-3.9.25-linux-x86_64-gnu                   <download available>
cpython-3.8.20-linux-x86_64-gnu                   <download available>
pypy-3.11.15-linux-x86_64-gnu                     <download available>
pypy-3.10.16-linux-x86_64-gnu                     <download available>
pypy-3.9.19-linux-x86_64-gnu                      <download available>
pypy-3.8.16-linux-x86_64-gnu                      <download available>
graalpy-3.12.0-linux-x86_64-gnu                   <download available>
graalpy-3.11.0-linux-x86_64-gnu                   <download available>
graalpy-3.10.0-linux-x86_64-gnu                   <download available>
graalpy-3.8.5-linux-x86_64-gnu                    <download available>

To narrow the results to a particular series:

uv python list 3.12
cpython-3.12.13-linux-x86_64-gnu    <download available>
cpython-3.12.3-linux-x86_64-gnu     /usr/bin/python3.12
cpython-3.12.3-linux-x86_64-gnu     /usr/bin/python3 -> python3.12
cpython-3.12.3-linux-x86_64-gnu     /usr/bin/python -> python3
graalpy-3.12.0-linux-x86_64-gnu     <download available>

If you only want to see interpreters that are already installed on your machine:

uv python list --only-installed
cpython-3.13.13-linux-x86_64-gnu    /home/runner/.local/share/uv/python/cpython-3.13-linux-x86_64-gnu/bin/python3.13
cpython-3.12.3-linux-x86_64-gnu     /usr/bin/python3.12
cpython-3.12.3-linux-x86_64-gnu     /usr/bin/python3 -> python3.12
cpython-3.12.3-linux-x86_64-gnu     /usr/bin/python -> python3

This prints only the interpreters that are already installed on your machine. It is useful when you are unsure which interpreters are already available before pinning or creating an environment.

Finding the Exact Interpreter Path

If you need the exact path to the interpreter that uv would use, run:

uv python find
/home/runner/work/msdp-book/msdp-book/.venv/bin/python3

This prints the path to the first compatible Python executable that uv discovers.

You can also ask for a specific version:

uv python find 3.12
uv python find '>=3.11'
/home/runner/work/msdp-book/msdp-book/.venv/bin/python3
/home/runner/work/msdp-book/msdp-book/.venv/bin/python3

If you want to ignore virtual environments and search only for system interpreters, use:

uv python find --system
/usr/bin/python3.12

You should see a filesystem path to a Python executable.

This command is especially helpful when configuring an editor or checking which interpreter uv is about to use.

Upgrading Managed Python Versions

If you are using a uv-managed Python installation, you can upgrade it to the latest supported patch release with:

uv python upgrade 3.12
Installed Python 3.12.13 in 1.16s
 + cpython-3.12.13-linux-x86_64-gnu

Or upgrade all uv-managed Python versions at once:

uv python upgrade
All versions already on latest supported patch release

This updates patch releases within the same minor version, for example from Python 3.12.7 to Python 3.12.13.

Recap

References