Apply lockfile marker normalization for fork markers#18116
Conversation
While dependency markers get a roundtrip through simplify/complexify (https://github.com/astral-sh/uv/blob/3223b1c39f8011a4460f2b5d56ace19e5d26e16d/crates/uv-resolver/src/lock/mod.rs#L4846-L4848), this treatment was missing for fork markers, causing errors with `--locked --refresh` on a fresh lockfile. Fixes #16839 Closes #18024
|
@BurntSushi I tagged you for expertise on simplify/complexify; I don't have a full understanding of when we do which I one (and sometimes both in normalization pass), I've basically just copied the approach from dependency markers to fork markers here. |
|
Is it not sufficient to (1) store simplified markers and (2) ensure we always compare the simplified markers here? |
…change detection Instead of normalizing fork markers via a simplify/complexify round-trip (as proposed in astral-sh#18116), store both simplified and complexified forms in a new `ForkMarkers` type. PartialEq compares the simplified forms, ensuring markers from the resolver match markers deserialized from the lockfile regardless of whether they've been through a requires-python round-trip. This follows the same pattern as `Dependency`, which stores both `simplified_marker` and `complexified_marker`. Fixes astral-sh#16839 Closes astral-sh#18024 https://claude.ai/code/session_017Wu3GxDzMrmiymfDHiXHBq
|
That'd look like main...zaniebot:claude/investigate-uv-pr-H6fIZ |
I don't follow, isn't that what this PR does? |
BurntSushi
left a comment
There was a problem hiding this comment.
I think this LGTM in the sense that it does match what we do elsewhere.
| .iter() | ||
| .map(|marker| { | ||
| let simplified = SimplifiedMarkerTree::new(&requires_python, marker.combined()); | ||
| UniversalMarker::from_combined(simplified.into_marker(&requires_python)) |
There was a problem hiding this comment.
I think what confuses me is that deserializing a lock file is already doing this step?
uv/crates/uv-resolver/src/lock/mod.rs
Lines 2279 to 2284 in 7ba5946
There was a problem hiding this comment.
The bug in #16839 is that we compare the resolver output to the deserialized output, and then see a mismatch, even if there was no change, as the one from the lockfile had a roundtrip through complexify/simplify, but the one from the resolver didn't.
| }; | ||
| // Normalize fork markers with a simplify/complexify round-trip through | ||
| // `requires-python`. This ensures markers from the resolver (which don't include | ||
| // `requires-python` bounds) match markers deserialized from the lockfile (which get |
There was a problem hiding this comment.
My understanding/memory is that "complexified" markers are what we use inside the resolver. That is, "simplified" markers are really only a thing in the context of writing a lock file whose markers are simplified given the context of a requires-python. But those simplified markers can't really be used on their own, because they lack the constraints that would otherwise be present with requires-python.
|
(Defer to Andrew's review.) |
EliteTK
left a comment
There was a problem hiding this comment.
When we discussed this on Discord it seemed to make sense and it does indeed now match the other code.
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [uv](https://github.com/astral-sh/uv) | patch | `0.10.4` → `0.10.6` | 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 (uv)</summary> ### [`v0.10.6`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0106) [Compare Source](astral-sh/uv@0.10.5...0.10.6) Released on 2026-02-24. ##### Bug fixes - Apply lockfile marker normalization for fork markers ([#​18116](astral-sh/uv#18116)) - Fix Python version selection for scripts with a `requires-python` conflicting with `.python-version` ([#​18097](astral-sh/uv#18097)) - Preserve file permissions when using reflinks on Linux ([#​18187](astral-sh/uv#18187)) ##### Documentation - Remove verbose documentation from optional dependencies help text ([#​18180](astral-sh/uv#18180)) ### [`v0.10.5`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0105) [Compare Source](astral-sh/uv@0.10.4...0.10.5) Released on 2026-02-23. ##### Enhancements - Add hint when named index is found in a parent config file ([#​18087](astral-sh/uv#18087)) - Add warning for `uv lock --frozen` ([#​17859](astral-sh/uv#17859)) - Attempt to use reflinks by default on Linux ([#​18117](astral-sh/uv#18117)) - Fallback to hardlinks after reflink failure before copying ([#​18104](astral-sh/uv#18104)) - Filter `pylock.toml` wheels by tags and `requires-python` ([#​18081](astral-sh/uv#18081)) - Validate wheel filenames are normalized during `uv publish` ([#​17783](astral-sh/uv#17783)) - Fix message when `exclude-newer` invalidates the lock file ([#​18100](astral-sh/uv#18100)) - Change the missing files log level to debug ([#​18075](astral-sh/uv#18075)) ##### Performance - Improve performance of repeated conflicts with an extra ([#​18094](astral-sh/uv#18094)) ##### Bug fixes - Fix `--no-emit-workspace` with `--all-packages` on single-member workspaces ([#​18098](astral-sh/uv#18098)) - Fix `UV_NO_DEFAULT_GROUPS` rejecting truthy values like `1` ([#​18057](astral-sh/uv#18057)) - Fix iOS detection ([#​17973](astral-sh/uv#17973)) - Propagate project-level conflicts to package extras ([#​18096](astral-sh/uv#18096)) - Use a global build concurrency semaphore ([#​18054](astral-sh/uv#18054)) ##### Documentation - Update documentation heading for environment variable files ([#​18122](astral-sh/uv#18122)) - Fix comment about `uv export` formats ([#​17900](astral-sh/uv#17900)) - Make it clear that Windows is supported in user- and system- level configuration docs ([#​18106](astral-sh/uv#18106)) </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:eyJjcmVhdGVkSW5WZXIiOiI0My4zMS4xIiwidXBkYXRlZEluVmVyIjoiNDMuMzEuOSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6OnBhdGNoIl19-->
While dependency markers get a roundtrip through simplify/complexify (crates/uv-resolver/src/lock/mod.rs#L4846-L4848, #15994), this treatment was missing for fork markers, causing errors with
--locked --refreshon a fresh lockfile.Fixes #16839
Closes #18024