When developing a Python project, there are two related but distinct questions about Python versions that you need to answer:
Which Python versions does your project support for users who want to install it?
Which Python version do you want to use for your work?
The answers to these questions are important because:
it affects which language features and standard library APIs you can use,
it determines which versions of third-party packages are compatible with your project
it affects the ease of installation and collaboration for your project
To capture the answers to these two questions, uv will use two different files:
requires-pythoninpyproject.tomldeclares which Python versions the project supports;.python-versionrecords which Python version you want to use locally while working on the project.
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.12Pinned `.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 --versionwarning: `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:
managed Python installations, which are downloaded and installed by uv;
system Python installations, which include Python versions already available on your machine, whether they came from the operating system, Homebrew, pyenv, Conda, or some other tool.
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 --versionwarning: `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:
an exact version such as
3.13.0;a minor version such as
3.13;a version range such as
>=3.10,<3.14;a direct interpreter path such as
/opt/homebrew/bin/python3.13.
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 listcpython-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.12cpython-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-installedcpython-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.12Installed 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 upgradeAll 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¶
use
.python-versionwhen you want to pin one concrete Python version for your local work;use
requires-pythonwhen you want to declare which Python versions the project supports;use
--pythonwhen you want to override the default choice for one command;use
uv python listanduv python findwhen you want to inspect what is available or whatuvwill select.