Applies a patch to use Python 3.6 compatible types in our vendored
`packaging` implementation used in the interpreter query script. Adds
Python 3.6 and 3.7 test coverage in CI.
## Summary
We need to normalize any relative managed-Python install roots before
checking whether the active environment’s interpreter is uv-managed, so
that `sync --active` reuses the environment.
Closes https://github.com/astral-sh/uv/issues/16631.
## Summary
I was [working on addressing feedback and some issues I spotted in the
centralised environments
PR](https://www.youtube.com/watch?v=5W4NFcamRhM) and I noticed that this
wrapper type was unnecessary to achieve the desired result.
## Test Plan
Existing tests.
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:
- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->
## Summary
<!-- What's the purpose of the change? What does it do, and why? -->
bug fix, in find version 3.1 should not match 3.10
## Test Plan
<!-- How was it tested? -->
---------
Co-authored-by: konstin <konstin@mailbox.org>
Co-authored-by: Zanie Blue <contact@zanie.dev>
Update available python versions to include CPython 3.15.0a6
Update scripts used to sync pbs releases to account for recent changes
in the repo and to support running on macOS.
## Summary
This adds warnings to both our steam and sync ZIP handling on ZIP
entries that aren't "well-known." For now, "well-known" means stored
(i.e. no compression), DEFLATE, or zstd.
In practice we have duplicated codepaths for this check: one for the
"sync" (pre-downloaded) path, and one for the streaming path.
See #16911 and #17467 for context.
## Test Plan
Will update snapshots if/when they change. I'll also add a ZIP test for
this.
(Upd: added some "futzed" wheels for the ZIP tests.)
---------
Signed-off-by: William Woodruff <william@astral.sh>
Includes a few things...
- Drops preview warnings for use of `uv python upgrade` and `uv python
install --upgrade`
- Adds `--resolve-links` to `uv python find`, which I needed in test
cases to retain existing snapshots
- Fixes issues in our "Using environment ..." messages on Windows which
were incorrect
- Refactors `from_executable` for the `PythonMinorVersionLink` type
(https://github.com/astral-sh/uv/pull/17842/commits/28b2ed2525327d94fdf5372a29bbbc476d74680f)
to use the type system to prevent incorrect construction (for above)
- Removes special casing where we only upgrade links if they already
exist, which existed so preview wasn't needed on every invocation
- Fixes a bug with `PythonMinorVersionLink::exists` which returned
`true` even if the link pointed to the wrong Python installation leading
to discovery failures
Closes#12921
For `uv tool run`, we'll just use the global Python version for all
invocations without an explicit alternative request (i.e., via the
`--python` flag).
For `uv tool install`, it's a bit more complicated:
- If the tool is not installed, we'll use the global Python version
- If the tool is already installed, we won't change the Python version
unless `--reinstall` or `--python` is used
- If the tool was installed with `--python`, we won't use the global
Python version, unless the tool is uninstalled first
The behavior can be demonstrated as follows
```
$ uv python pin --global 3.12
$ uv tool install flask # uses 3.12
$ uv tool install flask # no-op
$ uv python pin --global 3.13
$ uv tool install flask # no-op
$ uv tool install flask --reinstall # uses 3.13
$ uv tool install flask -p 3.12 # uses 3.12
$ uv tool install flask # no-op
$ uv tool install flask --reinstall # uses 3.12
```
This is a little more complicated than always reinstalling when the
global Python version pin changes, but I think it's probably more
intuitive when actually using the tool. We briefly touched on this when
adding global version pins at
https://github.com/astral-sh/uv/pull/12115#discussion_r1992222278
Minor note: I need to do a self-review of this implementation, as it's a
little awkward to encode this behavior in the existing logic.
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:
- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->
## Summary
@zanieb in #14916 found an interesting bug. Global pin is the user
preference across projects, but if the project locally has a local pin,
it should be an authoritative constraint and end up with error. This
avoids blocking new projects that intentionally require a newer Python
version than the user’s global default. We still error on a local
`.python-version` inside the project to preserve explicit, repo-scoped
intent.
* Explicit `--python` → Always wins regardless of constraints
* Local `.python-version` → Project-scoped, errors on conflict
* Global `.python-version` → User preference, ignored if conflicts with
project. Global pins are suggestions that can be overridden by project
requirements
* Project `requires-python` → Fallback when no pins exist
Implementation :
* If a global `~/.config/uv/.python-version` conflicts with a project
`requires-python`, we ignore the pin and use the project requirement
* If a local project `.python-version` conflicts, we error, with
guidance to update the pin
* Explicit `--python` continues to override both
Now, global pins are suggestions that can be overridden by project
requirements, rather than hard constraints that block project setup.
## Test Plan
A new has been added in `sync_python_version()` along with manual
testing :
```
harshps22ugp@lab:~/projects/uv$ target/debug/uv python pin --global 3.10
Pinned `/home/harshps22ugp/.config/uv/.python-version` to `3.10`
harshps22ugp@lab:~/projects/uv$ mkdir -p /tmp/uv-global-pin && cd /tmp/uv-global-pin
harshps22ugp@lab:/tmp/uv-global-pin$ cat > pyproject.toml <<'EOF'
> [project]
> name = "project"
> version = "0.1.0"
> requires-python = ">=3.11"
> dependencies = ["anyio==3.7.0"]
> EOF
harshps22ugp@lab:/tmp/uv-global-pin$ /home/harshps22ugp/projects/uv/target/debug/uv sync
Using CPython 3.13.5
Creating virtual environment at: .venv
Resolved 4 packages in 276ms
Prepared 3 packages in 149ms
░░░░░░░░░░░░░░░░░░░░ [0/3] Installing wheels... warning: Failed to hardlink files; falling back to full copy. This may lead to degraded performance.
If the cache and target directories are on different filesystems, hardlinking may not be supported.
If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.
Installed 3 packages in 35ms
+ anyio==3.7.0
+ idna==3.10
+ sniffio==1.3.1
harshps22ugp@lab:/tmp/uv-global-pin$ . .venv/bin/activate
(project) harshps22ugp@lab:/tmp/uv-global-pin$ python -V
Python 3.13.5
(project) harshps22ugp@lab:/tmp/uv-global-pin$
```
No error was thrown!
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>