## Summary
Fixes#17814.
When a Python version installed by uv spawns another Python version via
subprocess (e.g., Python 3.12 spawning Python 3.13), the child process
would inherit the parent's `PYTHONHOME` environment variable. This
caused the child Python to load the wrong stdlib, resulting in errors
like `AssertionError: SRE module mismatch`.
The fix removes the check that prevented overwriting an inherited
`PYTHONHOME` value. Now the Windows trampoline always sets `PYTHONHOME`
to the correct directory for non-virtualenv Python installations,
ensuring each Python version uses its own stdlib.
## Test Plan
Tested manually using the reproduction script from the issue:
```
uv python install 3.12
uv python install 3.13
echo "from os import environ;print(environ['PYTHONHOME']);import re" > test.py
python3.12.exe -c "import subprocess; subprocess.run(['python3.13.exe', 'test.py'])"
```
Before: `AssertionError: SRE module mismatch`
After: Runs successfully with correct `PYTHONHOME` pointing to 3.13's
installation.
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
We return these from pyx and recently added generic handling (which I
refactor a little here)
I think they could be a bit friendlier in general, but we can futz with
that globally separately.
This is a bit of a nit, but we log three request timeouts in a row
without any clarity about what is different about them, e.g.
```
❯ uv publish wheels/* -v
...
DEBUG Using request timeout of 900s
DEBUG Using request timeout of 30s
DEBUG Using request timeout of 900s
```
This adds an identifier to each one
Under the `special-conda-env-names` preview feature, instead, just using
our path-based logic.
---------
Co-authored-by: Claude <noreply@anthropic.com>
This is a bug that was found by fuzzing with Claude
> The `==X.Y.*` and `!=X.Y.*` operators use `zip` to compare version
> components, but `zip` stops at the shorter iterator. This caused
> short versions to incorrectly match longer prefix specifiers.
>
> For example, version "2" (which is semantically "2.0") would
> incorrectly match "==2.1.*" because the `zip` would only compare
> the first component (2 == 2) and never check the second component.
>
> The fix pads the version with zeros when it's shorter than the
> specifier prefix, matching PEP 440's normalization semantics where
> trailing zeros are implied.
Co-authored-by: Claude <noreply@anthropic.com>
Adds support for wheel-tag-style platform name aliases (with
architecture as a suffix) for all manylinux targets in the
`TargetTriple` enum. For example, `manylinux2014_x86_64` and
`manylinux_2_17_aarch64` are now accepted as aliases alongside the
canonical names like `x86_64-manylinux2014` and
`aarch64-manylinux_2_17`.
I noticed that you can't request these in the format in which they're
displayed as wheel tags which we'll show during a resolution error. I
foolishly just tried to copy and paste from our hint and was surprised
it failed.
---------
Co-authored-by: Claude <noreply@anthropic.com>
The `with_real_home()` method sets `HOME` to the real home directory,
which is required for tests that use the macOS keychain for
authentication. However, this causes a problem: when `HOME` is set but
`XDG_CONFIG_HOME` is not, uv resolves the config directory to
`$HOME/.config/uv` per the XDG specification. This means tests would
read the user's real configuration files (like `.python-version` or
`uv.toml`), which can override test-specified settings and cause
failures.
This PR sets `XDG_CONFIG_HOME` to the test's isolated config directory
in `with_real_home()`, ensuring that even when the real HOME is needed
for keychain access, configuration files are read from an isolated
location.
## Test plan
- Existing tests pass
- Tests using `with_real_home()` no longer read user config files
## Summary
This adds Pyodide interpreter support in windows environment. In Pyodide
0.29.2, we made some enhancements to run Pyodide CLI in windows. This PR
relaxes a check that was disabling `uv pip` in Windows + Pyodide and
adds integration test.
## Test Plan
Added integration test, also tested locally by running
```
uv python install cpython-3.13.2-emscripten-wasm32-musl
uv venv venv-pyodide -p cpython-3.13.2-emscripten-wasm32-musl
call venv-pyodide\Scripts\activate
uv pip install packaging
python -c "import packaging"
```
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [http](https://redirect.github.com/hyperium/http) |
workspace.dependencies | minor | `1.3.1` → `1.4.0` |
---
### Release Notes
<details>
<summary>hyperium/http (http)</summary>
###
[`v1.4.0`](https://redirect.github.com/hyperium/http/blob/HEAD/CHANGELOG.md#140-November-24-2025)
[Compare
Source](https://redirect.github.com/hyperium/http/compare/v1.3.1...v1.4.0)
- Add `StatusCode::EARLY_HINTS` constant for 103 Early Hints.
- Make `StatusCode::from_u16` now a `const fn`.
- Make `Authority::from_static` now a `const fn`.
- Make `PathAndQuery::from_static` now a `const fn`.
- MSRV increased to 1.57 (allows legible const fn panic messages).
</details>
---
### Configuration
📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM, only on
Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule
defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/astral-sh/uv).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi43NC41IiwidXBkYXRlZEluVmVyIjoiNDIuOTIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1yZWxlYXNlIiwiaW50ZXJuYWwiXX0=-->
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tomasz (Tom) Kramkowski <tom@astral.sh>
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [thiserror](https://redirect.github.com/dtolnay/thiserror) |
workspace.dependencies | patch | `2.0.17` → `2.0.18` |
---
### Release Notes
<details>
<summary>dtolnay/thiserror (thiserror)</summary>
###
[`v2.0.18`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.18)
[Compare
Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.17...2.0.18)
- Make compatible with project-level `needless_lifetimes = "forbid"`
([#​443](https://redirect.github.com/dtolnay/thiserror/issues/443),
thanks
[@​LucaCappelletti94](https://redirect.github.com/LucaCappelletti94))
</details>
---
### Configuration
📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM, only on
Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule
defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/astral-sh/uv).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi45Mi4xIiwidXBkYXRlZEluVmVyIjoiNDIuOTIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1yZWxlYXNlIiwiaW50ZXJuYWwiXX0=-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## Summary
This PR replaces `bitflags` in favour of `enumflags2` (which we already
transitively depended on) so that `PreviewFeatures` can be replaced with
`PreviewFeature` which is an enum. This clarifies intent in cases where
we only care about one specific `PreviewFeature`.
To avoid a bunch of boilerplate changes, the `Preview` wrapper has been
kept and creation now involves a `&[PreviewFeature]` in all cases. The
alternative was to have everything which initialises a `Preview` use
`BitFlags` directly and possibly to remove `Preview` entirely but this
keeps things simpler and limits the changes throughout the rest of the
codebase solely to changes which deal with the name changes (ALL_CAPS to
PascalCase) and the impact on `--show-settings` which I don't believe we
care about stability of output for?
The changes to `--show-settings` could be avoided with some custom
`Debug` implementation but that seems excessive.
This PR will impact #16452. But the changes were inspired by trying to
remove the need for that particular PR to add more runtime type
checking.
## Test Plan
Existing tests were adjusted (I also fixed some missing cases). The test
for panicking in cases which are now prevented through the use of type
changes has been dropped. All the rest of the tests were ran, snapshot
changes reviewed and applied.
In the previous iteration, conflict detection was based on top level
modules. This would work if all namespace packages correctly omitted the
`__init__.py`, but e.g. the nvidia packages include an empty
`nvida/__init__.py`.
Instead, we track overlapping top level modules during installation and
perform conflict analysis after installation, recursing only as far as
necessary.
See https://github.com/astral-sh/uv/pull/13437 for a list of reported
conflicts.
Before:
```
$ uv venv -c -q && uv pip install --preview nvidia-nvjitlink-cu12==12.8.93 nvidia-nvtx-cu12==12.8.90
Resolved 2 packages in 0.99ms
░░░░░░░░░░░░░░░░░░░░ [0/2] Installing wheels... warning: The module `nvidia` is provided by more than one package, which causes an install race condition and can result in a broken module. Consider removing your dependency on either `nvidia-nvtx-cu12` (v12.8.90) or `nvidia-nvjitlink-cu12` (v12.8.93).
Installed 2 packages in 3ms
+ nvidia-nvjitlink-cu12==12.8.93
+ nvidia-nvtx-cu12==12.8.90
```
After:
```
$ uv venv -c -q && cargo run -q pip install --preview nvidia-nvjitlink-cu12==12.8.93 nvidia-nvtx-cu12==12.8.90
Resolved 2 packages in 3ms
Installed 2 packages in 4ms
+ nvidia-nvjitlink-cu12==12.8.93
+ nvidia-nvtx-cu12==12.8.90
```
Still detected true positive:
```
$ uv venv -c -q && cargo run -q pip install --no-progress opencv-python opencv-contrib-python --no-build --no-deps --preview
Resolved 2 packages in 5ms
warning: The file `cv2/__init__.pyi` is provided by more than one package, which causes an install race condition and can result in a broken module. Packages containing the file:
* opencv-contrib-python (opencv_contrib_python-4.13.0.90-cp37-abi3-manylinux_2_28_x86_64.whl)
* opencv-python (opencv_python-4.13.0.90-cp37-abi3-manylinux_2_28_x86_64.whl)
Installed 2 packages in 6ms
+ opencv-contrib-python==4.13.0.90
+ opencv-python==4.13.0.90
```
Improve test consistency a bit, with an eye towards environment variable
usage.
Notably, use `TestContext::pip_uninstall` and `TestContext::pip_tree`
over `Command::new`.