Skip to content

Release 0.12.0#20355

Draft
zanieb wants to merge 9 commits into
mainfrom
release/0.12.0
Draft

Release 0.12.0#20355
zanieb wants to merge 9 commits into
mainfrom
release/0.12.0

Conversation

@astral-sh-bot

astral-sh-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

uv test inventory changes

This PR changes the tests when compared with the main base revision.

  • Added tests: 46
  • Removed tests: 1
  • Changed suites: 6
uv::lock: +4 / -0

Added:

  • uv::lock::lock::lock_explicit_prerelease_mode
  • uv::lock::lock::lock_upgrade_group_frozen
  • uv::lock::lock::lock_upgrade_group_legacy_dev_dependencies
  • uv::lock::lock::lock_upgrade_group_missing

Removed: none

uv::lock_scenarios: +5 / -0

Added:

  • uv::lock_scenarios::lock_scenarios::prerelease_base_marker_stable_preference_explicit_first
  • uv::lock_scenarios::lock_scenarios::prerelease_base_marker_stable_preference_plain_first
  • uv::lock_scenarios::lock_scenarios::prerelease_marker_equivalent_stable_preference
  • uv::lock_scenarios::lock_scenarios::prerelease_marker_stable_preference_backtracks
  • uv::lock_scenarios::lock_scenarios::transitive_prerelease_forks

Removed: none

uv::pip: +23 / -0

Added:

  • uv::pip::pip_install_scenarios::package_stable_prerelease_candidates
  • uv::pip::pip_install_scenarios::prerelease_base_extra_stable_preference_after_backtrack
  • uv::pip::pip_install_scenarios::prerelease_base_extra_stable_preference_explicit_first
  • uv::pip::pip_install_scenarios::prerelease_base_extra_stable_preference_plain_first
  • uv::pip::pip_install_scenarios::prerelease_capped_union_alternate_parent
  • uv::pip::pip_install_scenarios::prerelease_capped_union_backtrack
  • uv::pip::pip_install_scenarios::prerelease_equivalent_stable_preference_explicit_first
  • uv::pip::pip_install_scenarios::prerelease_equivalent_stable_preference_plain_first
  • uv::pip::pip_install_scenarios::prerelease_extra_stable_preference
  • uv::pip::pip_install_scenarios::prerelease_extra_stable_preference_backtracks
  • uv::pip::pip_install_scenarios::prerelease_fallback_after_stable_rejected
  • uv::pip::pip_install_scenarios::prerelease_multiple_redundant_stable_preference
  • uv::pip::pip_install_scenarios::prerelease_multiple_redundant_stable_preference_explicit_first
  • uv::pip::pip_install_scenarios::prerelease_redundant_stable_preference_explicit_first
  • uv::pip::pip_install_scenarios::prerelease_redundant_stable_preference_plain_first
  • uv::pip::pip_install_scenarios::transitive_prerelease_after_decision
  • uv::pip::pip_install_scenarios::transitive_prerelease_backtracks
  • uv::pip::pip_install_scenarios::transitive_prerelease_equivalent_stable_preference_explicit_first
  • uv::pip::pip_install_scenarios::transitive_prerelease_equivalent_stable_preference_plain_first
  • uv::pip::pip_install_scenarios::transitive_prerelease_prefers_stable
  • uv::pip::pip_install_scenarios::transitive_prerelease_redundant_stable_preference_parent_first
  • uv::pip::pip_install_scenarios::transitive_prerelease_redundant_stable_preference_plain_first
  • uv::pip::pip_sync::require_hashes_in_requirements_txt

Removed: none

uv::pip_compile: +4 / -0

Added:

  • uv::pip_compile::pip_compile::compile_lowest_prereleases
  • uv::pip_compile::pip_compile::inactive_scoped_override_does_not_enable_prerelease
  • uv::pip_compile::pip_compile::offline_registry_prerelease
  • uv::pip_compile::pip_compile::unsafe_package_no_annotate

Removed: none

