Skip to content

[pull] main from astral-sh:main - #277

Merged
pull[bot] merged 10 commits into
Moshbbab:mainfrom
astral-sh:main
Sep 30, 2026
Merged

pull[bot] merged 10 commits into
Moshbbab:mainfrom
astral-sh:main

Conversation

@pull

@pull pull Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

## Summary

Record workspace members' default dependency groups in `uv.lock`, so
frozen commands can select them without reading member manifests in the
future:

```toml
[manifest.default-groups]
member = ["docs"]
```

(We omit the implicit `["dev"]` default.)

As part of this change, I've bumped to revision 5. This effectively
removes the behavior where if revision 4 is set, we "retain"
metadata-free locks; I think it's fine to require that the relevant flag
is set in those cases?
## Summary

Record dependency group metadata for workspace members in `uv.lock`, so
frozen commands can select a compatible Python interpreter without
reading member manifests:

```toml
[manifest.group-metadata]
member = { docs = { requires-python = ">=3.13" } }
```

The recorded Python requirement includes bounds inherited through
`include-group`. Groups without metadata are omitted, and changing a
recorded requirement makes the lockfile stale. Member default groups are
recorded separately in `[manifest.default-groups]`.

The group metadata is recorded in lockfile revision 5 alongside member
defaults. Older lockfiles remain valid without a group metadata
freshness check. Requirements for non-project workspace roots are not
yet recorded.
## Summary

`uv sync --package member` uses the selected member's default dependency
groups, but adding `--frozen` makes us use the defaults of the project
we're running from instead.

For example, when run from a workspace root whose defaults are
`["dev"]`, we select `dev` even if the requested member's defaults are
`["docs"]`. The same package selection can therefore install different
dependencies depending on whether you pass `--frozen`.

For revision 5 and later lockfiles, frozen sync uses the selected
member's recorded default groups and group Python requirements,
including when the member's manifest is missing.
We now update the HTTP cache policy in place on a 304 response, avoiding
a rewrite of the cached payload. The format change bumps the six cache
buckets containing HTTP responses.

Warm-cache benchmarks on Linux/ext4, with 96 entries and 16 concurrent
requests per batch (`c9dab42be` → `1562e401b`, using SeaHash):

| Warm-cache workload | Main | PR | Paired change |
|---|---:|---:|---:|
| 304 refresh, 256 KiB | 80.39 ms | 9.84 ms | 87.4% faster |
| 304 refresh, 1 MiB | 323.20 ms | 17.59 ms | 94.6% faster |
| Fresh reads, 4 KiB | 0.711 ms | 0.712 ms | Approximately unchanged |
| Fresh reads, 256 KiB | 2.140 ms | 2.112 ms | 2.9% faster |
| Fresh reads, 1 MiB | 7.529 ms | 7.698 ms | No clear difference |
We store source-distribution revision IDs as `uv_fastid::Id`, avoiding
the `String` allocation when creating or cloning them. IDs still
serialize as strings.

The `sdists-v10` bump allows us to reject legacy 21-character IDs.
We serialize `HashDigest` directly with Serde and rkyv, removing the
legacy `HashDigestWire` adapter. Archived digests validate their length
and hexadecimal characters through `Digest<BYTES>` and normalize to
lowercase on deserialization.

The cache bumps cover the source-distribution, wheel, simple-index, and
flat-index buckets that contain these hashes. Lockfile and index hash
formats are unchanged.
We derive `Serialize` for `Revision` and `Archive`, writing MessagePack
arrays instead of maps. This removes the custom serializers and saves 15
bytes per source revision and 32 bytes per wheel archive record.

The `sdists-v10` and `wheels-v7` bumps remove the need to support older
readers that cannot accept the added `size` field.
We use `WheelFilename::cache_key()` for Windows wheel download,
extraction, and metadata locks, limiting lock filenames to 69
characters, including `.lock`. This covers both PEP 658 metadata
requests and the range-request fallback.

The `wheels-v7` and `sdists-v10` bumps remove the need to share lock
filenames with older uv versions.
We store the same HTTP cache information in fewer bytes, without
changing cache freshness or revalidation behavior.

- **Booleans become bits.** Ten fields like `no_cache`, `no_store`, and
`immutable` each occupied a byte. We pack them into bits of one integer.
- **Optional numbers share their presence flags.** Each archived
`Option<u64>` occupies 16 bytes: the number, an indicator of whether it
exists, and alignment padding. We store the numbers together and use one
bit per number to indicate whether it exists.

For example, `max_age = None` and `max_age = Some(0)` both store the
number `0`, but their presence bits differ. Getters reconstruct the
normal `Option<u64>`.

We apply this to cache-control directives and response timestamps. The
fixed archived policy shrinks from **320 to 200 bytes**. We use
`bitflags` for typed flag operations and retain endian-aware integers in
the archived representation.

The cache bucket bumps cover the new representation.
We align HTTP cache policies within the payload buffer and access them
directly after validation, removing a separate allocation and copy from
every cache read. Extracting the payload reuses the same allocation.

The file adds up to 15 bytes of padding, covered by the CRC32. Policy
validation is restricted to its own slice, and refreshes retain the
entry ID check before overwriting the policy.
@pull pull Bot locked and limited conversation to collaborators Sep 30, 2026
@pull pull Bot added the ⤵️ pull label Sep 30, 2026
@pull
pull Bot merged commit 06fdf0c into Moshbbab:main Sep 30, 2026
1 check failed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant