pyfaro python¶
pyfaro python lists, installs and pins Python versions through uv. Use it to
see which interpreters are available, to fetch one explicitly, and to record
the version a project should use in .python-version. It is the only
Pyfaro command allowed to make uv download an interpreter.
Quick example¶
$ pyfaro python list --only-installed
cpython-3.14.8-linux-x86_64-gnu /usr/bin/python3.14
cpython-3.13.11-linux-x86_64-gnu ~/.local/share/uv/python/cpython-3.13.11-linux-x86_64-gnu/bin/python3.13
cpython-3.12.12-linux-x86_64-gnu ~/.local/share/uv/python/cpython-3.12.12-linux-x86_64-gnu/bin/python3.12
$ pyfaro python pin 3.13
Pinned `.python-version` to `3.13`
Scenarios¶
1. list: what is available¶
$ pyfaro python list 3.12
cpython-3.12.12-linux-x86_64-gnu ~/.local/share/uv/python/cpython-3.12.12-linux-x86_64-gnu/bin/python3.12
graalpy-3.12.0-linux-x86_64-gnu <download available>
| Option | Effect |
|---|---|
[REQUEST] |
Filter by a Python request such as 3.12. |
--only-installed |
Hide downloads that are only available. |
--all-versions |
Include old patch versions. |
$ pyfaro python list --all-versions 3.12
cpython-3.12.12-linux-x86_64-gnu ~/.local/share/uv/python/cpython-3.12.12-linux-x86_64-gnu/bin/python3.12
cpython-3.12.11-linux-x86_64-gnu <download available>
cpython-3.12.10-linux-x86_64-gnu <download available>
…
list is a catalog query. It installs nothing, and it is not filtered by the
project's requires-python.
2. install: fetch an interpreter explicitly¶
$ pyfaro python install 3.13
Installed Python 3.13.11 in 31ms
+ cpython-3.13.11-linux-x86_64-gnu (python3.13)
$ pyfaro python install 3.12 3.13
All requested versions already installed
With no target, uv uses .python-version (or .python-versions) if present,
and otherwise applies its own default:
$ pyfaro python install
Installed Python 3.12.12 in 32ms
+ cpython-3.12.12-linux-x86_64-gnu (python3.12)
An unknown request fails:
$ pyfaro python install 3.99
error: No download found for request: cpython-3.99-linux-x86_64-gnu
error: uv python install failed (exit status: 2); see uv's output above
Installing is not pinning: an explicit install request does not change the
project.
3. pin: record the project's Python¶
$ pyfaro python pin 3.13
Pinned `.python-version` to `3.13`
$ cat .python-version
3.13
$ pyfaro python pin
3.13
$ pyfaro python pin --rm
Removed Python version file at `.python-version`
pin <REQUEST>writes.python-version.pinwith no request displays the current pin.pin --rmremoves it.
uv checks a new pin against the project's requires-python:
$ pyfaro python pin 3.9
warning: No interpreter found for Python 3.9 in managed installations or search path
error: The requested Python version `3.9` is incompatible with the project `requires-python` value of `>=3.12`.
error: uv python pin failed (exit status: 2); see uv's output above
Pins and requires-python are what uv reads in later sync and run
workflows.
4. --offline and --uv¶
--offline disables network access for all three subcommands, install
included. --uv <path> selects the uv executable. uv 0.9.26 or newer is
required. Requests are passed as separate arguments with no shell. Use --
before a request that starts with a dash.
Project selection¶
Options go before or after the subcommand.
| Form | Meaning |
|---|---|
pyfaro python … |
uv works from the current directory, including its ancestors. |
pyfaro python --project <PATH> … |
Run uv in that exact directory, which must contain a valid pyproject.toml. |
--project lets you pin another project's Python from anywhere:
$ cd other
$ pyfaro python pin 3.12 --project ../acme-widget
Pinned `.python-version` to `3.12`
$ pyfaro python --project ../acme-widget pin
3.12
$ pyfaro python pin 3.12 --project ../nope
error: could not resolve project directory ../nope: No such file or directory (os error 2)
Note
Without --project, pin writes .python-version in uv's discovered
location. In a directory with no project, that is the current directory.
What it writes, and what it never writes¶
Writes: .python-version (pin) and uv's managed interpreters
(install, uv's own cache directory).
Never writes: pyproject.toml, uv.lock or .venv. list writes
nothing. Pyfaro keeps no installer, catalog or cache of its own.
The everyday commands (init, sync,
run) pass --no-python-downloads, so they never download an
interpreter behind your back.
Errors you may hit¶
| Message | Fix |
|---|---|
No Python version file found; specify a version to create one |
pin with no request and no existing pin. Give a version. |
The requested Python version … is incompatible with the project requires-python |
Pin a version inside the range, or update requires-python. |
No download found for request: … |
Check the version spelling with pyfaro python list. |
could not resolve project directory … |
--project points to a missing directory. |
No Python version file found on pin --rm |
There is no pin to remove. |
Exit codes¶
| Code | Meaning |
|---|---|
0 |
The operation succeeded. |
1 |
A Pyfaro error, such as a bad --project. |
2 |
A usage error, or uv failed with status 2 (as in all examples above). |
| other | uv's numeric status is forwarded. |
130 |
Cancelled. |
See also¶
- Python versions workflow
pyfaro sync: build the environment with the pinned Python.pyfaro create:--pythonsets the minimum version.