astral-sh / uv

An extremely fast Python package and project manager, written in Rust.
https://docs.astral.sh/uv
Apache License 2.0
24.7k stars 714 forks source link

[feat] `uv python upgrade` or `uv python install --upgrade` #7892

Open baggiponte opened 3 weeks ago

baggiponte commented 3 weeks ago

Ciao! New python versions are coming out and I wonder if uv can behave a bit more like mise or other devtools in that it can upgrade the python versions. For example, @hynek teased a video about how he uses MOPup to keep his Python versions updated and it would be fun to ruin his plans once again.

Jokes aside, I think it might be useful to either have a way to see if local python versions are outdated (uv python list --outdated?) and possibly a uv python install --upgrade. For example, I think uv python install --upgrade 3.12 automatically downloads the 3.12 release from yesterday (3.12.7 was released) and, if I have an older one, removes that (since the user is explicitly asking for an update).

Currently, uv python install 3.12 does not download anything if there is a 3.12 version already installed on the machine.

This can be a bit of a pain to implement in that it requires all tools installed with a specific python version to a. be reinstalled or b. be modified to point to the new python path.

I searched the issue tab but could not find a similar issue. Feel free to close.

j178 commented 3 weeks ago

This gonna be pretty tricky, as managed Python installations are tied to specific locations based on installation key, which include the full version information. Not only the installed tools, but all venvs created using that Python installation, all of which would need to be recreated as well.

I'm thinking to introduce an intermediary layer between the user and the specific Python installation, called alias for the time.

Proposed operations:

uv python alias <alias> <python-request>: Create/update an alias. This would create an alias to a Python installation based on the resolved Python request. To upgrade or switch the alias to another Python installation, simply rerun the command with a different <python-request>.

Implementation details:

zanieb commented 3 weeks ago

There are a couple related issues

baggiponte commented 3 weeks ago

Not only the installed tools, but all venvs created using that Python installation, all of which would need to be recreated as well.

Completely forgot about this. You are totally right, this is going to be a total PITA to implement 😱 I think that if a user deliberately invokes the command should be aware of the consequences (for venvs at least; perhaps not for tools) and might be informed via a message. But I also see reasons against doing this :)

I guess that, as a starter, it could be handy if uv python install 3.12 would install the latest version, if there's a new one not yet installed?

zanieb commented 3 weeks ago

@baggiponte if you use uv python install 3.12 --reinstall we will upgrade it — we can add an --upgrade option that only reinstalls on upgrade though. Otherwise uv python install 3.12 will exit happily if the request is satisfied, in the same way as uv pip install ruff if you already have ruff installed.

baggiponte commented 3 weeks ago

@baggiponte if you use uv python install 3.12 --reinstall we will upgrade it — we can add an --upgrade option that only reinstalls on upgrade though. Otherwise uv python install 3.12 will exit happily if the request is satisfied, in the same way as uv pip install ruff if you already have ruff installed.

I guess, problem solved:

uv python install --reinstall 3.{9,10,11,12}
Searching for Python versions matching: Python 3.10
Found existing installation for Python 3.10: cpython-3.10.14-macos-aarch64-none
Searching for Python versions matching: Python 3.11
Found existing installation for Python 3.11: cpython-3.11.9-macos-aarch64-none
Searching for Python versions matching: Python 3.12
Found existing installation for Python 3.12: cpython-3.12.5-macos-aarch64-none
Searching for Python versions matching: Python 3.9
Found existing installation for Python 3.9: cpython-3.9.19-macos-aarch64-none
Installed 4 versions in 11.25s
 - cpython-3.9.19-macos-aarch64-none
 + cpython-3.9.20-macos-aarch64-none
 - cpython-3.10.14-macos-aarch64-none
 + cpython-3.10.15-macos-aarch64-none
 - cpython-3.11.9-macos-aarch64-none
 + cpython-3.11.10-macos-aarch64-none
 - cpython-3.12.5-macos-aarch64-none
 + cpython-3.12.6-macos-aarch64-none

I'm kinda happy with this. If you think it makes sense, I'd be willing to document this behaviour in the docs 😊

EDIT:

of course, after this I ran uv tool upgrade --all and it rightfully complained:

Failed to upgrade `argcomplete`: `argcomplete` is not installed; run `uv tool install argcomplete` to install
Failed to upgrade `asitop`: `asitop` is not installed; run `uv tool install asitop` to install
Failed to upgrade `azure-cli`: `azure-cli` is not installed; run `uv tool install azure-cli` to install
Failed to upgrade `commitizen`: `commitizen` is not installed; run `uv tool install commitizen` to install
Failed to upgrade `cookiecutter`: `cookiecutter` is not installed; run `uv tool install cookiecutter` to install
Failed to upgrade `huggingface-hub`: `huggingface-hub` is not installed; run `uv tool install huggingface-hub` to install
Failed to upgrade `jupytext`: `jupytext` is not installed; run `uv tool install jupytext` to install
Failed to upgrade `mypy`: `mypy` is not installed; run `uv tool install mypy` to install
Failed to upgrade `pytest`: `pytest` is not installed; run `uv tool install pytest` to install
Failed to upgrade `ruff`: `ruff` is not installed; run `uv tool install ruff` to install

I tried uv tool upgrade --all --reinstall but it did not work. I wonder if it made sense to have a sort of "symmetry"/combination of the two flags?