uv::pip_install: +9 / -1

Added:

  • uv::pip_install::pip_install::build_transitive_prerelease
  • uv::pip_install::pip_install::disallow_transitive_prerelease
  • uv::pip_install::pip_install::explicit_prerelease_allows_direct_marker
  • uv::pip_install::pip_install::explicit_prerelease_disallows_transitive_marker
  • uv::pip_install::pip_install::explicit_prerelease_does_not_fall_back_if_necessary
  • uv::pip_install::pip_install::explicit_prerelease_prefers_stable_for_direct_marker
  • uv::pip_install::pip_install::if_necessary_or_explicit_is_deprecated_alias
  • uv::pip_install::pip_install::install_require_hashes_in_requirements_txt
  • uv::pip_install::pip_install::prerelease_index_strategy_ordering

Removed:

  • uv::pip_install::pip_install::build_prerelease_hint
uv::project: +1 / -0

Added:

  • uv::project::edit::add_relative_and_absolute_archives

Removed: none

@codspeed-hq

codspeed-hq Bot commented Jul 14, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 6.14%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 20 untouched benchmarks
⏩ 6 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation resolve_warm_jupyter_universal 118.3 ms 126 ms -6.14%

Tip

Investigate this regression with the CodSpeed MCP and your agent.


Comparing release/0.12.0 (2a1da9b) with main (deada69)

Open in CodSpeed

Footnotes

  1. 6 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

zanieb added a commit that referenced this pull request Jul 14, 2026
Revert #20402. Older uv versions could emit `pylock.toml` files without
the required `packages` array; #20145 only recently corrected that
emission. Rejecting those existing files in a non-breaking release would
make previously generated lockfiles unusable.

#20402 has been moved to #20355 as
ace867f

Co-authored-by: Zanie Blue <contact@zanie.dev>
@konstin konstin added this to the v0.12.0 milestone Jul 21, 2026
Comment thread crates/uv-requirements-txt/src/lib.rs
Comment on lines +819 to +820
} else if s.eat_if("--require-hashes") {
RequirementsTxtStatement::RequireHashes

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Propagate hash policy from nested constraint files

This newly accepts --require-hashes, but the -c include path discards the child file's require_hashes value while -r propagates it. A focused parser test confirmed nested constraints return false, leaving pip install and pip sync in Verify mode and allowing publisher-controlled artifacts without the operator-required hash. OR sub_constraints.require_hashes into the parent before consuming its entries.

zanieb and others added 7 commits July 24, 2026 14:54
Prior to this change, we needed to know upfront whether a given package
was "allowed" to use a pre-release -- either by way of being a
first-party dependency with a pre-release marker on it (e.g., `flask >=
2.0.0a0`), or by _only_ having pre-releases available on PyPI at all, or
by the user _always_ allowing pre-releases via configuration. By
default, if transitive metadata later introduced a requirement like
`foo>=2.0.0b1`, that requirement did _not_ enable pre-releases for
`foo`, even though it should've (per the spec).

This PR adds support for actual transitive pre-release requirements: we
prefer stable candidates that satisfy the current range, then consider
pre-releases when those candidates are exhausted. An explicit
pre-release requirement discovered during resolution is represented by a
PubGrub proxy package.

For completeness, I also prototyped a
[nab](https://github.com/notatallshaw/nab)-style solution in #19998.
That design encoded stable- and pre-release-enabled variants directly in
PubGrub. It's arguably semantically nicer, but it was much more invasive
and caused more significant CodSpeed regressions on large graphs. I
ultimately decided that this solution is better for now, given that it's
both simpler and closer to how we model versions today.

This smaller, proxy-package solution does get at least one case wrong.
If a selected stable version of package A satisfies requirements, and we
then find a package that depends on A with a pre-release, PubGrub may
retain that version instead of "upgrading" it to a newer pre-release.
The net effect is that we may accept an older stable release rather than
upgrading to a newer pre-release if we see a pre-release requirement
later on in a solve. I think this is an acceptable limitation as
compared to the number of issues we'll be able to close here. And nab
suffers from some similar issues (as per
#19993 (comment)).

Finally, the former `--prerelease=explicit` policy has been deprecated.
`explicit` is the only mode we can't support here, because it requires
adding pre-release candidates after resolution has already begun. The
behavior is preserved, but unlike the other modes, it doesn't support
transitive pre-releases (i.e., it's ~unchanged vs. main). Personally, I
don't think that `explicit` vs. `if-necessary-or-explicit` is really an
important distinction.

Related: #3602.
Related: #14851.

Closes #19593.
Closes #2685.
Closes #11483.
Closes #19324.
Closes #12589.
Closes #9395.
Closes #16494.
Closes #16893.
## Summary

Right now, we log a warning but proceed, which means we're effectively
ignoring the `--require-hashes` directive (if you're not careful to
watch for warnings).

This can be considered breaking because workflows that previously passed
may now fail.

Co-authored-by: Codex <noreply@openai.com>
The target must match to an existent group.

Closes #18939.
## Summary

- suppress the excluded-package footer when `uv pip compile
--no-annotate` is used
- keep the existing footer behavior when annotations are enabled
- add coverage for `--unsafe-package` combined with `--no-annotate`

Closes #19948.

Co-authored-by: wzp <wangzupeng12061@gmail.com>
## Summary

Follow-up to #18176. This fixes the remaining absolute/relative path
issues when `uv add` edits `pyproject.toml`.

`uv add` now preserves the user's path form:

- Relative paths remain relative.
- Absolute paths and literal `file://` URLs remain absolute.
- URLs containing expanded variables remain relative, preserving the
portability behavior from #18680 for both named and unnamed
requirements.

This applies to local directories and local archives.

* Closes #17307
* Closes #17316

## Test Plan

- Integration coverage for relative paths, absolute paths, and literal
`file://` URLs.
- Integration coverage for directory and archive sources.
- Regression coverage for expanded-variable URLs.
- `cargo nextest run -E 'test(add_relative_and_absolute_paths) or
test(add_relative_and_absolute_archives) or
test(lock_pep508_urls_with_vars)'`
- `cargo nextest run -p uv-pep508 -p uv-pypi-types`
- `cargo clippy --workspace --all-targets --all-features --locked -- -D
warnings`
- `cargo xwin clippy --workspace --all-targets --all-features --locked
-- -D warnings`
## Summary

> Note: Not sure if this is bug or enhancement. Someone help.

While perusing the code I noticed this confusing TODO about `uv python
install --reinstall`.

In #11072 we changed `uv python install --reinstall` to reinstall all
existing Python installations except when a specific minor version was
passed, in which case we would instead install the latest available
patch. This was justified due to having no `--upgrade` at the time.

Then in #16676 we introduced `uv python install --upgrade` but we didn't
change the `--reinstall` behaviour. So we now had two ways to do this
one thing, but no way to re-install only specific versions.

This PR completes the deferred change to `--reinstall`. That's the first
commit. The second commit restores the behaviour of `--reinstall
--upgrade`, which install or reinstalls the latest patch only, not sure
if this is a desirable combo, but it _did_ work in the past and I didn't
know if it should break too. Without the special case `--reinstall`
takes precedence and `--upgrade` is ignored.

This change seems breaking. It's currently just dropped right in (maybe
0.12.0?) but I'm also open to putting it behind a preview flag and
adding some warnings.

## Test Plan

Test adjustments, to match/test the new behaviours.
## Summary

~~WIP.~~

This removes the bzip2/lzma/xz features from our backing ZIP
dependencies, per our long term plans to not support these compression
schemes (as they're not standard parts of Python packaging). ~~This
doesn't remove the similar paths from tarball handling, yet.~~

This is a breaking change, so it probably shouldn't be merged until
we're ready to cut 0.12.

See #16911 for context.

## Test Plan

Will update the snapshot tests.

---------

Signed-off-by: William Woodruff <william@yossarian.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants