Skip to content

Conversation

@InSyncWithFoo
Copy link
Contributor

@InSyncWithFoo InSyncWithFoo commented Mar 2, 2025

Summary

Resolves #11794.

When uv python find is given a --script option, either the existing environment for that script or the Python executable that would be used to create it will be returned. If neither are found, the command exits with exit code 1.

--script is incompatible with all other options to the same command.

Test Plan

Unit tests.

@zanieb zanieb self-assigned this Mar 2, 2025
@InSyncWithFoo InSyncWithFoo marked this pull request as ready for review March 2, 2025 19:30
@konstin konstin added the enhancement New feature or improvement to existing functionality label Mar 3, 2025
@zanieb
Copy link
Member

zanieb commented Mar 5, 2025

How did you choose to exit with a non-zero code if the environment does not exist rather than showing the interpreter we would use to create the environment? I think there's probably a use case for uv python find --script <path> that shows the interpreter that fulfills the requires-python range, right? The downside here is that a user then needs to do more analysis to understand if the interpreter is for the synced environment or not.

Separately, if we're going to exit with a non-zero code, we need to show a message indicating why we failed.

@InSyncWithFoo
Copy link
Contributor Author

InSyncWithFoo commented Mar 5, 2025

@zanieb I was thinking about my use case: An existing environment is needed to power language features. Showing the base interpreter would be misleading, since it won't have access to the dependencies of the script. Additionally, if an environment doesn't exist, the user should have a chance to decide whether it should be created or not.

As for the exit code and error messages, I don't have a strong opinion. Maybe exit code 0 should be used even when an interpreter cannot be found.

@zanieb
Copy link
Member

zanieb commented Mar 5, 2025

For your use-case, why wouldn't you always run a sync operation first?

The problem with failing if the environment doesn't exist is that it's inconsistent with how this interface normally behaves, e.g.:

❯ uv python find
/Users/zb/.local/share/uv/python/cpython-3.13.0-macos-aarch64-none/bin/python3.13
❯ uv sync
❯ uv python find
/Users/zb/workspace/uv/example/.venv/bin/python3

We could consider --script "opt-in" to requiring the script's environment to be found, but then there's no way for users to recover the behavior I described where you want to inspect what interpreter would be used for a given script.

@InSyncWithFoo
Copy link
Contributor Author

sync is a potentially expensive process; running it "just" to retrieve the interpreter is very likely not desirable.

@charliermarsh
Copy link
Member

If the environment doesn't exist, I would probably expect uv python find --script to show me where the script environment would be, rather than the interpreter that would be used to create it.

@InSyncWithFoo
Copy link
Contributor Author

InSyncWithFoo commented Mar 5, 2025

@charliermarsh That is also undesirable: Tools might run the interpreter to retrieve its version. If I recall correctly, both PyCharm and Pyright do this.

@charliermarsh
Copy link
Member

Either way they have to handle the environment not existing, right?

@zanieb
Copy link
Member

zanieb commented Mar 5, 2025

Either way they have to handle the environment not existing, right?

👍 that's my point.

Tools might run the interpreter to retrieve its version.

If all you want is the interpreter for metadata, uv python find makes sense. It'd be bad if it showed you the path to an interpreter that does not exist. You don't need the virtual environment to know what Python interpreter uv would use.

sync is a potentially expensive process; running it "just" to retrieve the interpreter is very likely not desirable.

If you are trying to provide up-to-date type information, this seems like what you need though? As Charlie said, you need to handle the case where it doesn't exist regardless.

If the environment doesn't exist, I would probably expect uv python find --script to show me where the script environment would be, rather than the interpreter that would be used to create it.

That's not how it works for projects, though I'd be willing to consider changing that. I think it's more like uv env find (or uv python find --env) at that point? I worry quite a bit about returning the path to an interpreter that does not exist. We don't have a good way to signal that to the user.

@InSyncWithFoo
Copy link
Contributor Author

If you are trying to provide up-to-date type information, this seems like what you need though? As Charlie said, you need to handle the case where it doesn't exist regardless.

In my opinion, such expensive processes should not be run without explicit user consent. Here's how I think the logic should be:

  • If the interpreter exists and it is up-to-date, that's great.
  • If the interpreter exists but not up-to-date, the user will be asked if they want to synchronize it (e.g., in the form of a quick fix to an "unresolved import" error).
  • If the interpreter does not exist, the user will be asked if they want to create it.

If the installation is known to take a long time, the user might not want to create an environment on their development machine (especially if they don't intend to do any significant changes). Even if they do want to, prompting gives them a chance to check the script metadata block for any potential problems, like a typo in a dependency specifier.

The interpreter given must be one that belongs to the environment of that script. Otherwise, tools might have to do things twice, one for the global/base interpreter and one for the new interpreter (PyCharm would reindex the standard library, for example).

@zanieb
Copy link
Member

zanieb commented Mar 6, 2025

In my opinion, such expensive processes should not be run without explicit user consent

This is roughly the antithesis of the design of this tool. We do these things transparently in the background all the time. We invest in making them fast enough that this is not expensive.

Regardless... if we return to your use-case, I think all you need is uv sync --dry-run?

❯ uv init --script foo.py
Initialized script at `foo.py`
❯ uv sync --script foo.py --dry-run
Would create script environment at: /Users/zb/.cache/uv/environments-v2/foo-2a05ce447f85797e

@InSyncWithFoo
Copy link
Contributor Author

We invest in making them fast enough that this is not expensive.

That's just uv itself. Downloading takes time, and I have seen many complaints about how PyCharm's indexing takes seemingly forever.

Using uv sync --dry-run has two disadvantages:

  • The path is that of the virtual environment directory, rather than the interpreter. Monkeypatching client-side is simple enough, but I'd rather not to.
  • It would happily return the path to a potentially non-existent directory, which is undesired. The messages can be used to differentiate the two cases, but this is rather fragile.

@zanieb
Copy link
Member

zanieb commented Mar 6, 2025

The path is that of the virtual environment directory, rather than the interpreter. Monkeypatching client-side is simple enough, but I'd rather not to.

I think this is well within scope for a consumer, but we could definitely add the "supposed" interpreter path to a JSON output format.

It would happily return the path to a potentially non-existent directory, which is undesired. The messages can be used to differentiate the two cases, but this is rather fragile.

I think you'd use a JSON output mode to differentiate between these cases, so it's not fragile.

@InSyncWithFoo
Copy link
Contributor Author

I think you'd use a JSON output mode to differentiate between these cases, so it's not fragile.

That would be right, except sync doesn't support --format. This would be within the scope of #3199.

Return to the PR at hand: The hypothetical sync --dry-run --format=json doesn't exist just yet (and tackling that would require even more design), so I'm inclined to keep this PR as it is, save for the exit code and such. What do you say?

@zanieb
Copy link
Member

zanieb commented Mar 7, 2025

I don't think I'm wiling to compromise on the consistency of the uv python find behavior to fulfill a use-case that would better filled in another interface.

@zanieb
Copy link
Member

zanieb commented Mar 20, 2025

Thanks for updating the branch. I'll review again today so it doesn't go stale again.

Copy link
Member

@zanieb zanieb left a comment

Choose a reason for hiding this comment

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

Thanks for your patience here

@zanieb zanieb merged commit b128aa0 into astral-sh:main Mar 21, 2025
76 checks passed
@zanieb
Copy link
Member

zanieb commented Mar 21, 2025

w.r.t. adding an --output-format to uv sync (ref #11891 (comment)) — at some point I want a holistic design for #3199 but I don't think that needs to block commands where JSON output will unblock a concrete use-case. If you're interested in adding that, I'm supportive.

@InSyncWithFoo InSyncWithFoo deleted the python-find-script branch March 21, 2025 06:33
Gankra added a commit that referenced this pull request Mar 21, 2025
Gankra added a commit that referenced this pull request Mar 21, 2025
This reverts commit b128aa0 (#11891)

It *seems* like it's causing several tests to fail on linux?
Gankra added a commit that referenced this pull request Mar 21, 2025
zanieb added a commit that referenced this pull request Mar 21, 2025
Let's see if this reproduces in a PR now...

---------

Co-authored-by: Zanie Blue <[email protected]>
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Mar 26, 2025
This MR contains the following updates:

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

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.6.10`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0610)

[Compare Source](astral-sh/uv@0.6.9...0.6.10)

##### Enhancements

-   Add `uv sync --check` flag ([#&#8203;12342](astral-sh/uv#12342))
-   Add support for Python version requests in `uv python list` ([#&#8203;12375](astral-sh/uv#12375))
-   Support `.env` files in `uv tool run` ([#&#8203;12386](astral-sh/uv#12386))
-   Support `python find --script` ([#&#8203;11891](astral-sh/uv#11891))

##### Preview features

-   Check all compatible torch indexes when `--torch-backend` is enabled ([#&#8203;12385](astral-sh/uv#12385))

##### Performance

-   Use a boxed slice for extras and groups ([#&#8203;12391](astral-sh/uv#12391))
-   Use small string for index name type ([#&#8203;12355](astral-sh/uv#12355))

##### Bug fixes

-   Allow virtual packages with `--no-build` ([#&#8203;12314](astral-sh/uv#12314))
-   Ignore `--find-links` entries for pinned indexes ([#&#8203;12396](astral-sh/uv#12396))
-   Omit wheels from lockfile based on `--exclude-newer` ([#&#8203;12299](astral-sh/uv#12299))
-   Retain end-of-line comment position when adding dependency ([#&#8203;12360](astral-sh/uv#12360))
-   Omit fragment when querying for wheels in Simple HTML API ([#&#8203;12384](astral-sh/uv#12384))
-   Error on missing argument in `requirements.txt` ([#&#8203;12354](astral-sh/uv#12354))
-   Support modules with different casing in build backend ([#&#8203;12240](astral-sh/uv#12240))
-   Add authentication policy support for `pip` commands ([#&#8203;12470](astral-sh/uv#12470))

</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:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMTMuNSIsInVwZGF0ZWRJblZlciI6IjM5LjIxMy41IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Apr 21, 2025
## 0.6.14

### Python versions

The following Python versions have been added:

- CPython 3.13.3
- CPython 3.12.10
- CPython 3.11.12
- CPython 3.10.17
- CPython 3.9.22

See the [`python-build-standalone` release notes](https://github.com/astral-sh/python-build-standalone/releases/tag/20250409) for more details.

### Enhancements

- Add `uv-build` and `uv_build` aliases to `uv init --build-backend` ([#12776](astral-sh/uv#12776))
- Emit dedicated error message for Conda `environment.yml` files ([#12669](astral-sh/uv#12669))


### Preview features

- Build backend: Check module dir exists for sdist build ([#12779](astral-sh/uv#12779))
- Build backend: Fix sdist with long directories ([#12764](astral-sh/uv#12764))

### Performance

- Avoid querying GitHub on repeated install invocations ([#12767](astral-sh/uv#12767))

### Bug fixes

- Error when `tool.uv.sources` is set in system-level configuration file ([#12757](astral-sh/uv#12757))
- Split workspace members onto their own lines in `uv init` ([#12756](astral-sh/uv#12756))

### Documentation

- Add lockfile note about PEP 751 ([#12732](astral-sh/uv#12732))
- Extend the reference documentation for `uv pip sync` ([#12683](astral-sh/uv#12683))
- Fix mismatched pip interface header / nav titles ([#12640](astral-sh/uv#12640))

## 0.6.13

### Enhancements

- Add `--show-version` to `uv python find` ([#12376](astral-sh/uv#12376))
- Remove `--no-config` warning from `uv pip compile` and `uv pip sync` ([#12642](astral-sh/uv#12642))
- Skip repeated directories in `PATH` when searching for Python interpreters ([#12367](astral-sh/uv#12367))
- Unset `SCRIPT_PATH` in relocatable activation script ([#12672](astral-sh/uv#12672))
- Add `UV_PYTHON_DOWNLOADS_JSON_URL` to set custom managed python sources ([#10939](astral-sh/uv#10939))
- Reject `pyproject.toml` files in `uv pip compile -o` ([#12673](astral-sh/uv#12673))
- Respect the `--offline` flag for Git operations ([#12619](astral-sh/uv#12619))

### Bug fixes

- Warn instead of error if CRC appears to be missing ([#12722](astral-sh/uv#12722))
- Avoid infinite loop in `uv export` with conflicts ([#12726](astral-sh/uv#12726))

### Rust API

- Update MSRV to 1.84 ([#12670](astral-sh/uv#12670))

## 0.6.12

### Enhancements

- Report the queried executable path in `uv python list` ([#12628](astral-sh/uv#12628))
- Improve archive unpack error messages ([#12627](astral-sh/uv#12627))

### Bug fixes

- Respect `authenticate` when using `explicit = true` ([#12631](astral-sh/uv#12631))
- Normalize extra and group names in `uv add` and `uv remove` ([#12586](astral-sh/uv#12586))
- Enforce CRC-32 checks when unpacking archives ([#12623](astral-sh/uv#12623))
- Fix parsing of `python-platform` in settings files ([#12592](astral-sh/uv#12592))

### Documentation

- Add note about `uv build` to `package = false` ([#12608](astral-sh/uv#12608))
- Add index fallback note to `authenticate = always` documentation ([#12498](astral-sh/uv#12498))
- Fix invalid 'kind' reference in flat index docs ([#12583](astral-sh/uv#12583))

## 0.6.11

### Enhancements

- Add dependents ("via ..." comments) in `uv export` command ([#12350](astral-sh/uv#12350))
- Bump least-recent non-EOL macOS version to 13.0 ([#12518](astral-sh/uv#12518))
- Support `--find-links`-style "flat" indexes in `[[tool.uv.index]]` ([#12407](astral-sh/uv#12407))
- Distinguish between `-q` and `-qq` ([#12300](astral-sh/uv#12300))

### Configuration

- Support `UV_PROJECT` environment to set project directory. ([#12327](astral-sh/uv#12327))

### Performance

- Use a boxed slice for various requirement types ([#12514](astral-sh/uv#12514))

### Bug fixes

- Add a newline after metadata when initializing scripts with other metadata blocks ([#12501](astral-sh/uv#12501))
- Avoid writing empty `requires-python` to script blocks ([#12517](astral-sh/uv#12517))
- Respect build constraints in `uv sync` ([#12502](astral-sh/uv#12502))
- Respect transitive dependencies in `uv tree --only-group` ([#12560](astral-sh/uv#12560))

## 0.6.10

### Enhancements

- Add `uv sync --check` flag ([#12342](astral-sh/uv#12342))
- Add support for Python version requests in `uv python list` ([#12375](astral-sh/uv#12375))
- Support `.env` files in `uv tool run` ([#12386](astral-sh/uv#12386))
- Support `python find --script` ([#11891](astral-sh/uv#11891))

### Preview features

- Check all compatible torch indexes when `--torch-backend` is enabled ([#12385](astral-sh/uv#12385))

### Performance

- Use a boxed slice for extras and groups ([#12391](astral-sh/uv#12391))
- Use small string for index name type ([#12355](astral-sh/uv#12355))

### Bug fixes

- Allow virtual packages with `--no-build` ([#12314](astral-sh/uv#12314))
- Ignore `--find-links` entries for pinned indexes ([#12396](astral-sh/uv#12396))
- Omit wheels from lockfile based on `--exclude-newer` ([#12299](astral-sh/uv#12299))
- Retain end-of-line comment position when adding dependency ([#12360](astral-sh/uv#12360))
- Omit fragment when querying for wheels in Simple HTML API ([#12384](astral-sh/uv#12384))
- Error on missing argument in `requirements.txt` ([#12354](astral-sh/uv#12354))
- Support modules with different casing in build backend ([#12240](astral-sh/uv#12240))
- Add authentication policy support for `pip` commands ([#12470](astral-sh/uv#12470))

## 0.6.9

### Enhancements

- Use `keyring --mode creds` when `authenticate = "always"` ([#12316](astral-sh/uv#12316))
- Fail with specific error message when no password is present and `authenticate = "always"` ([#12313](astral-sh/uv#12313))

### Bug fixes

- Add boolish value parser for `UV_MANAGED_PYTHON` flags ([#12345](astral-sh/uv#12345))
- Make deserialization non-fatal when assessing source tree revisions ([#12319](astral-sh/uv#12319))
- Use resolver-returned wheel over alternate cached wheel ([#12301](astral-sh/uv#12301))

### Documentation

- Add experimental `--torch-backend` to the PyTorch guide ([#12317](astral-sh/uv#12317))
- Fix `#keyring-provider` references in alternative index docs ([#12315](astral-sh/uv#12315))
- Fix `--directory` path in examples ([#12165](astral-sh/uv#12165))

### Preview changes

- Automatically infer the PyTorch index via `--torch-backend=auto` ([#12070](astral-sh/uv#12070))

## 0.6.8

### Enhancements

- Add support for enabling all groups by default with `default-groups = "all"` ([#12289](astral-sh/uv#12289))
- Add simpler `--managed-python` and `--no-managed-python` flags for toggling Python preferences ([#12246](astral-sh/uv#12246))

### Performance

- Avoid allocations for default cache keys ([#12063](astral-sh/uv#12063))

### Bug fixes

- Allow local version mismatches when validating lockfile ([#12285](astral-sh/uv#12285))
- Allow owned string when deserializing `requires-python` ([#12278](astral-sh/uv#12278))
- Make cache errors non-fatal in `Planner::build` ([#12281](astral-sh/uv#12281))

## 0.6.7

### Python

- Add CPython 3.14.0a6
- Fix regression where extension modules would use wrong `CXX` compiler on Linux
- Enable FTS3 enhanced query syntax for SQLite

See the [`python-build-standalone` release notes](https://github.com/astral-sh/python-build-standalone/releases/tag/20250317) for more details.

### Enhancements

- Add support for `-c` constraints in `uv add` ([#12209](astral-sh/uv#12209))
- Add support for `--global` default version in `uv python pin` ([#12115](astral-sh/uv#12115))
- Always reinstall local source trees passed to `uv pip install` ([#12176](astral-sh/uv#12176))
- Render token claims on publish permission error ([#12135](astral-sh/uv#12135))
- Add pip-compatible `--group` flag to `uv pip install` and `uv pip compile` ([#11686](astral-sh/uv#11686))

### Preview features

- Avoid creating duplicate directory entries in built wheels ([#12206](astral-sh/uv#12206))
- Allow overriding module names for editable builds ([#12137](astral-sh/uv#12137))

### Performance

- Avoid replicating core-metadata field on `File` struct ([#12159](astral-sh/uv#12159))

### Bug fixes

- Add `src` to default cache keys ([#12062](astral-sh/uv#12062))
- Discard insufficient fork markers ([#10682](astral-sh/uv#10682))
- Ensure `python pin --global` creates parent directories if missing ([#12180](astral-sh/uv#12180))
- Fix GraalPy abi tag parsing and discovery ([#12154](astral-sh/uv#12154))
- Remove extraneous script packages in `uv sync --script` ([#12158](astral-sh/uv#12158))
- Remove redundant `activate.bat` output ([#12160](astral-sh/uv#12160))
- Avoid subsequent index hint when no versions are available on the first index ([#9332](astral-sh/uv#9332))
- Error on lockfiles with incoherent wheel versions ([#12235](astral-sh/uv#12235))

### Rust API

- Update `BaseClientBuild` to accept custom proxies ([#12232](astral-sh/uv#12232))

### Documentation

- Make testpypi index explicit in example snippet ([#12148](astral-sh/uv#12148))
- Reverse and format the archived changelogs ([#12099](astral-sh/uv#12099))
- Use consistent commas around i.e. and e.g. ([#12157](astral-sh/uv#12157))
- Fix typos in MRE docs ([#12198](astral-sh/uv#12198))
- Fix double space typo ([#12171](astral-sh/uv#12171))
sai-rekhawar pushed a commit to sai-rekhawar/cloe-nessy-py that referenced this pull request Jul 1, 2025
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [ghcr.io/astral-sh/uv](https://github.com/astral-sh/uv) | final | minor | `0.5.7` -> `0.6.10` |

---

### Release Notes

<details>
<summary>astral-sh/uv (ghcr.io/astral-sh/uv)</summary>

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

[Compare Source](astral-sh/uv@0.6.9...0.6.10)

##### Enhancements

-   Add `uv sync --check` flag ([#&#8203;12342](astral-sh/uv#12342))
-   Add support for Python version requests in `uv python list` ([#&#8203;12375](astral-sh/uv#12375))
-   Support `.env` files in `uv tool run` ([#&#8203;12386](astral-sh/uv#12386))
-   Support `python find --script` ([#&#8203;11891](astral-sh/uv#11891))

##### Preview features

-   Check all compatible torch indexes when `--torch-backend` is enabled ([#&#8203;12385](astral-sh/uv#12385))

##### Performance

-   Use a boxed slice for extras and groups ([#&#8203;12391](astral-sh/uv#12391))
-   Use small string for index name type ([#&#8203;12355](astral-sh/uv#12355))

##### Bug fixes

-   Allow virtual packages with `--no-build` ([#&#8203;12314](astral-sh/uv#12314))
-   Ignore `--find-links` entries for pinned indexes ([#&#8203;12396](astral-sh/uv#12396))
-   Omit wheels from lockfile based on `--exclude-newer` ([#&#8203;12299](astral-sh/uv#12299))
-   Retain end-of-line comment position when adding dependency ([#&#8203;12360](astral-sh/uv#12360))
-   Omit fragment when querying for wheels in Simple HTML API ([#&#8203;12384](astral-sh/uv#12384))
-   Error on missing argument in `requirements.txt` ([#&#8203;12354](astral-sh/uv#12354))
-   Support modules with different casing in build backend ([#&#8203;12240](astral-sh/uv#12240))
-   Add authentication policy support for `pip` commands ([#&#8203;12470](astral-sh/uv#12470))

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

[Compare Source](astral-sh/uv@0.6.8...0.6.9)

##### Enhancements

-   Use `keyring --mode creds` when `authenticate = "always"` ([#&#8203;12316](astral-sh/uv#12316))
-   Fail with specific error message when no password is present and `authenticate = "always"` ([#&#8203;12313](astral-sh/uv#12313))

##### Bug fixes

-   Add boolish value parser for `UV_MANAGED_PYTHON` flags ([#&#8203;12345](astral-sh/uv#12345))
-   Make deserialization non-fatal when assessing source tree revisions ([#&#8203;12319](astral-sh/uv#12319))
-   Use resolver-returned wheel over alternate c...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or improvement to existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Get path to virtual environment for script

4 participants