Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add uv python install --default #8650

Merged
merged 2 commits into from
Dec 3, 2024
Merged

Add uv python install --default #8650

merged 2 commits into from
Dec 3, 2024

Conversation

zanieb
Copy link
Member

@zanieb zanieb commented Oct 28, 2024

This pull request is best viewed with whitespace hidden

Adds a --default flag to uv python install in preview. This includes a python and python{major} executable in addition to the python{major}.{minor} executable. We will replace uv-managed executables, but externally managed executables require the --force flag to overwrite.

If you run uv python install (without arguments), we include the --default flag implicitly to populate python and python3 for the "default" install version.

In the future, we should add a warning if the installed executable isn't at the front of the PATH.

@zanieb zanieb force-pushed the zb/python-exec-default branch 2 times, most recently from 457a318 to 4579f3f Compare October 29, 2024 15:41
@zanieb zanieb force-pushed the zb/python-exec-dir branch 2 times, most recently from 783e70d to 00873e2 Compare October 29, 2024 16:28
@zanieb zanieb force-pushed the zb/python-exec-default branch from 4579f3f to 7e14476 Compare October 29, 2024 16:28
@zanieb zanieb force-pushed the zb/python-exec-default branch 3 times, most recently from 5280eab to 0598d60 Compare October 29, 2024 22:29
@zanieb zanieb force-pushed the zb/python-exec-dir branch 5 times, most recently from bb90cbd to ae37a24 Compare October 30, 2024 14:05
Base automatically changed from zb/python-exec-dir to main October 30, 2024 14:13
zanieb added a commit that referenced this pull request Oct 30, 2024
…v python install` (#8458)

Updates `uv python install` to link `python3.x` in the executable
directory (i.e., `~/.local/bin`) to the the managed interpreter path.

Includes

- #8569 
- #8571 

Remaining work

- #8663 
- #8650 
- Add an opt-out setting and flag
- Update documentation
@zanieb zanieb force-pushed the zb/python-exec-default branch 2 times, most recently from 032950f to 43e7779 Compare October 30, 2024 15:15
zanieb added a commit that referenced this pull request Oct 30, 2024
Pulling out of #8650 for
readability.

Trying to clean this up to simplify extensions in the future. This is
not a strict refactor, there are behavioral changes here.

- Adds some structs for managing state.
- Addresses some likely inconsistent behavior for weird edge-cases. 
- We fill platform information before checking if a request is
satisfied.
- We error earlier if we can't find a download for the request, i.e.,
even if you somehow have it installed.
- Only reports versions as uninstalled if a download actually replaces
them.
- Moves some of the default output to tracing messages.
- Even if an installation was already satisfied, we'll check that it is
setup properly
@zanieb zanieb force-pushed the zb/python-exec-default branch 2 times, most recently from 2981c8d to 4e4d3cd Compare October 31, 2024 00:59
@zanieb zanieb added the preview Experimental behavior label Oct 31, 2024
@zanieb zanieb force-pushed the zb/python-exec-default branch from 4e4d3cd to 40c88cd Compare October 31, 2024 01:09
zanieb added a commit that referenced this pull request Oct 31, 2024
@zanieb zanieb force-pushed the zb/python-exec-default branch 4 times, most recently from af592db to 25ad2fe Compare November 1, 2024 13:28
@zanieb
Copy link
Member Author

zanieb commented Nov 26, 2024

Thanks, I can look into fixing that.

@jooon
Copy link
Contributor

jooon commented Nov 27, 2024

I am a bit confused how the default versions are replaced. I know I can force replace them by adding --force, but if I don't, what is replaced feels a bit off.

Starting from scratch, install and set 3.12.6 as default

$ uv python install --default 3.12.6
Installed Python 3.12.6 in 4.55s
 + cpython-3.12.6-linux-x86_64-gnu (python, python3, python3.12)

OK!

New version released, install and set 3.12.7 as default

$ uv python install --default 3.12.7
Installed Python 3.12.7 in 4.60s
 + cpython-3.12.7-linux-x86_64-gnu (python, python3, python3.12)

OK!

New minor version released, install and set 3.13 as default.

$ uv python install --default 3.13
Installed Python 3.13.0 in 4.17s
 + cpython-3.13.0-linux-x86_64-gnu (python3.13)

hmm?

@zanieb
Copy link
Member Author

zanieb commented Nov 27, 2024

That looks wrong indeed :) thanks for giving it a try.

@jooon
Copy link
Contributor

jooon commented Nov 27, 2024

Should --default maybe always imply --force?

From scratch again:

$ uv python install --default 3.13 3.12
Installed 2 versions in 7.93s
 + cpython-3.12.7-linux-x86_64-gnu (python3.12)
 + cpython-3.13.0-linux-x86_64-gnu (python, python3, python3.13)
$ uv python install --default 3.12
$ echo $?
0
$ python
Python 3.13.0 (main, Oct 16 2024, 03:23:02) [Clang 18.1.8 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

The install command returns success because it has successfully made sure there is a 3.12 version installed. However, in my mind, it "failed" to set 3.12 as default.

@zanieb
Copy link
Member Author

zanieb commented Nov 27, 2024

If you use --default with multiple versions we'll set the first one as the default. Sorry, missed a command invocation there. We should definitely override uv managed executables with --default. --force implies overriding executables not managed by uv. For reference, the verbose logs are:

❯ cargo run -- python install --preview --default 3.12 -v
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.17s
     Running `target/debug/uv python install --preview --default 3.12 -v`
DEBUG uv 0.5.4 (c1619ee49 2024-11-26)
DEBUG Acquired lock for `/Users/zb/.local/share/uv/python`
DEBUG Found `cpython-3.12.7-macos-aarch64-none` for request `Python 3.12`
DEBUG Using request timeout of 30s
DEBUG Inspecting existing executable at `/Users/zb/.local/bin/python3.12`
DEBUG Executable at `/Users/zb/.local/bin/python3.12` is already for `cpython-3.12.7-macos-aarch64-none`
DEBUG Inspecting existing executable at `/Users/zb/.local/bin/python3`
DEBUG Executable already exists at `cpython-3.13.0-macos-aarch64-none` for `/Users/zb/.local/bin/python3`. Use `--force` to replace it
DEBUG Inspecting existing executable at `/Users/zb/.local/bin/python`
DEBUG Executable already exists at `cpython-3.13.0-macos-aarch64-none` for `/Users/zb/.local/bin/python`. Use `--force` to replace it
DEBUG Released lock at `/Users/zb/.local/share/uv/python/.lock`

@zanieb
Copy link
Member Author

zanieb commented Nov 27, 2024

That's fixed now.

@jooon
Copy link
Contributor

jooon commented Nov 27, 2024

--default works as I expected now!

--force seems to both be needed to replace executables not managed by uv as well as allowing minor versions managed by uv to be downgraded.

$ touch $HOME/.local/bin/python3.12

$ uv python install 3.12.5
Installed Python 3.12.5 in 4.85s
 + cpython-3.12.5-linux-x86_64-gnu
error: Failed to install cpython-3.12.5-linux-x86_64-gnu
  Caused by: Executable already exists at `/home/jon/.local/bin/python3.12` but is not managed by uv; use `--force` to replace it

$ uv python install --force 3.12.5
Installed Python 3.12.5 in 7ms
 + cpython-3.12.5-linux-x86_64-gnu (python3.12)

$ uv python install 3.12.7
Installed Python 3.12.7 in 4.57s
 + cpython-3.12.7-linux-x86_64-gnu (python3.12)

$ uv python install 3.12.6
Installed Python 3.12.6 in 4.44s
 + cpython-3.12.6-linux-x86_64-gnu

$ uv python install --force 3.12.6
Installed Python 3.12.6 in 6ms
 + cpython-3.12.6-linux-x86_64-gnu (python3.12)

@zanieb
Copy link
Member Author

zanieb commented Nov 27, 2024

The latter is intentional. Do you think we should make the log more visible explaining that behavior?

@jooon
Copy link
Contributor

jooon commented Nov 27, 2024

I think it makes perfect sense and I don't think it needs to be clarified. More information can also confuse.

I think I was mostly confused by your comment above that --force was for replacing executables not managed by uv. I just had never encountered that before.

zanieb added a commit that referenced this pull request Nov 27, 2024
These were erroneously being filtered, interfering with the snapshots in
#8650
@zanieb zanieb force-pushed the zb/python-exec-default branch 3 times, most recently from 44b018a to fc46546 Compare November 27, 2024 14:58
@zanieb zanieb force-pushed the zb/python-exec-default branch from fc46546 to c2b582a Compare November 27, 2024 15:40
@zanieb zanieb requested a review from charliermarsh November 27, 2024 16:03
@zanieb
Copy link
Member Author

zanieb commented Nov 27, 2024

In a follow-up, I'd like to change the executable display to include all the executables available for the version not just the ones we added in this invocation.

Copy link
Member

@charliermarsh charliermarsh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good, just a few comments.

crates/uv/src/commands/python/install.rs Outdated Show resolved Hide resolved
crates/uv-cli/src/lib.rs Show resolved Hide resolved
@@ -302,114 +312,136 @@ pub(crate) async fn install(
.expect("We should have a bin directory with preview enabled")
.as_path();

let target = bin.join(installation.key().versioned_executable_name());
let targets = if (default || is_default_install)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is_default_install here? I thought that meant something distinct from default.

Copy link
Member Author

@zanieb zanieb Dec 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you run uv python install (without arguments), we include the --default flag implicitly to populate python and python3 for the "default" install version.

When you run uv python install without arguments, it's a "default install". The idea is for that bootstrapping experience to get you a complete installation. Using the --default flag in subsequent operations would be used to change the default.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(If you've previously installed Python with uv, using uv python install without arguments has no effect)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, ok. But if there's a .python-version file, it does not count as a "default" install.

Copy link
Member Author

@zanieb zanieb Dec 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm not really sure if it makes sense but I would find it surprising for my "default" version to be set when installing the Python versions needed for a project, e.g., I noticed this for uv. It's pretty niche though.

target.simplified_display()
);
for target in targets {
let target = bin.join(target);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is everything from here down mostly just an indent of the existing logic?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, and some tweaks from rebases though I've reduced those a couple times.

This pull request is best viewed with whitespace hidden

Copy link
Member

@charliermarsh charliermarsh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Trust you to act on feedback as you see fit!)

@zanieb
Copy link
Member Author

zanieb commented Dec 2, 2024

Should be addressed in d3d94ce

@zanieb zanieb force-pushed the zb/python-exec-default branch from d3d94ce to d95fe76 Compare December 2, 2024 23:51
@zanieb zanieb merged commit 63443f1 into main Dec 3, 2024
64 checks passed
@zanieb zanieb deleted the zb/python-exec-default branch December 3, 2024 01:05
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Dec 5, 2024
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.5.5` -> `0.5.6` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>astral-sh/uv (astral-sh/uv)</summary>

### [`v0.5.6`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#056)

[Compare Source](astral-sh/uv@0.5.5...0.5.6)

##### Enhancements

-   Add `--dry-run` to `uv pip uninstall` ([#&#8203;9557](astral-sh/uv#9557))
-   Allow `--constraints` and `--overrides` in `uv tool install` ([#&#8203;9547](astral-sh/uv#9547))
-   Display removed Python executables on uninstall ([#&#8203;9459](astral-sh/uv#9459))
-   Warn when keyring has no password for `uv publish` ([#&#8203;8827](astral-sh/uv#8827))
-   Add suggested action when `.python-version` pin is incompatible with the project ([#&#8203;9590](astral-sh/uv#9590))
-   Improve error messages for mismatches in `tool.uv.sources` ([#&#8203;9482](astral-sh/uv#9482))
-   Use constraints in trace rather than irrelevant `requires-python` ([#&#8203;9529](astral-sh/uv#9529))

##### Preview features

-   Add `uv python install --default` ([#&#8203;8650](astral-sh/uv#8650))
-   Fix Python executable installation when multiple patch versions are requested ([#&#8203;9607](astral-sh/uv#9607))
-   Build backend: Revamp `include` / `exclude` ([#&#8203;9525](astral-sh/uv#9525))
-   Build backend: Add fast path  ([#&#8203;9556](astral-sh/uv#9556))
-   Build backend: Add functions to collect file list ([#&#8203;9602](astral-sh/uv#9602))
-   Build backend: Default excludes ([#&#8203;9552](astral-sh/uv#9552))
-   Build backend: Refactoring before list ([#&#8203;9558](astral-sh/uv#9558))
-   Build backend: Warn when visiting over 10k files  ([#&#8203;9523](astral-sh/uv#9523))

##### Configuration

-   Make `check-url` available in configuration files ([#&#8203;9032](astral-sh/uv#9032))

##### Performance

-   Avoid adding non-extra package with extra dependencies ([#&#8203;9540](astral-sh/uv#9540))
-   Avoid cloning `String` in marker evaluation ([#&#8203;9598](astral-sh/uv#9598))

##### Rust API

-   `uv-pep508`: Add more methods for simplifying `extra`-related expressions ([#&#8203;9469](astral-sh/uv#9469))

##### Bug fixes

-   Allow `file:` URLs to include package names ([#&#8203;9493](astral-sh/uv#9493))
-   Avoid using IDs across PubGrub states ([#&#8203;9538](astral-sh/uv#9538))
-   Consistently enforce requested-vs.-built metadata when retrieving wheels ([#&#8203;9484](astral-sh/uv#9484))
-   Do not show empty version specifier in `uv tool list` ([#&#8203;9605](astral-sh/uv#9605))
-   Include Git member information when getting metadata from cache ([#&#8203;9388](astral-sh/uv#9388))
-   Include base installation directory in uv run PATH ([#&#8203;9585](astral-sh/uv#9585))
-   Insert backslash when appending to system drive ([#&#8203;9488](astral-sh/uv#9488))
-   Normalize paths when lowering Git dependencies ([#&#8203;9595](astral-sh/uv#9595))
-   Omit origin when comparing requirements ([#&#8203;9570](astral-sh/uv#9570))
-   Override `manylinux_compatible` with `--python-platform` ([#&#8203;9526](astral-sh/uv#9526))
-   Pass extra when evaluating lockfile markers ([#&#8203;9539](astral-sh/uv#9539))
-   Propagate markers for recursive extras in resolver ([#&#8203;9509](astral-sh/uv#9509))
-   Respect path dependencies within Git dependencies ([#&#8203;9594](astral-sh/uv#9594))
-   Support recursive extras with marker in `pip compile -r pyproject.toml` ([#&#8203;9535](astral-sh/uv#9535))
-   Don't emit unpinned warning for proxy packages ([#&#8203;9497](astral-sh/uv#9497))
-   Fix `--refresh-package` flag mentioned as `--refresh-dependency` ([#&#8203;9486](astral-sh/uv#9486))
-   Handle Windows AV/EDR file locks during script installations ([#&#8203;9543](astral-sh/uv#9543))
-   Re-enable conflicting extra/group tests and fix regression from [#&#8203;9540](astral-sh/uv#9540) ([#&#8203;9582](astral-sh/uv#9582))

##### Documentation

-   Add missing word to docs for `run.md` ([#&#8203;9527](astral-sh/uv#9527))
-   Add policies reference section and license document ([#&#8203;9367](astral-sh/uv#9367))
-   Fix typo in entry point docs ([#&#8203;9491](astral-sh/uv#9491))
-   Fix up version in prior uninstall instructions ([#&#8203;9485](astral-sh/uv#9485))
-   Mention `uv pip` behavior in build system note ([#&#8203;9586](astral-sh/uv#9586))
-   Update build failures document ([#&#8203;9584](astral-sh/uv#9584))
-   Correct wording for multiple sources section ([#&#8203;9504](astral-sh/uv#9504))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
preview Experimental behavior
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants