From 4d6ca8dc9f2819174d069eafc078873e84e81fdd Mon Sep 17 00:00:00 2001 From: Oshadha Gunawardena Date: Mon, 11 May 2026 06:40:32 +0530 Subject: [PATCH 01/16] Fix `uv tree` showing extra-conditional deps for packages required without extras (#19332) When a package is required both as a plain dependency and as `pkg[extra]` in a group, `uv tree` can show the extra's dependencies under the plain occurrence too. This updates `TreeDisplay::visit` to only traverse optional outgoing edges when the incoming edge actually activates the matching extra, while leaving `--invert` unchanged since the edge direction is reversed there. Added `dep_and_group_extras` in `crates/uv/tests/it/tree.rs`. All existing tree tests pass. Closes #19327 --------- Co-authored-by: Charlie Marsh --- crates/uv-resolver/src/lock/tree.rs | 83 ++++++++-- crates/uv/tests/it/tree.rs | 234 ++++++++++++++++++++++++++++ 2 files changed, 302 insertions(+), 15 deletions(-) diff --git a/crates/uv-resolver/src/lock/tree.rs b/crates/uv-resolver/src/lock/tree.rs index a129be1cde1d6..cd388545cb8d3 100644 --- a/crates/uv-resolver/src/lock/tree.rs +++ b/crates/uv-resolver/src/lock/tree.rs @@ -16,7 +16,7 @@ use uv_pep440::Version; use uv_pep508::MarkerTree; use uv_pypi_types::ResolverMarkerEnvironment; -use crate::lock::PackageId; +use crate::lock::{Package, PackageId}; use crate::{Lock, PackageMap}; #[derive(Debug)] @@ -31,6 +31,8 @@ pub struct TreeDisplay<'env> { depth: usize, /// Whether to de-duplicate the displayed dependencies. no_dedupe: bool, + /// Whether the graph edges have been reversed (i.e., `--invert` mode). + invert: bool, /// Reference to the lock to look up additional metadata (e.g., wheel sizes). lock: &'env Lock, /// Whether to show sizes in the rendered output. @@ -410,6 +412,7 @@ impl<'env> TreeDisplay<'env> { latest, depth, no_dedupe, + invert, lock, show_sizes, } @@ -419,8 +422,8 @@ impl<'env> TreeDisplay<'env> { fn visit( &'env self, cursor: Cursor, - visited: &mut FxHashMap<&'env PackageId, Vec<&'env PackageId>>, - path: &mut Vec<&'env PackageId>, + visited: &mut FxHashMap, Vec<&'env PackageId>>, + path: &mut Vec>, ) -> Vec { // Short-circuit if the current path is longer than the provided depth. if path.len() > self.depth { @@ -431,6 +434,13 @@ impl<'env> TreeDisplay<'env> { return Vec::new(); }; let edge = cursor.edge().map(|edge_id| &self.graph[edge_id]); + let package = self.lock.find_by_id(package_id); + + let expanded_extras = self.expanded_extras(package, edge); + let visited_node = VisitedNode { + package_id, + expanded_extras: expanded_extras.clone(), + }; let line = { let mut line = format!("{}", package_id.name); @@ -464,7 +474,6 @@ impl<'env> TreeDisplay<'env> { // Append compressed wheel size, if available in the lockfile. // Keep it simple: use the first wheel entry that includes a size. if self.show_sizes { - let package = self.lock.find_by_id(package_id); if let Some(size_bytes) = package.wheels.iter().find_map(|wheel| wheel.size) { let (bytes, unit) = human_readable_bytes(size_bytes); line.push(' '); @@ -478,14 +487,17 @@ impl<'env> TreeDisplay<'env> { // Skip the traversal if: // 1. The package is in the current traversal path (i.e., a dependency cycle). // 2. The package has been visited and de-duplication is enabled (default). - if let Some(requirements) = visited.get(package_id) { - if !self.no_dedupe || path.contains(&package_id) { - return if requirements.is_empty() { - vec![line] - } else { - vec![format!("{line} (*)")] - }; - } + if path.contains(&visited_node) { + return vec![format!("{line} (*)")]; + } + if !self.no_dedupe + && let Some(requirements) = visited.get(&visited_node) + { + return if requirements.is_empty() { + vec![line] + } else { + vec![format!("{line} (*)")] + }; } // Incorporate the latest version of the package, if known. @@ -500,7 +512,18 @@ impl<'env> TreeDisplay<'env> { .edges_directed(cursor.node(), Direction::Outgoing) .filter_map(|edge| match self.graph[edge.target()] { Node::Root => None, - Node::Package(_) => Some(Cursor::new(edge.target(), edge.id())), + Node::Package(_) => { + // Only include extra-conditional dependencies if the activating extra is + // enabled in the current context. + if !self.invert + && let Edge::Optional(required_extra, _) = &self.graph[edge.id()] + { + if !expanded_extras.contains(required_extra) { + return None; + } + } + Some(Cursor::new(edge.target(), edge.id())) + } }) .collect::>(); dependencies.sort_by_key(|cursor| { @@ -518,7 +541,7 @@ impl<'env> TreeDisplay<'env> { // Only mark as visited if we're going to expand children (not at depth limit). if path.len() < self.depth { visited.insert( - package_id, + visited_node.clone(), dependencies .iter() .filter_map(|node| match self.graph[node.node()] { @@ -528,7 +551,7 @@ impl<'env> TreeDisplay<'env> { .collect(), ); } - path.push(package_id); + path.push(visited_node); for (index, dep) in dependencies.iter().enumerate() { // For sub-visited packages, add the prefix to make the tree display user-friendly. @@ -600,6 +623,36 @@ impl<'env> TreeDisplay<'env> { lines } + + /// Return the extras that can change this package's rendered child list. + fn expanded_extras( + &self, + package: &'env Package, + edge: Option<&Edge<'env>>, + ) -> BTreeSet<&'env ExtraName> { + if self.invert { + // In inverted mode, optional edges are reverse "required by extra" relationships. + // They do not select this package's outgoing dependencies, so de-dupe stays + // package-only. + return BTreeSet::default(); + } + + let Some(requested_extras) = edge.and_then(Edge::extras) else { + // Roots are rendered with all optional dependency groups expanded. + return package.optional_dependencies.keys().collect(); + }; + + requested_extras + .iter() + .filter(|extra| package.optional_dependencies.contains_key(*extra)) + .collect() + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +struct VisitedNode<'env> { + package_id: &'env PackageId, + expanded_extras: BTreeSet<&'env ExtraName>, } #[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd)] diff --git a/crates/uv/tests/it/tree.rs b/crates/uv/tests/it/tree.rs index d717873f0db87..0dcaf86287667 100644 --- a/crates/uv/tests/it/tree.rs +++ b/crates/uv/tests/it/tree.rs @@ -797,6 +797,240 @@ fn optional_dependencies_inverted() -> Result<()> { Ok(()) } +/// Regression test for . +/// +/// When a package is required both as a plain dep and as a dep with extras (e.g., from a +/// dependency group), `uv tree` should not display extra-conditional dependencies for the plain +/// occurrence. +#[test] +fn dep_and_group_extras() -> Result<()> { + let context = uv_test::test_context!("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["flask"] + + [dependency-groups] + dev = ["flask[dotenv]"] + "#, + )?; + + // Plain `flask` should not show `python-dotenv` (which belongs to the `dotenv` extra), + // but the `flask[dotenv]` occurrence should still be expanded in its own extra context. + uv_snapshot!(context.filters(), context.tree().arg("--universal"), @" + success: true + exit_code: 0 + ----- stdout ----- + project v0.1.0 + ├── flask v3.0.2 + │ ├── blinker v1.7.0 + │ ├── click v8.1.7 + │ │ └── colorama v0.4.6 + │ ├── itsdangerous v2.1.2 + │ ├── jinja2 v3.1.3 + │ │ └── markupsafe v2.1.5 + │ └── werkzeug v3.0.1 + │ └── markupsafe v2.1.5 + └── flask[dotenv] v3.0.2 (group: dev) + ├── blinker v1.7.0 + ├── click v8.1.7 (*) + ├── itsdangerous v2.1.2 + ├── jinja2 v3.1.3 (*) + ├── werkzeug v3.0.1 (*) + └── python-dotenv v1.0.1 (extra: dotenv) + (*) Package tree already displayed + + ----- stderr ----- + Resolved 10 packages in [TIME] + " + ); + + // With `--no-dedupe`, `flask[dotenv]` is expanded and shows `python-dotenv` as an extra dep, + // while plain `flask` still does not show it. + uv_snapshot!(context.filters(), context.tree().arg("--universal").arg("--no-dedupe"), @" + success: true + exit_code: 0 + ----- stdout ----- + project v0.1.0 + ├── flask v3.0.2 + │ ├── blinker v1.7.0 + │ ├── click v8.1.7 + │ │ └── colorama v0.4.6 + │ ├── itsdangerous v2.1.2 + │ ├── jinja2 v3.1.3 + │ │ └── markupsafe v2.1.5 + │ └── werkzeug v3.0.1 + │ └── markupsafe v2.1.5 + └── flask[dotenv] v3.0.2 (group: dev) + ├── blinker v1.7.0 + ├── click v8.1.7 + │ └── colorama v0.4.6 + ├── itsdangerous v2.1.2 + ├── jinja2 v3.1.3 + │ └── markupsafe v2.1.5 + ├── werkzeug v3.0.1 + │ └── markupsafe v2.1.5 + └── python-dotenv v1.0.1 (extra: dotenv) + + ----- stderr ----- + Resolved 10 packages in [TIME] + " + ); + + Ok(()) +} + +#[test] +fn dep_and_group_extras_with_extra_only_dependency() -> Result<()> { + let context = uv_test::test_context!("3.12"); + + let leaf = context.temp_dir.child("leaf"); + fs_err::create_dir_all(leaf.path())?; + leaf.child("pyproject.toml").write_str( + r#" + [project] + name = "leaf" + version = "0.1.0" + requires-python = ">=3.12" + "#, + )?; + let leaf_url = Url::from_file_path(leaf.path()) + .map_err(|()| anyhow::anyhow!("failed to convert leaf path to URL"))?; + + let child = context.temp_dir.child("child"); + fs_err::create_dir_all(child.path())?; + child.child("pyproject.toml").write_str(&formatdoc! { + r#" + [project] + name = "child" + version = "0.1.0" + requires-python = ">=3.12" + + [project.optional-dependencies] + extra = ["leaf @ {}"] + "#, + leaf_url, + })?; + let child_url = Url::from_file_path(child.path()) + .map_err(|()| anyhow::anyhow!("failed to convert child path to URL"))?; + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str(&formatdoc! { + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["child @ {}"] + + [dependency-groups] + dev = ["child[extra] @ {}"] + "#, + child_url, + child_url, + })?; + + uv_snapshot!(context.filters(), context.tree(), @" + success: true + exit_code: 0 + ----- stdout ----- + project v0.1.0 + ├── child v0.1.0 + └── child[extra] v0.1.0 (group: dev) + └── leaf v0.1.0 (extra: extra) + + ----- stderr ----- + Resolved 3 packages in [TIME] + "); + + Ok(()) +} + +#[test] +fn dep_and_group_extras_with_different_extras_in_path() -> Result<()> { + let context = uv_test::test_context!("3.12"); + + let leaf = context.temp_dir.child("leaf"); + fs_err::create_dir_all(leaf.path())?; + leaf.child("pyproject.toml").write_str( + r#" + [project] + name = "leaf" + version = "0.1.0" + requires-python = ">=3.12" + "#, + )?; + let leaf_url = Url::from_file_path(leaf.path()) + .map_err(|()| anyhow::anyhow!("failed to convert leaf path to URL"))?; + + let a = context.temp_dir.child("a"); + fs_err::create_dir_all(a.path())?; + let b = context.temp_dir.child("b"); + fs_err::create_dir_all(b.path())?; + let b_url = Url::from_file_path(b.path()) + .map_err(|()| anyhow::anyhow!("failed to convert b path to URL"))?; + a.child("pyproject.toml").write_str(&formatdoc! { + r#" + [project] + name = "a" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["b[extra2] @ {}"] + "#, + b_url, + })?; + let a_url = Url::from_file_path(a.path()) + .map_err(|()| anyhow::anyhow!("failed to convert a path to URL"))?; + + b.child("pyproject.toml").write_str(&formatdoc! { + r#" + [project] + name = "b" + version = "0.1.0" + requires-python = ">=3.12" + + [project.optional-dependencies] + extra1 = ["a @ {}"] + extra2 = ["leaf @ {}"] + "#, + a_url, + leaf_url, + })?; + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str(&formatdoc! { + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["b[extra1] @ {}"] + "#, + b_url, + })?; + + uv_snapshot!(context.filters(), context.tree(), @" + success: true + exit_code: 0 + ----- stdout ----- + project v0.1.0 + └── b[extra1] v0.1.0 + └── a v0.1.0 (extra: extra1) + └── b[extra2] v0.1.0 + └── leaf v0.1.0 (extra: extra2) + + ----- stderr ----- + Resolved 4 packages in [TIME] + "); + + Ok(()) +} + #[test] fn package() -> Result<()> { let context = uv_test::test_context!("3.12"); From d61b337eec45edad61f2ce2f10b29b90d614d008 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 10 May 2026 19:28:08 -0700 Subject: [PATCH 02/16] Update Rust crate reqwest to v0.13.3 (#19348) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [reqwest](https://redirect.github.com/seanmonstar/reqwest) | workspace.dependencies | patch | `0.13.2` → `0.13.3` | --- ### Release Notes
seanmonstar/reqwest (reqwest) ### [`v0.13.3`](https://redirect.github.com/seanmonstar/reqwest/blob/HEAD/CHANGELOG.md#v0133) [Compare Source](https://redirect.github.com/seanmonstar/reqwest/compare/v0.13.2...v0.13.3) - Fix CertificateRevocationList parsing of PEM values. - Fix logging in resolver to only show host, not full URL. - Fix hickory-dns to fallback to a default if `/etc/resolv.conf` fails. - Fix HTTP/3 to handle `STOP_SENDING` as not an error. - Fix HTTP/3 pool to remove timed out QUIC connections. - Fix HTTP/3 connection establishment picking IPv4 and IPv6. - Upgrade rustls-platform-verifier. - (wasm) Only use wasm-bindgen on unknown-\* targets.
--- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`) - 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. --- - [ ] 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). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9fe8f4ca56f2..ddb201d6a3f69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3937,9 +3937,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" dependencies = [ "base64 0.22.1", "bytes", From a56dd749b20202c99d0c98de8a64384852acc9d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 10 May 2026 19:29:16 -0700 Subject: [PATCH 03/16] Update CodSpeedHQ/action action to v4.15.0 (#19350) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | Pending | |---|---|---|---|---| | [CodSpeedHQ/action](https://redirect.github.com/CodSpeedHQ/action) | action | minor | `v4.14.0` → `v4.15.0` | `v4.15.1` | --- ### Release Notes
CodSpeedHQ/action (CodSpeedHQ/action) ### [`v4.15.0`](https://redirect.github.com/CodSpeedHQ/action/releases/tag/v4.15.0) [Compare Source](https://redirect.github.com/CodSpeedHQ/action/compare/v4.14.0...v4.15.0) #### Release Notes This release adds first support for macOS walltime. Please note that profiling and other instruments are not yet available on macOS and will come in a later update. ##### Minimum integration versions - [`pytest-codspeed` v4.5.0](https://redirect.github.com/CodSpeedHQ/pytest-codspeed/releases/tag/v4.5.0) - [`codspeed-rust` v4.6.0](https://redirect.github.com/CodSpeedHQ/codspeed-rust/releases/tag/v4.6.0) - [`codspeed-cpp` v2.3.0](https://redirect.github.com/CodSpeedHQ/codspeed-cpp/releases/tag/v2.3.0) - [`codspeed-go` v1.2.0](https://redirect.github.com/CodSpeedHQ/codspeed-go/releases/tag/v1.2.0) - [`codspeed-node` v5.4.0](https://redirect.github.com/CodSpeedHQ/codspeed-node/releases/tag/v5.4.0) ##### 🚀 Features - Revert logo changes by [@​GuillaumeLagrange](https://redirect.github.com/GuillaumeLagrange) - Display N/A rather than NaN/inf in the benchmarks results table by [@​GuillaumeLagrange](https://redirect.github.com/GuillaumeLagrange) in [#​314](https://redirect.github.com/CodSpeedHQ/runner/pull/314) - Only wrap walltime command with sudo on linux by [@​GuillaumeLagrange](https://redirect.github.com/GuillaumeLagrange) - Add `--with-token` flag to read token from stdin by [@​fargito](https://redirect.github.com/fargito) in [#​313](https://redirect.github.com/CodSpeedHQ/runner/pull/313) - Warn when libc debug info is not found by [@​not-matthias](https://redirect.github.com/not-matthias) in [#​310](https://redirect.github.com/CodSpeedHQ/runner/pull/310) - Resolve debug info and symbols from separate debug files by [@​not-matthias](https://redirect.github.com/not-matthias) in [#​303](https://redirect.github.com/CodSpeedHQ/runner/pull/303) ##### 🧪 Testing - Add libc debuglink/build-id fixtures by [@​not-matthias](https://redirect.github.com/not-matthias) - Add stripped binary and debug file test fixtures by [@​not-matthias](https://redirect.github.com/not-matthias) ##### ⚙️ Internals - chore: bump runner version to 4.15.0 by [@​github-actions](https://redirect.github.com/github-actions)\[bot] in [#​204](https://redirect.github.com/CodSpeedHQ/action/pull/204) - Bump exec-harness version - Add macos basic run test by [@​GuillaumeLagrange](https://redirect.github.com/GuillaumeLagrange) in [#​319](https://redirect.github.com/CodSpeedHQ/runner/pull/319) - Remove DumpPerfMapAtExit in favor of custom dumper by [@​not-matthias](https://redirect.github.com/not-matthias) in [#​295](https://redirect.github.com/CodSpeedHQ/runner/pull/295) #### Install codspeed-runner 4.15.0 ##### Install prebuilt binaries via shell script ```sh curl --proto '=https' --tlsv1.2 -LsSf https://github.com/CodSpeedHQ/codspeed/releases/download/v4.15.0/codspeed-runner-installer.sh | sh ``` #### Download codspeed-runner 4.15.0 | File | Platform | Checksum | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | [codspeed-runner-aarch64-apple-darwin.tar.gz](https://redirect.github.com/CodSpeedHQ/codspeed/releases/download/v4.15.0/codspeed-runner-aarch64-apple-darwin.tar.gz) | Apple Silicon macOS | [checksum](https://redirect.github.com/CodSpeedHQ/codspeed/releases/download/v4.15.0/codspeed-runner-aarch64-apple-darwin.tar.gz.sha256) | | [codspeed-runner-aarch64-unknown-linux-musl.tar.gz](https://redirect.github.com/CodSpeedHQ/codspeed/releases/download/v4.15.0/codspeed-runner-aarch64-unknown-linux-musl.tar.gz) | ARM64 MUSL Linux | [checksum](https://redirect.github.com/CodSpeedHQ/codspeed/releases/download/v4.15.0/codspeed-runner-aarch64-unknown-linux-musl.tar.gz.sha256) | | [codspeed-runner-x86\_64-unknown-linux-musl.tar.gz](https://redirect.github.com/CodSpeedHQ/codspeed/releases/download/v4.15.0/codspeed-runner-x86_64-unknown-linux-musl.tar.gz) | x64 MUSL Linux | [checksum](https://redirect.github.com/CodSpeedHQ/codspeed/releases/download/v4.15.0/codspeed-runner-x86_64-unknown-linux-musl.tar.gz.sha256) | **Full Runner Changelog**: **Full Changelog**:
--- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`) - 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. --- - [ ] 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). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/bench.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 83f97b2b84462..3a8bcdc286192 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -88,7 +88,7 @@ jobs: run: ./target/debug/uv venv --cache-dir .cache - name: "Run benchmarks" - uses: CodSpeedHQ/action@658a901452bb54c799643e060733b7afe9121b8d # v4.14.0 + uses: CodSpeedHQ/action@c381be0bfd20e844fb45594f6aa182ffcd94545c # v4.15.0 with: run: cargo codspeed run mode: walltime @@ -129,7 +129,7 @@ jobs: run: cargo codspeed build --profile profiling -p uv-bench - name: "Run benchmarks" - uses: CodSpeedHQ/action@658a901452bb54c799643e060733b7afe9121b8d # v4.14.0 + uses: CodSpeedHQ/action@c381be0bfd20e844fb45594f6aa182ffcd94545c # v4.15.0 with: run: cargo codspeed run mode: simulation From f3185e46f28034361d6e689a31c452e59b3ea54f Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Sun, 10 May 2026 19:35:37 -0700 Subject: [PATCH 04/16] Encapsulate fastid APIs in their type (#19328) ## Summary This was purely an oversight from #19201 -- `Id::{secure,insecure}` is what I meant to do for ctors, instead of having these float on the module itself. ## Test Plan NFC, no public changes. Signed-off-by: William Woodruff --- crates/uv-cache/src/archive.rs | 2 +- crates/uv-distribution/src/source/revision.rs | 2 +- crates/uv-fastid/src/lib.rs | 56 ++++++++++--------- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/crates/uv-cache/src/archive.rs b/crates/uv-cache/src/archive.rs index 0f35bb202c107..352ae6230c83c 100644 --- a/crates/uv-cache/src/archive.rs +++ b/crates/uv-cache/src/archive.rs @@ -19,7 +19,7 @@ impl Default for ArchiveId { impl ArchiveId { /// Generate a new unique identifier for an archive. pub fn new() -> Self { - Self(uv_fastid::insecure().to_string()) + Self(uv_fastid::Id::insecure().to_string()) } } diff --git a/crates/uv-distribution/src/source/revision.rs b/crates/uv-distribution/src/source/revision.rs index c1f06db970dab..b8a4d367afdae 100644 --- a/crates/uv-distribution/src/source/revision.rs +++ b/crates/uv-distribution/src/source/revision.rs @@ -65,7 +65,7 @@ pub(crate) struct RevisionId(String); impl RevisionId { /// Generate a new unique identifier for an archive. fn new() -> Self { - Self(uv_fastid::insecure().to_string()) + Self(uv_fastid::Id::insecure().to_string()) } pub(crate) fn as_str(&self) -> &str { diff --git a/crates/uv-fastid/src/lib.rs b/crates/uv-fastid/src/lib.rs index a263e7e99671a..d352767c08caa 100644 --- a/crates/uv-fastid/src/lib.rs +++ b/crates/uv-fastid/src/lib.rs @@ -78,30 +78,32 @@ impl<'de> serde::Deserialize<'de> for Id { } } -/// Generate an [`Id`] from a cryptographically secure RNG. -/// -/// The resulting ID is suitable for use in contexts where uniqueness is needed and -/// the risk of an adversarial collision is non-negligible. -pub fn secure() -> Id { - let mut raw = [0u8; 16]; - let mut rng = rand::rng(); - rng.fill_bytes(raw.as_mut()); - Id(reduce(&raw)) -} +impl Id { + /// Generate an [`Id`] from a cryptographically secure RNG. + /// + /// The resulting ID is suitable for use in contexts where uniqueness is needed and + /// the risk of an adversarial collision is non-negligible. + pub fn secure() -> Self { + let mut raw = [0u8; 16]; + let mut rng = rand::rng(); + rng.fill_bytes(raw.as_mut()); + Self(Self::reduce(&raw)) + } -/// Generate an [`Id`] from a fast, non-cryptographically secure RNG. -/// -/// The resulting ID is suitable for use in contexts where uniqueness is needed -/// but the risk of an adversarial collision is negligible (such as local cache keys). -pub fn insecure() -> Id { - let mut raw = [0u8; 16]; - fastrand::fill(&mut raw); - Id(reduce(&raw)) -} + /// Generate an [`Id`] from a fast, non-cryptographically secure RNG. + /// + /// The resulting ID is suitable for use in contexts where uniqueness is needed + /// but the risk of an adversarial collision is negligible (such as local cache keys). + pub fn insecure() -> Self { + let mut raw = [0u8; 16]; + fastrand::fill(&mut raw); + Self(Self::reduce(&raw)) + } -/// Reduce a 16-byte array of random bytes to a 16-byte array of ASCII characters in our ID alphabet. -fn reduce(raw: &[u8; 16]) -> [u8; 16] { - raw.map(|byte| ALPHABET[(byte & MASK) as usize]) + /// Reduce a 16-byte array of random bytes to a 16-byte array of ASCII characters in our ID alphabet. + fn reduce(raw: &[u8; 16]) -> [u8; 16] { + raw.map(|byte| ALPHABET[(byte & MASK) as usize]) + } } #[cfg(test)] @@ -128,7 +130,7 @@ mod tests { "_-0123456789abcd", ), ] { - let bytes = reduce(&raw); + let bytes = Id::reduce(&raw); let actual = std::str::from_utf8(&bytes).expect("reduce produces ASCII"); assert_eq!(actual, expected, "reduce({raw:?}) should be {expected}"); } @@ -136,14 +138,14 @@ mod tests { #[test] fn test_secure() { - let id = secure(); + let id = Id::secure(); assert_eq!(id.len(), 16); assert!(id.bytes().all(|byte| ALPHABET.contains(&byte))); } #[test] fn test_insecure() { - let id = insecure(); + let id = Id::insecure(); assert_eq!(id.len(), 16); assert!(id.bytes().all(|byte| ALPHABET.contains(&byte))); } @@ -166,12 +168,12 @@ mod tests { #[test] fn round_trip() { - let id = secure(); + let id = Id::secure(); let json = serde_json::to_string(&id).unwrap(); let parsed: Id = serde_json::from_str(&json).unwrap(); assert_eq!(id, parsed); - let id = insecure(); + let id = Id::insecure(); let json = serde_json::to_string(&id).unwrap(); let parsed: Id = serde_json::from_str(&json).unwrap(); assert_eq!(id, parsed); From 248ad8a8493a0dafa7000d6af92bd3a0a2b77e5f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 02:40:44 +0000 Subject: [PATCH 05/16] Update dependency astral-sh/uv to v0.11.13 (#19354) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [astral-sh/uv](https://redirect.github.com/astral-sh/uv) | uses-with | patch | `0.11.12` → `0.11.13` | --- ### Release Notes
astral-sh/uv (astral-sh/uv) ### [`v0.11.13`](https://redirect.github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#01113) [Compare Source](https://redirect.github.com/astral-sh/uv/compare/0.11.12...0.11.13) Released on 2026-05-10. ##### Bug fixes - Include data files in editable builds ([#​19312](https://redirect.github.com/astral-sh/uv/pull/19312)) - Respect `--require-hashes` when installing from `pylock.toml` files ([#​19334](https://redirect.github.com/astral-sh/uv/pull/19334)) ##### Python - Add CPython 3.14.5
--- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`) - 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. --- - [ ] 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). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/check-docs.yml | 2 +- .github/workflows/check-fmt.yml | 2 +- .github/workflows/check-lint.yml | 6 +++--- .github/workflows/publish-docs.yml | 2 +- .github/workflows/test.yml | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/check-docs.yml b/.github/workflows/check-docs.yml index 469c6c4f6aa6f..412cf55ada2f1 100644 --- a/.github/workflows/check-docs.yml +++ b/.github/workflows/check-docs.yml @@ -15,7 +15,7 @@ jobs: persist-credentials: false - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - version: "0.11.12" + version: "0.11.13" - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 diff --git a/.github/workflows/check-fmt.yml b/.github/workflows/check-fmt.yml index aca9b21c481b7..0a26b42b33c5d 100644 --- a/.github/workflows/check-fmt.yml +++ b/.github/workflows/check-fmt.yml @@ -34,5 +34,5 @@ jobs: - name: "Install uv" uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - version: "0.11.12" + version: "0.11.13" - run: uvx ruff format --diff . diff --git a/.github/workflows/check-lint.yml b/.github/workflows/check-lint.yml index c66b310acb2d5..af0c32398efee 100644 --- a/.github/workflows/check-lint.yml +++ b/.github/workflows/check-lint.yml @@ -28,7 +28,7 @@ jobs: - name: "Install uv" uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - version: "0.11.12" + version: "0.11.13" - run: uvx ruff check . ty: @@ -41,7 +41,7 @@ jobs: - name: "Install uv" uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - version: "0.11.12" + version: "0.11.13" - run: | uvx ty check python/uv uvx \ @@ -75,7 +75,7 @@ jobs: - name: "Install uv" uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - version: "0.11.12" + version: "0.11.13" - run: uvx --from 'validate-pyproject[all,store]' validate-pyproject pyproject.toml readme: diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index 9eba89255efe9..e3e882f2a7990 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -75,7 +75,7 @@ jobs: - name: "Install uv" uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - version: "0.11.12" + version: "0.11.13" - name: "Build docs" run: uv run --only-group docs mkdocs build --strict -f mkdocs.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b8318e657e3ed..c6946c7949bfc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,7 +45,7 @@ jobs: - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - version: "0.11.12" + version: "0.11.13" - name: "Install required Python versions" run: uv python install @@ -153,7 +153,7 @@ jobs: - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - version: "0.11.12" + version: "0.11.13" - name: "Install required Python versions" run: uv python install @@ -226,7 +226,7 @@ jobs: - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: - version: "0.11.12" + version: "0.11.13" - name: "Install required Python versions" run: uv python install From 2b0def7d5075bc2f818f13be2af23c8f22fa5792 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 02:40:57 +0000 Subject: [PATCH 06/16] Update crate-ci/typos action to v1.46.0 (#19351) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | Pending | |---|---|---|---|---| | [crate-ci/typos](https://redirect.github.com/crate-ci/typos) | action | minor | `v1.45.1` → `v1.46.0` | `v1.46.1` | --- ### Release Notes
crate-ci/typos (crate-ci/typos) ### [`v1.46.0`](https://redirect.github.com/crate-ci/typos/releases/tag/v1.46.0) [Compare Source](https://redirect.github.com/crate-ci/typos/compare/v1.45.2...v1.46.0) #### \[1.46.0] - 2026-04-30 ##### Features - Updated the dictionary with the [April 2026](https://redirect.github.com/crate-ci/typos/issues/1531) changes ### [`v1.45.2`](https://redirect.github.com/crate-ci/typos/releases/tag/v1.45.2) [Compare Source](https://redirect.github.com/crate-ci/typos/compare/v1.45.1...v1.45.2) ##### \[1.45.2] - 2026-04-27 ##### Fixes - Ignore ssh [`ed25519`](https://redirect.github.com/crate-ci/typos/commit/ed25519) public keys
--- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`) - 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. --- - [ ] 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). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/check-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-lint.yml b/.github/workflows/check-lint.yml index af0c32398efee..b56132f4875f2 100644 --- a/.github/workflows/check-lint.yml +++ b/.github/workflows/check-lint.yml @@ -162,4 +162,4 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - uses: crate-ci/typos@cf5f1c29a8ac336af8568821ec41919923b05a83 # v1.45.1 + - uses: crate-ci/typos@bbaefadf97b0ec5fdc942684b647f1a6ab250274 # v1.46.0 From 9f21ff88867f59e84bc82f7422492b998aba6e30 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 10 May 2026 23:30:24 -0400 Subject: [PATCH 07/16] Avoid applying `.env` files in parent process (#19343) ## Summary Our support for `.env` files is intended to be limited to the process we execute in `uv run` or `uv tool run` (or `uvx`), i.e., we don't intend to support setting uv-specific environment variables via `.env`. As-is, though, some environment variables like `UV_TOOL_DIR` _can_ be set due to order of operations. This PR modifies our loading to avoid reading the `.env` into the parent process. Instead, we use `dotenvy` to read the values, but set them explicitly on the child process. --------- Co-authored-by: Zanie Blue --- crates/uv/src/commands/tool/run.rs | 132 +++++++++++++++++++++-------- crates/uv/tests/it/tool_run.rs | 58 +++++++++++++ 2 files changed, 153 insertions(+), 37 deletions(-) diff --git a/crates/uv/src/commands/tool/run.rs b/crates/uv/src/commands/tool/run.rs index f90b8016092a1..0d38b0ef22f9a 100644 --- a/crates/uv/src/commands/tool/run.rs +++ b/crates/uv/src/commands/tool/run.rs @@ -82,6 +82,99 @@ impl Display for ToolRunCommand { } } +/// Read dotenv files into an overlay for the spawned tool process. +/// +/// These values intentionally do not mutate uv's process environment and cannot mutate +/// the current uv process' settings. +fn read_env_files( + env_file: &[PathBuf], + no_env_file: bool, +) -> anyhow::Result> { + let mut environment = Vec::new(); + + if no_env_file { + return Ok(environment); + } + + for env_file_path in env_file.iter().rev().map(PathBuf::as_path) { + let iter = match dotenvy::from_path_iter(env_file_path) { + Err(dotenvy::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => { + bail!( + "No environment file found at: `{}`", + env_file_path.simplified_display() + ); + } + Err(dotenvy::Error::Io(err)) => { + bail!( + "Failed to read environment file `{}`: {err}", + env_file_path.simplified_display() + ); + } + Err(dotenvy::Error::LineParse(content, position)) => { + warn_user!( + "Failed to parse environment file `{}` at position {position}: {content}", + env_file_path.simplified_display(), + ); + continue; + } + Err(err) => { + warn_user!( + "Failed to parse environment file `{}`: {err}", + env_file_path.simplified_display(), + ); + continue; + } + Ok(iter) => iter, + }; + + let mut parsed = true; + for item in iter { + match item { + Ok((key, value)) => { + if std::env::var(&key).is_err() { + environment.push((key, value)); + } + } + Err(dotenvy::Error::Io(err)) => { + bail!( + "Failed to read environment file `{}`: {err}", + env_file_path.simplified_display() + ); + } + Err(dotenvy::Error::LineParse(content, position)) => { + warn_user!( + "Failed to parse environment file `{}` at position {position}: {content}", + env_file_path.simplified_display(), + ); + parsed = false; + break; + } + Err(err) => { + warn_user!( + "Failed to parse environment file `{}`: {err}", + env_file_path.simplified_display(), + ); + parsed = false; + break; + } + } + } + + if parsed { + debug!( + "Read environment file at: `{}`", + env_file_path.simplified_display() + ); + } + } + + // `dotenvy::from_path` preserves the first loaded value, while `Command::envs` preserves the + // last value set for the child process. + environment.reverse(); + + Ok(environment) +} + /// Check if the given arguments contain a verbose flag (e.g., `--verbose`, `-v`, `-vv`, etc.) fn find_verbose_flag(args: &[std::ffi::OsString]) -> Option<&str> { args.iter().find_map(|arg| { @@ -138,43 +231,7 @@ pub(crate) async fn run( ); } - // Read from the `.env` file, if necessary. - if !no_env_file { - for env_file_path in env_file.iter().rev().map(PathBuf::as_path) { - match dotenvy::from_path(env_file_path) { - Err(dotenvy::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => { - bail!( - "No environment file found at: `{}`", - env_file_path.simplified_display() - ); - } - Err(dotenvy::Error::Io(err)) => { - bail!( - "Failed to read environment file `{}`: {err}", - env_file_path.simplified_display() - ); - } - Err(dotenvy::Error::LineParse(content, position)) => { - warn_user!( - "Failed to parse environment file `{}` at position {position}: {content}", - env_file_path.simplified_display(), - ); - } - Err(err) => { - warn_user!( - "Failed to parse environment file `{}`: {err}", - env_file_path.simplified_display(), - ); - } - Ok(()) => { - debug!( - "Read environment file at: `{}`", - env_file_path.simplified_display() - ); - } - } - } - } + let env_file_environment = read_env_files(&env_file, no_env_file)?; let Some(command) = command else { // When a command isn't provided, we'll show a brief help including available tools @@ -403,6 +460,7 @@ pub(crate) async fn run( }; process.args(args); + process.envs(env_file_environment); // Construct the `PATH` environment variable. let new_path = std::env::join_paths( diff --git a/crates/uv/tests/it/tool_run.rs b/crates/uv/tests/it/tool_run.rs index ad2f28522e04a..5a49ab847656e 100644 --- a/crates/uv/tests/it/tool_run.rs +++ b/crates/uv/tests/it/tool_run.rs @@ -1,6 +1,11 @@ +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; + use anyhow::Result; use assert_cmd::prelude::*; use assert_fs::prelude::*; +#[cfg(unix)] +use fs_err::{metadata, set_permissions}; use indoc::indoc; use uv_fs::copy_dir_all; use uv_static::EnvVars; @@ -2672,6 +2677,59 @@ fn run_with_env_file() -> anyhow::Result<()> { Resolved [N] packages in [TIME] "); + let evil_tools = context.temp_dir.child(".evil-tools"); + let evil_tool = evil_tools.child("foo"); + let evil_python = if cfg!(windows) { + let scripts = evil_tool.child("Scripts"); + scripts.create_dir_all()?; + scripts.child("python.exe") + } else { + let bin = evil_tool.child("bin"); + bin.create_dir_all()?; + bin.child("python3") + }; + evil_python.write_str(indoc! { r" + #!/bin/sh + echo queried > queried.txt + exit 1 + " })?; + + #[cfg(unix)] + { + let mut permissions = metadata(evil_python.path())?.permissions(); + permissions.set_mode(0o755); + set_permissions(evil_python.path(), permissions)?; + } + + context.temp_dir.child(".file").write_str(indoc! { " + UV_TOOL_DIR=.evil-tools + THE_EMPIRE_VARIABLE=palpatine + REBEL_1=leia_organa + REBEL_2=obi_wan_kenobi + REBEL_3=C3PO + " + })?; + + uv_snapshot!(context.filters(), context.tool_run() + .arg("--from") + .arg("./foo") + .arg("script") + .env(EnvVars::UV_ENV_FILE, ".file") + .env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()), @" + success: true + exit_code: 0 + ----- stdout ----- + palpatine + leia_organa + obi_wan_kenobi + C3PO + + ----- stderr ----- + Resolved [N] packages in [TIME] + "); + + assert!(!context.temp_dir.child("queried.txt").exists()); + Ok(()) } From 81e7f8ccbbd3ed407f32312743fe138d36411cff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 13:52:12 +0000 Subject: [PATCH 08/16] Update Rust crate junction to v2 (#19353) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: William Woodruff --- Cargo.lock | 4 +- Cargo.toml | 2 +- crates/uv/src/commands/python/uninstall.rs | 83 ++++++++++------------ crates/uv/tests/it/python_install.rs | 1 + 4 files changed, 41 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ddb201d6a3f69..0efd2e3716bba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2538,9 +2538,9 @@ dependencies = [ [[package]] name = "junction" -version = "1.4.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cfc352a66ba903c23239ef51e809508b6fc2b0f90e3476ac7a9ff47e863ae95" +checksum = "160f2eade097f30263b548aae5deb12ad349c909baa710fa24b92c9090b2e006" dependencies = [ "scopeguard", "windows-sys 0.61.2", diff --git a/Cargo.toml b/Cargo.toml index 1e2d0192ea448..d68b7fda0c42f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -171,7 +171,7 @@ indicatif = { version = "0.18.0" } indoc = { version = "2.0.5" } itertools = { version = "0.14.0" } jiff = { version = "0.2.0", features = ["serde"] } -junction = { version = "1.4.2" } +junction = { version = "2.0.0" } mailparse = { version = "0.16.0" } md-5 = { version = "0.10.6" } memchr = { version = "2.7.4" } diff --git a/crates/uv/src/commands/python/uninstall.rs b/crates/uv/src/commands/python/uninstall.rs index 62124c13cc8e4..ca2df3139783e 100644 --- a/crates/uv/src/commands/python/uninstall.rs +++ b/crates/uv/src/commands/python/uninstall.rs @@ -198,50 +198,6 @@ async fn do_uninstall( .insert(executable); } - // Pre-compute which minor versions will have no remaining installations - // after all matching installations are removed. - let matching_keys: IndexSet<_> = matching_installations - .iter() - .map(|installation| installation.key().clone()) - .collect(); - let anticipated_remaining_minor_versions = - PythonInstallationMinorVersionKey::highest_installations_by_minor_version_key( - installed_installations - .iter() - .filter(|installation| !matching_keys.contains(installation.key())), - ); - - // Remove minor version links (symlinks on Unix, junctions on Windows) for minor - // versions that will have no remaining installations. This must happen before - // removing the installation directories so that the link targets still exist, - // which is required when reading link targets on Windows. - for installation in &matching_installations { - if !anticipated_remaining_minor_versions.contains_key(installation.minor_version_key()) { - if let Some(minor_version_link) = - PythonMinorVersionLink::from_installation(installation) - { - if minor_version_link.exists() { - if cfg!(windows) { - fs_err::remove_dir(minor_version_link.symlink_directory.as_path())?; - } else { - fs_err::remove_file(minor_version_link.symlink_directory.as_path())?; - } - let symlink_term = if cfg!(windows) { - "junction" - } else { - "symlink directory" - }; - debug!( - "Removed {}: {}", - symlink_term, - minor_version_link.symlink_directory.to_string_lossy() - ); - } - } - } - } - - // Remove the installation directories. let mut tasks = FuturesUnordered::new(); for installation in &matching_installations { tasks.push(async { @@ -261,8 +217,9 @@ async fn do_uninstall( } } - // Update minor version links for minor versions that still have remaining - // installations, ensuring the link points to the new highest patch. + // Read all existing managed installations and find the highest installed patch + // for each installed minor version. Ensure the minor version link directory + // is still valid. let uninstalled_minor_versions: IndexSet<_> = uninstalled .iter() .map(PythonInstallationMinorVersionKey::ref_cast) @@ -283,6 +240,40 @@ async fn do_uninstall( { installation.ensure_minor_version_link()?; } + // For each uninstalled installation, check if there are no remaining installations + // for its minor version. If there are none remaining, remove the symlink directory + // (or junction on Windows) if it exists. + for installation in &matching_installations { + if !remaining_minor_versions.contains_key(installation.minor_version_key()) { + if let Some(minor_version_link) = + PythonMinorVersionLink::from_installation(installation) + { + if minor_version_link.exists() { + let result = if cfg!(windows) { + fs_err::remove_dir(minor_version_link.symlink_directory.as_path()) + } else { + fs_err::remove_file(minor_version_link.symlink_directory.as_path()) + }; + if result.is_err() { + return Err(anyhow::anyhow!( + "Failed to remove symlink directory {}", + minor_version_link.symlink_directory.display() + )); + } + let symlink_term = if cfg!(windows) { + "junction" + } else { + "symlink directory" + }; + debug!( + "Removed {}: {}", + symlink_term, + minor_version_link.symlink_directory.to_string_lossy() + ); + } + } + } + } // Report on any uninstalled installations. if let Some(first_uninstalled) = uninstalled.first() { diff --git a/crates/uv/tests/it/python_install.rs b/crates/uv/tests/it/python_install.rs index 85df47bc29ccd..645a85c21393f 100644 --- a/crates/uv/tests/it/python_install.rs +++ b/crates/uv/tests/it/python_install.rs @@ -3683,6 +3683,7 @@ fn uninstall_last_patch() { /// (symlink on Unix, junction on Windows) should be removed. /// /// Regression test for . +/// This now backstops the upgrade to `junction` >=2, which can read dangling junctions. #[test] fn uninstall_last_patch_removes_minor_version_link() { let context = uv_test::test_context_with_versions!(&[]) From b2bd71a82c172926d6fb76ecbbad9c61c6e706b1 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Mon, 11 May 2026 06:55:11 -0700 Subject: [PATCH 09/16] Filter ANSI codes in logging output (#19311) --- Cargo.lock | 1 + crates/uv-logging/Cargo.toml | 2 +- crates/uv-logging/src/lib.rs | 71 +++++++++++++++++++++++++++++++++++- crates/uv/src/logging.rs | 3 +- 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0efd2e3716bba..f5e805c670c90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6720,6 +6720,7 @@ dependencies = [ name = "uv-logging" version = "0.0.46" dependencies = [ + "anstream", "jiff", "owo-colors", "tracing", diff --git a/crates/uv-logging/Cargo.toml b/crates/uv-logging/Cargo.toml index 815c90c9057b5..4898522e34a7c 100644 --- a/crates/uv-logging/Cargo.toml +++ b/crates/uv-logging/Cargo.toml @@ -11,12 +11,12 @@ license = { workspace = true } [lib] doctest = false -test = false [lints] workspace = true [dependencies] +anstream = { workspace = true } jiff = { workspace = true } owo-colors = { workspace = true } tracing-subscriber = { workspace = true } diff --git a/crates/uv-logging/src/lib.rs b/crates/uv-logging/src/lib.rs index 7d5aa1575c2ec..1dce7c955a85c 100644 --- a/crates/uv-logging/src/lib.rs +++ b/crates/uv-logging/src/lib.rs @@ -2,8 +2,9 @@ use std::fmt; use jiff::Timestamp; use owo_colors::OwoColorize; -use tracing::{Event, Subscriber}; -use tracing_subscriber::fmt::format::Writer; +use tracing::{Event, Subscriber, field::Field}; +use tracing_subscriber::field::MakeExt; +use tracing_subscriber::fmt::format::{self, Writer}; use tracing_subscriber::fmt::{FmtContext, FormatEvent, FormatFields}; use tracing_subscriber::registry::LookupSpan; @@ -93,3 +94,69 @@ where writeln!(writer) } } + +/// Return the field formatter for uv logging. +/// +/// The event formatter is responsible for uv's own log colors, such as the level prefix. Field +/// values can come from arbitrary `Display` or `Debug` implementations, so strip any ANSI escape +/// sequences there before writing them to the log line. +pub fn uv_fields() -> impl for<'writer> FormatFields<'writer> { + format::debug_fn(format_field) + .display_messages() + .delimited(" ") +} + +fn format_field(writer: &mut Writer<'_>, field: &Field, value: &dyn fmt::Debug) -> fmt::Result { + // NOTE: The various cases in this function match tracing-subscriber's default field formatting. + // See: https://docs.rs/tracing-subscriber/0.3.23/src/tracing_subscriber/fmt/format/mod.rs.html#1303-1338 + + let field = field.name(); + if field.starts_with("log.") { + return Ok(()); + } + + let value = format!("{value:?}"); + let value = anstream::adapter::strip_str(&value); + + if field == "message" { + write!(writer, "{value}") + } else { + write!( + writer, + "{}={value}", + // Render `type=...` instead of `r#type=...`. + field.strip_prefix("r#").unwrap_or(field) + ) + } +} + +#[cfg(test)] +mod tests { + use tracing::{Callsite, Event, Level, field::Value, metadata::Kind}; + use tracing_subscriber::fmt::FormatFields; + use tracing_subscriber::fmt::format::Writer; + + use super::uv_fields; + + #[test] + fn strips_ansi_from_message_fields() { + let callsite = tracing::callsite! { + name: "event", + kind: Kind::EVENT, + level: Level::TRACE, + fields: message + }; + let metadata = callsite.metadata(); + let message = format_args!("Error trace: {}", "\x1b[36m\x1b[1mhint\x1b[0m"); + let values = [Some(&message as &dyn Value)]; + let fields = metadata.fields().value_set_all(&values); + let event = Event::new(metadata, &fields); + let mut output = String::new(); + + uv_fields() + .format_fields(Writer::new(&mut output), event) + .expect("field formatting should succeed"); + + assert_eq!(output, "Error trace: hint"); + } +} diff --git a/crates/uv/src/logging.rs b/crates/uv/src/logging.rs index db34c0ab49e54..be27c7a836d1c 100644 --- a/crates/uv/src/logging.rs +++ b/crates/uv/src/logging.rs @@ -13,7 +13,7 @@ use tracing_tree::HierarchicalLayer; use tracing_tree::time::Uptime; use uv_cli::ColorChoice; -use uv_logging::UvFormat; +use uv_logging::{UvFormat, uv_fields}; #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub(crate) enum Level { @@ -106,6 +106,7 @@ pub(crate) fn setup_logging( .with( tracing_subscriber::fmt::layer() .event_format(UvFormat::default()) + .fmt_fields(uv_fields()) .with_writer(writer) .with_ansi(ansi) .with_filter(filter), From 96b43afadc2add190895b20282e83023a08bd0e7 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Mon, 11 May 2026 10:48:02 -0500 Subject: [PATCH 10/16] Ensure publish to crates.io is idempotent (#19361) Co-authored-by: Codex --- .github/workflows/publish-crates.yml | 2 +- scripts/publish-crates.py | 190 +++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 scripts/publish-crates.py diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml index 9c0ad1c155b09..165e6238b83d3 100644 --- a/.github/workflows/publish-crates.yml +++ b/.github/workflows/publish-crates.yml @@ -33,6 +33,6 @@ jobs: run: rustup toolchain install nightly-2026-04-15 --profile minimal --no-self-update - name: Publish workspace crates # Note `--no-verify` is safe because we do a publish dry-run elsewhere in CI - run: cargo +nightly-2026-04-15 publish --workspace --no-verify -Zpublish-timeout --config 'publish.timeout=600' + run: python3 scripts/publish-crates.py --cargo cargo +nightly-2026-04-15 --no-verify -- -Zpublish-timeout --config 'publish.timeout=600' env: CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} diff --git a/scripts/publish-crates.py b/scripts/publish-crates.py new file mode 100644 index 0000000000000..9c3fb2cbf2166 --- /dev/null +++ b/scripts/publish-crates.py @@ -0,0 +1,190 @@ +# Publish workspace crates to crates.io idempotently. +# +# `cargo publish --workspace` fails if any selected crate version already exists on crates.io. That +# makes release re-runs fail after a previous partial publish. This script queries crates.io first, +# excludes package versions that already exist, then delegates to `cargo publish --workspace` for the +# remaining packages so Cargo still handles package ordering. +# +# Usage: +# +# CARGO_REGISTRY_TOKEN= python3 scripts/publish-crates.py --no-verify + +from __future__ import annotations + +import argparse +import dataclasses +import json +import pathlib +import subprocess +import sys +import time +import urllib.error +import urllib.parse +import urllib.request + +CRATES_IO_API = "https://crates.io/api/v1" +USER_AGENT = "uv-crates-io-publish (github.com/astral-sh/uv)" + +REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent + +# Short delay between crates.io API requests to avoid burst rate limits. +CRATES_IO_REQUEST_DELAY_SECS = 0.2 + + +@dataclasses.dataclass(frozen=True) +class Crate: + name: str + version: str + + def pretty(self) -> str: + return f"{self.name}@{self.version}" + + +def get_publishable_crates(cargo: list[str]) -> list[Crate]: + """Return publishable workspace crates.""" + result = subprocess.run( + [*cargo, "metadata", "--format-version", "1", "--no-deps"], + cwd=REPO_ROOT, + capture_output=True, + text=True, + check=True, + ) + metadata = json.loads(result.stdout) + + workspace_member_ids = set(metadata["workspace_members"]) + crates = [] + for package in metadata["packages"]: + if package["id"] not in workspace_member_ids: + continue + # `publish = false` is represented as an empty list in cargo metadata. + if package.get("publish") == []: + continue + crates.append(Crate(name=package["name"], version=package["version"])) + + return crates + + +def crate_version_url(crate: Crate, api_url: str) -> str: + crate_name = urllib.parse.quote(crate.name, safe="") + crate_version = urllib.parse.quote(crate.version, safe="") + return f"{api_url}/crates/{crate_name}/{crate_version}" + + +def crate_version_exists(crate: Crate, api_url: str) -> bool: + """Return True if the crate version already exists on crates.io.""" + request = urllib.request.Request( + crate_version_url(crate, api_url), + headers={"User-Agent": USER_AGENT}, + ) + try: + with urllib.request.urlopen(request) as response: + if response.status == 200: + return True + raise RuntimeError( + f"unexpected status {response.status} for {crate.pretty()}" + ) + except urllib.error.HTTPError as exc: + if exc.code == 404: + return False + raise RuntimeError( + f"failed to query {crate.pretty()} from crates.io: HTTP {exc.code}" + ) from exc + except urllib.error.URLError as exc: + raise RuntimeError( + f"failed to query {crate.pretty()} from crates.io: {exc}" + ) from exc + + +def existing_crate_versions(crates: list[Crate], api_url: str) -> set[str]: + """Return the names of workspace crates whose current version exists on crates.io.""" + existing = set() + for index, crate in enumerate(crates): + if index > 0: + time.sleep(CRATES_IO_REQUEST_DELAY_SECS) + if crate_version_exists(crate, api_url): + print(f"Skipping {crate.pretty()}: already exists on crates.io") + existing.add(crate.name) + return existing + + +def build_cargo_publish_command( + cargo: list[str], existing: set[str], cargo_publish_args: list[str] +) -> list[str]: + """Build the `cargo publish` command for all not-yet-published workspace crates.""" + command = [*cargo, "publish", "--workspace"] + for crate_name in sorted(existing): + command.extend(["--exclude", crate_name]) + command.extend(cargo_publish_args) + return command + + +def publish_workspace( + cargo: list[str], crates: list[Crate], api_url: str, cargo_publish_args: list[str] +) -> int: + existing = existing_crate_versions(crates, api_url) + missing = [crate for crate in crates if crate.name not in existing] + + if not missing: + print("All publishable workspace crate versions already exist on crates.io") + return 0 + + print("Publishing workspace crate versions that do not exist on crates.io:") + for crate in missing: + print(f" {crate.pretty()}") + + command = build_cargo_publish_command(cargo, existing, cargo_publish_args) + return subprocess.run(command, cwd=REPO_ROOT).returncode + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Publish workspace crates to crates.io idempotently." + ) + parser.add_argument( + "--api-url", + default=CRATES_IO_API, + help=argparse.SUPPRESS, + ) + parser.add_argument( + "--cargo", + default=["cargo"], + nargs="+", + help=argparse.SUPPRESS, + ) + parser.add_argument( + "--dry-run", + action="store_true", + help="Pass --dry-run through to cargo publish.", + ) + parser.add_argument( + "--no-verify", + action="store_true", + help="Pass --no-verify through to cargo publish.", + ) + parser.add_argument( + "cargo_publish_args", + nargs=argparse.REMAINDER, + help=argparse.SUPPRESS, + ) + args = parser.parse_args(argv) + if args.cargo_publish_args[:1] == ["--"]: + args.cargo_publish_args = args.cargo_publish_args[1:] + return args + + +def main(argv: list[str] | None = None) -> int: + args = parse_args(argv) + + cargo_publish_args = [] + if args.dry_run: + cargo_publish_args.append("--dry-run") + if args.no_verify: + cargo_publish_args.append("--no-verify") + cargo_publish_args.extend(args.cargo_publish_args) + + crates = get_publishable_crates(args.cargo) + return publish_workspace(args.cargo, crates, args.api_url, cargo_publish_args) + + +if __name__ == "__main__": + sys.exit(main()) From 374fcaa56aa46a2923eed31fe0df7a4a7a14c477 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Mon, 11 May 2026 13:42:31 -0700 Subject: [PATCH 11/16] Fix JUnit upload on Windows runners (#19370) ## Summary This was an oversight from #19330. We're running our tests on Windows in a Dev Drive, so we need to fixup the path rather than assuming that CWD has a `target` dir. ## Test Plan NFC. Signed-off-by: William Woodruff --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c6946c7949bfc..afb1e2574bc1e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -288,6 +288,6 @@ jobs: uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: junit-results-windows-${{ matrix.partition }} - path: target/nextest/ci*/junit.xml + path: ${{ env.UV_WORKSPACE }}/target/nextest/ci*/junit.xml if-no-files-found: ignore retention-days: 14 From 685c32c51de5f21cdffe1311d6265b9dbebe2a03 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 11 May 2026 19:06:34 -0400 Subject: [PATCH 12/16] Ignore `top_level.txt` entries in uninstall that are not valid Python identifiers (#19340) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary In eggs, `top_level.txt` contains top-level import names, not paths. setuptools documents the file as [one Python identifier per line](https://setuptools.pypa.io/en/stable/deprecated/python_eggs.html#top-level-txt-conflict-management-metadata). This PR updates the egg uninstall process to reject `top_level.txt` entries that are not valid Python identifiers (before joining them against site-packages for deletion). That prevents malformed entries like `../../target` or absolute paths from deleting files outside the package’s valid top-level modules. --- crates/uv-install-wheel/src/uninstall.rs | 121 +++++++++++------------ crates/uv-installer/src/uninstall.rs | 8 +- crates/uv/tests/it/pip_uninstall.rs | 58 ++++++++++- 3 files changed, 120 insertions(+), 67 deletions(-) diff --git a/crates/uv-install-wheel/src/uninstall.rs b/crates/uv-install-wheel/src/uninstall.rs index 5e1a2a200b8a8..6853bb951c876 100644 --- a/crates/uv-install-wheel/src/uninstall.rs +++ b/crates/uv-install-wheel/src/uninstall.rs @@ -159,7 +159,8 @@ pub fn uninstall_wheel( }) } -static WARNED_FOR_PACKAGE: OnceLock>> = OnceLock::new(); +static WARNED_FOR_RECORD_ENTRY_PACKAGE: OnceLock>> = OnceLock::new(); +static WARNED_FOR_EGG_TOP_LEVEL_PACKAGE: OnceLock>> = OnceLock::new(); /// Check if the path is inside the venv or a system interpreter path, and warn if it isn't. /// @@ -194,7 +195,7 @@ fn is_path_in_scheme( } else { // A package that does this is malformed to the point of being a risk to the user, be // annoying about it, but only once per package. - if WARNED_FOR_PACKAGE + if WARNED_FOR_RECORD_ENTRY_PACKAGE .get_or_init(|| Mutex::new(HashSet::new())) .lock() .expect("The mutex is broken, did some other thread panic?") @@ -210,14 +211,39 @@ fn is_path_in_scheme( } } +/// Check that a `top_level.txt` entry names a single top-level module or package. +/// +/// Unlike wheel `RECORD` entries, egg `top_level.txt` entries refer to direct children of the +/// egg's base location, not arbitrary paths. Treating them as paths can make uninstall delete +/// directories outside `site-packages`. +fn is_valid_top_level_entry(entry: &str, distribution: impl Display) -> bool { + if is_safe_top_level_entry(entry) { + true + } else { + if WARNED_FOR_EGG_TOP_LEVEL_PACKAGE + .get_or_init(|| Mutex::new(HashSet::new())) + .lock() + .expect("The mutex is broken, did some other thread panic?") + .insert(distribution.to_string()) + { + warn_user!( + "Invalid `top_level.txt` entry in {} that is not a top-level module or package, skipping: {}", + distribution, + entry + ); + } + false + } +} + +fn is_safe_top_level_entry(entry: &str) -> bool { + !entry.is_empty() && entry != "." && entry != ".." && !entry.contains(['/', '\\']) +} + /// Uninstall the egg represented by the `.egg-info` directory. /// /// See: -pub fn uninstall_egg( - egg_info: &Path, - distribution: impl Display, - layout: &Layout, -) -> Result { +pub fn uninstall_egg(egg_info: &Path, distribution: impl Display) -> Result { let mut file_count = 0usize; let mut dir_count = 0usize; @@ -268,12 +294,12 @@ pub fn uninstall_egg( // Remove everything in `top_level.txt`. for entry in top_level { - let path = dist_location.join(&entry); - - if !is_path_in_scheme(&entry, dist_location, &distribution, layout) { + if !is_valid_top_level_entry(&entry, &distribution) { continue; } + let path = dist_location.join(&entry); + // Remove as a directory. match fs_err::remove_dir_all(&path) { Ok(()) => { @@ -435,7 +461,19 @@ mod tests { use uv_pypi_types::Scheme; use crate::Layout; - use crate::uninstall::{uninstall_egg, uninstall_wheel}; + use crate::uninstall::{is_safe_top_level_entry, uninstall_egg, uninstall_wheel}; + + #[test] + fn test_top_level_entry_safe_name() { + assert!(is_safe_top_level_entry("package")); + + assert!(!is_safe_top_level_entry("")); + assert!(!is_safe_top_level_entry(".")); + assert!(!is_safe_top_level_entry("..")); + assert!(!is_safe_top_level_entry("../package")); + assert!(!is_safe_top_level_entry("package/name")); + assert!(!is_safe_top_level_entry(r"package\name")); + } /// Uninstall must not remove files outside the install scheme. #[test] @@ -473,7 +511,7 @@ mod tests { let metadata = dist_info.child("METADATA"); metadata.touch().unwrap(); - // Something that looks sufficiently like a Unix venv. + // Something that looks sufficiently like a Unix environment. let layout = Layout { sys_executable: venv.path().join("bin/python"), python_version: (3, 13), @@ -500,20 +538,20 @@ mod tests { fn test_uninstall_egg_info_path_traversal() { let venv = assert_fs::TempDir::new().unwrap(); let site_packages = venv.child("lib/python3.12/site-packages"); - let outside_dir = assert_fs::TempDir::new().unwrap(); - // Create a directory outside site-packages that a malicious top_level.txt might target. - let target_dir = outside_dir.child("traversal_target"); + // Create directories outside site-packages, but inside the environment. Egg uninstall should + // still reject them, even though wheel RECORD entries may target other install-scheme + // directories. + let target_dir = venv.child("traversal_target"); let target_file = target_dir.child("secret.txt"); target_file.write_str("I should not be deleted").unwrap(); - // Build a relative traversal path from site-packages to the target directory. let egg_info = site_packages.child("evilpkg-0.1.0.egg-info"); egg_info.create_dir_all().unwrap(); let target_path = pathdiff::diff_paths(target_dir.path(), site_packages.path()).unwrap(); assert!(site_packages.join(&target_path).exists()); - // Create a fake egg-info directory with a top_level.txt containing a path traversal entry. + // Create a fake egg-info directory with a path traversal entry in `top_level.txt`. egg_info .child("top_level.txt") .write_str(&format!("evilpkg\n{}\n", target_path.display())) @@ -523,23 +561,10 @@ mod tests { let init_py = site_packages.child("evilpkg").child("__init__.py"); init_py.touch().unwrap(); - // Something that looks sufficiently like a Unix venv. - let layout = Layout { - sys_executable: venv.path().join("bin/python"), - python_version: (3, 13), - os_name: "posix".to_string(), - scheme: Scheme { - purelib: site_packages.to_path_buf(), - platlib: site_packages.to_path_buf(), - scripts: venv.path().join("bin"), - data: venv.path().to_path_buf(), - include: venv.path().join("include/python3.12"), - }, - }; + uninstall_egg(egg_info.path(), "evilpkg 0.1.0").unwrap(); - uninstall_egg(egg_info.path(), "evilpkg 0.1.0", &layout).unwrap(); - - // The regular package directory has been removed, while the directory outside the scheme still exists. + // The regular package directory has been removed, while the directory outside + // site-packages still exists. assert!(target_dir.exists()); assert!(target_file.exists()); assert!(!init_py.exists()); @@ -571,20 +596,7 @@ mod tests { egg_info.create_dir_all().unwrap(); egg_info.child("top_level.txt").write_str("\n").unwrap(); - let layout = Layout { - sys_executable: venv.path().join("bin/python"), - python_version: (3, 13), - os_name: "posix".to_string(), - scheme: Scheme { - purelib: site_packages.to_path_buf(), - platlib: site_packages.to_path_buf(), - scripts: venv.path().join("bin"), - data: venv.path().to_path_buf(), - include: venv.path().join("include/python3.12"), - }, - }; - - uninstall_egg(egg_info.path(), "emptypkg 0.1.0", &layout).unwrap(); + uninstall_egg(egg_info.path(), "emptypkg 0.1.0").unwrap(); // The egg-info is gone, but the rest of site-packages (including the sibling // package) survives. @@ -628,20 +640,7 @@ mod tests { .write_str("\npkg_a\n \r\npkg_b\n\n") .unwrap(); - let layout = Layout { - sys_executable: venv.path().join("bin/python"), - python_version: (3, 13), - os_name: "posix".to_string(), - scheme: Scheme { - purelib: site_packages.to_path_buf(), - platlib: site_packages.to_path_buf(), - scripts: venv.path().join("bin"), - data: venv.path().to_path_buf(), - include: venv.path().join("include/python3.12"), - }, - }; - - uninstall_egg(egg_info.path(), "mixedpkg 0.1.0", &layout).unwrap(); + uninstall_egg(egg_info.path(), "mixedpkg 0.1.0").unwrap(); // The two named packages are gone, the egg-info is gone, and site-packages plus // the sibling survive. diff --git a/crates/uv-installer/src/uninstall.rs b/crates/uv-installer/src/uninstall.rs index eace930091c9b..3c203334099c9 100644 --- a/crates/uv-installer/src/uninstall.rs +++ b/crates/uv-installer/src/uninstall.rs @@ -13,11 +13,9 @@ pub async fn uninstall( InstalledDistKind::Registry(_) | InstalledDistKind::Url(_) => Ok( uv_install_wheel::uninstall_wheel(dist.install_path(), &dist, &layout)?, ), - InstalledDistKind::EggInfoDirectory(_) => Ok(uv_install_wheel::uninstall_egg( - dist.install_path(), - &dist, - &layout, - )?), + InstalledDistKind::EggInfoDirectory(_) => { + Ok(uv_install_wheel::uninstall_egg(dist.install_path(), &dist)?) + } InstalledDistKind::LegacyEditable(dist) => { Ok(uv_install_wheel::uninstall_legacy_editable(&dist.egg_link)?) } diff --git a/crates/uv/tests/it/pip_uninstall.rs b/crates/uv/tests/it/pip_uninstall.rs index e475ac5be99e2..07d02d9cabe62 100644 --- a/crates/uv/tests/it/pip_uninstall.rs +++ b/crates/uv/tests/it/pip_uninstall.rs @@ -535,7 +535,7 @@ fn uninstall_record_path_traversal() -> Result<()> { // Build the relative traversal path from site-packages to a target file outside // site-packages but inside the test temp dir. RECORD uses forward slashes, even on - // Windows, and the venv layout (and thus the traversal depth) differs by platform, + // Windows, and the environment layout (and thus the traversal depth) differs by platform, // so we construct the path manually and filter the leading `../` sequence out of the // snapshot above. let target_file = context.temp_dir.child("traversal_target.txt"); @@ -580,6 +580,62 @@ fn uninstall_record_path_traversal() -> Result<()> { Ok(()) } +/// Egg `top_level.txt` entries must be top-level names, not paths. +#[test] +fn uninstall_egg_info_top_level_path_traversal() -> Result<()> { + // The traversal-depth count differs between Unix (`.venv/lib/pythonX.Y/site-packages`) + // and Windows (`.venv/Lib/site-packages`), so normalize the `../` sequence in the warning. + let context = uv_test::test_context!("3.12") + .with_filter((r"(\.\./)+traversal_target", "[..]/traversal_target")); + + let site_packages = ChildPath::new(context.site_packages()); + + // Manually create a `name-version.egg-info` directory, which is recognized by the shared egg + // filename parser. + let egg_info = site_packages.child("evilpkg-0.1.0.egg-info"); + egg_info.create_dir_all()?; + + // The traversal target is outside site-packages but inside the environment, so a wheel RECORD entry + // could validly target this scheme area. An egg `top_level.txt` entry must not. + let target_dir = context.venv.child("traversal_target"); + let target_file = target_dir.child("secret.txt"); + target_file.write_str("I should not be deleted")?; + + let depth = context + .site_packages() + .strip_prefix(context.venv.path())? + .components() + .count(); + let traversal_entry = format!("{}traversal_target", "../".repeat(depth)); + assert!(context.site_packages().join(&traversal_entry).exists()); + + egg_info + .child("top_level.txt") + .write_str(&format!("evilpkg\n{traversal_entry}\n"))?; + + let init_py = site_packages.child("evilpkg").child("__init__.py"); + init_py.touch()?; + + uv_snapshot!(context.filters(), context.pip_uninstall() + .arg("evilpkg"), @" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: Invalid `top_level.txt` entry in evilpkg==0.1.0 that is not a top-level module or package, skipping: [..]/traversal_target + Uninstalled 1 package in [TIME] + - evilpkg==0.1.0 + "); + + assert!(target_dir.exists()); + assert!(target_file.exists()); + assert!(!init_py.exists()); + assert!(!egg_info.exists()); + + Ok(()) +} + /// `--yes` is accepted for `pip uninstall` compatibility, but emits a warning. #[test] fn yes_flag() { From 7d6590313139e075eac190a3611238072e7c3cdf Mon Sep 17 00:00:00 2001 From: Zsolt Dollenstein Date: Tue, 12 May 2026 08:39:29 -0700 Subject: [PATCH 13/16] Add Astral mirror URL override (#19206) Support UV_ASTRAL_MIRROR_URL for mirrored Astral release metadata and artifacts, including Ruff, CPython downloads, and self-update. When set, no GitHub fallback takes place. The more specific env vars override this. Closes https://github.com/astral-sh/uv/issues/9134 Closes https://github.com/astral-sh/uv/issues/16519 Closes https://github.com/astral-sh/uv/issues/17255 Closes https://github.com/astral-sh/uv/issues/15970 Closes https://github.com/astral-sh/uv/issues/18525 --- Cargo.lock | 1 + crates/uv-bin-install/Cargo.toml | 1 + crates/uv-bin-install/src/lib.rs | 266 ++++++++++++++++++++------ crates/uv-python/src/downloads.rs | 141 ++++++++++++-- crates/uv-static/src/env_vars.rs | 29 +++ crates/uv-static/src/lib.rs | 28 +++ crates/uv/src/commands/self_update.rs | 209 +++++++++++++++++--- 7 files changed, 582 insertions(+), 93 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5e805c670c90..ce48fa8cbe7ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5988,6 +5988,7 @@ dependencies = [ "uv-pep440", "uv-platform", "uv-redacted", + "uv-static", "wiremock", ] diff --git a/crates/uv-bin-install/Cargo.toml b/crates/uv-bin-install/Cargo.toml index c6dfd214b02cc..4f049b5d4dc6e 100644 --- a/crates/uv-bin-install/Cargo.toml +++ b/crates/uv-bin-install/Cargo.toml @@ -23,6 +23,7 @@ uv-extract = { workspace = true } uv-pep440 = { workspace = true } uv-platform = { workspace = true } uv-redacted = { workspace = true } +uv-static = { workspace = true } fs-err = { workspace = true, features = ["tokio"] } futures = { workspace = true } diff --git a/crates/uv-bin-install/src/lib.rs b/crates/uv-bin-install/src/lib.rs index 1671b7e5b3fca..265e8224b418a 100644 --- a/crates/uv-bin-install/src/lib.rs +++ b/crates/uv-bin-install/src/lib.rs @@ -22,6 +22,7 @@ use tokio_util::compat::FuturesAsyncReadCompatExt; use url::Url; use uv_client::retryable_on_request_failure; use uv_distribution_filename::SourceDistExtension; +use uv_static::{astral_mirror_base_url, astral_mirror_url_from_env, custom_astral_mirror_url}; use uv_cache::{Cache, CacheBucket, CacheEntry, Error as CacheError}; use uv_client::{BaseClient, RetriableError, fetch_with_url_fallback}; @@ -72,69 +73,96 @@ impl Binary { platform: &str, format: ArchiveFormat, ) -> Result, Error> { + let custom_astral_mirror = astral_mirror_url_from_env(); + (*self).download_urls_with_astral_mirror( + version, + platform, + format, + custom_astral_mirror.as_deref(), + ) + } + + fn download_urls_with_astral_mirror( + self, + version: &Version, + platform: &str, + format: ArchiveFormat, + astral_mirror_url: Option<&str>, + ) -> Result, Error> { + let astral_mirror_url = custom_astral_mirror_url(astral_mirror_url); match self { Self::Ruff => { let suffix = format!("{version}/ruff-{platform}.{}", format.extension()); - let canonical = format!("{RUFF_GITHUB_URL_PREFIX}{suffix}"); - let mirror = format!("{RUFF_DEFAULT_MIRROR}{suffix}"); - Ok(vec![ - DisplaySafeUrl::parse(&mirror).map_err(|err| Error::UrlParse { - url: mirror, - source: err, - })?, - DisplaySafeUrl::parse(&canonical).map_err(|err| Error::UrlParse { - url: canonical, - source: err, - })?, - ]) + let mirror_base = astral_mirror_base_url(astral_mirror_url); + let mirror = format!("{mirror_base}{RUFF_MIRROR_SUFFIX}{suffix}"); + let mut urls = vec![parse_url(mirror)?]; + // When using the default mirror, also fall back to GitHub. + if astral_mirror_url.is_none() { + let canonical = format!("{RUFF_GITHUB_URL_PREFIX}{suffix}"); + urls.push(parse_url(canonical)?); + } + Ok(urls) } Self::Uv => { let canonical = format!( "{UV_GITHUB_URL_PREFIX}{version}/uv-{platform}.{}", format.extension() ); - Ok(vec![DisplaySafeUrl::parse(&canonical).map_err(|err| { - Error::UrlParse { - url: canonical, - source: err, - } - })?]) + Ok(vec![parse_url(canonical)?]) } } } /// Return the ordered list of manifest URLs to try for this binary. - fn manifest_urls(self) -> Vec { + fn manifest_urls(self) -> Result, Error> { + let custom_astral_mirror = astral_mirror_url_from_env(); + self.manifest_urls_with_astral_mirror(custom_astral_mirror.as_deref()) + } + + fn manifest_urls_with_astral_mirror( + self, + astral_mirror_url: Option<&str>, + ) -> Result, Error> { + let astral_mirror_url = custom_astral_mirror_url(astral_mirror_url); let name = self.name(); - match self { - // These are static strings so parsing cannot fail. - Self::Ruff => vec![ - DisplaySafeUrl::parse(&format!("{VERSIONS_MANIFEST_MIRROR}/{name}.ndjson")) - .unwrap(), - DisplaySafeUrl::parse(&format!("{VERSIONS_MANIFEST_URL}/{name}.ndjson")).unwrap(), - ], - Self::Uv => vec![ - DisplaySafeUrl::parse(&format!("{VERSIONS_MANIFEST_MIRROR}/{name}.ndjson")) - .unwrap(), - DisplaySafeUrl::parse(&format!("{VERSIONS_MANIFEST_URL}/{name}.ndjson")).unwrap(), - ], + let mirror_base = astral_mirror_base_url(astral_mirror_url); + let mirror = format!("{mirror_base}{VERSIONS_MANIFEST_MIRROR_SUFFIX}/{name}.ndjson"); + let mut urls = vec![parse_url(mirror)?]; + // When using the default mirror, also fall back to the canonical raw GitHub URL. + if astral_mirror_url.is_none() { + let canonical = format!("{VERSIONS_MANIFEST_URL}/{name}.ndjson"); + urls.push(parse_url(canonical)?); } + Ok(urls) } /// Given a canonical artifact URL (e.g., from the versions manifest), return the ordered list /// of URLs to try for this binary. - fn mirror_urls(self, canonical_url: DisplaySafeUrl) -> Vec { + fn mirror_urls(self, canonical_url: DisplaySafeUrl) -> Result, Error> { + let custom_astral_mirror = astral_mirror_url_from_env(); + self.mirror_urls_with_astral_mirror(canonical_url, custom_astral_mirror.as_deref()) + } + + fn mirror_urls_with_astral_mirror( + self, + canonical_url: DisplaySafeUrl, + astral_mirror_url: Option<&str>, + ) -> Result, Error> { + let astral_mirror_url = custom_astral_mirror_url(astral_mirror_url); match self { Self::Ruff => { if let Some(suffix) = canonical_url.as_str().strip_prefix(RUFF_GITHUB_URL_PREFIX) { - let mirror_str = format!("{RUFF_DEFAULT_MIRROR}{suffix}"); - if let Ok(mirror_url) = DisplaySafeUrl::parse(&mirror_str) { - return vec![mirror_url, canonical_url]; + let mirror_base = astral_mirror_base_url(astral_mirror_url); + let mirror = format!("{mirror_base}{RUFF_MIRROR_SUFFIX}{suffix}"); + let mirror_url = parse_url(mirror)?; + if astral_mirror_url.is_some() { + return Ok(vec![mirror_url]); } + return Ok(vec![mirror_url, canonical_url]); } - vec![canonical_url] + Ok(vec![canonical_url]) } - Self::Uv => vec![canonical_url], + Self::Uv => Ok(vec![canonical_url]), } } @@ -223,17 +251,18 @@ const RUFF_GITHUB_URL_PREFIX: &str = "https://github.com/astral-sh/ruff/releases /// The canonical GitHub URL prefix for uv releases. const UV_GITHUB_URL_PREFIX: &str = "https://github.com/astral-sh/uv/releases/download/"; -/// The default Astral mirror for Ruff releases. -/// -/// This mirror is tried first for Ruff downloads. If it fails, uv falls back to the canonical -/// GitHub URL. -const RUFF_DEFAULT_MIRROR: &str = "https://releases.astral.sh/github/ruff/releases/download/"; +/// The suffix appended to the Astral mirror base for Ruff releases. +const RUFF_MIRROR_SUFFIX: &str = "/github/ruff/releases/download/"; + +/// The suffix appended to the Astral mirror base for the versions manifest. +const VERSIONS_MANIFEST_MIRROR_SUFFIX: &str = "/github/versions/main/v1"; /// The canonical base URL for the versions manifest. const VERSIONS_MANIFEST_URL: &str = "https://raw.githubusercontent.com/astral-sh/versions/main/v1"; -/// The default Astral mirror for the versions manifest. -const VERSIONS_MANIFEST_MIRROR: &str = "https://releases.astral.sh/github/versions/main/v1"; +fn parse_url(url: String) -> Result { + DisplaySafeUrl::parse(&url).map_err(|source| Error::UrlParse { url, source }) +} /// Binary version information from the versions manifest. #[derive(Debug, Deserialize)] @@ -452,8 +481,10 @@ pub async fn find_matching_version( let platform = Platform::from_env()?; let platform_name = platform.as_cargo_dist_triple(); + let manifest_urls = binary.manifest_urls()?; + fetch_with_url_fallback( - &binary.manifest_urls(), + &manifest_urls, *retry_policy, &format!("manifest for `{binary}`"), |url| { @@ -506,13 +537,13 @@ async fn fetch_and_find_matching_version( return Ok(None); } let version_info: BinVersionInfo = serde_json::from_str(line_str)?; - Ok(check_version_match( + check_version_match( binary, &version_info, constraints, exclude_newer, platform_name, - )) + ) }; // Stream the response line by line @@ -559,27 +590,27 @@ async fn fetch_and_find_matching_version( /// Check if a version matches the constraints and find the artifact for the platform. /// -/// Returns `Some(resolved)` if the version matches and an artifact is found, -/// `None` if the version doesn't match or no artifact is available for the platform. +/// Returns `Ok(Some(resolved))` if the version matches and an artifact is found, +/// `Ok(None)` if the version doesn't match or no artifact is available for the platform. fn check_version_match( binary: Binary, version_info: &BinVersionInfo, constraints: Option<&uv_pep440::VersionSpecifiers>, exclude_newer: Option, platform_name: &str, -) -> Option { +) -> Result, Error> { // Skip versions newer than the exclude_newer cutoff if let Some(cutoff) = exclude_newer && version_info.date > cutoff { - return None; + return Ok(None); } // Skip versions that don't match the constraints if let Some(constraints) = constraints && !constraints.contains(&version_info.version) { - return None; + return Ok(None); } // Find an artifact matching the platform, trusting whichever archive format the @@ -599,14 +630,14 @@ fn check_version_match( _ => continue, }; - return Some(ResolvedVersion { + return Ok(Some(ResolvedVersion { version: version_info.version.clone(), - artifact_urls: binary.mirror_urls(canonical_url), + artifact_urls: binary.mirror_urls(canonical_url)?, archive_format, - }); + })); } - None + Ok(None) } /// Install the given binary from a [`ResolvedVersion`]. @@ -954,6 +985,129 @@ mod tests { ); } + #[test] + fn test_ruff_download_urls_custom_astral_mirror() { + let urls = Binary::Ruff + .download_urls_with_astral_mirror( + &Version::new([0, 15, 1]), + "x86_64-unknown-linux-gnu", + ArchiveFormat::TarGz, + Some("https://nexus.example.com/repository/releases.astral.sh/"), + ) + .expect("ruff download URLs should be valid"); + + let urls = urls + .into_iter() + .map(|url| url.to_string()) + .collect::>(); + assert_eq!( + urls, + vec![ + "https://nexus.example.com/repository/releases.astral.sh/github/ruff/releases/download/0.15.1/ruff-x86_64-unknown-linux-gnu.tar.gz" + .to_string(), + ] + ); + } + + #[test] + fn test_ruff_download_urls_empty_astral_mirror_uses_default() { + let default_urls = Binary::Ruff + .download_urls_with_astral_mirror( + &Version::new([0, 15, 1]), + "x86_64-unknown-linux-gnu", + ArchiveFormat::TarGz, + None, + ) + .expect("ruff download URLs should be valid"); + let empty_urls = Binary::Ruff + .download_urls_with_astral_mirror( + &Version::new([0, 15, 1]), + "x86_64-unknown-linux-gnu", + ArchiveFormat::TarGz, + Some(""), + ) + .expect("ruff download URLs should be valid"); + + assert_eq!(default_urls, empty_urls); + } + + #[test] + fn test_manifest_urls_custom_astral_mirror() { + for (binary, filename) in [(Binary::Ruff, "ruff.ndjson"), (Binary::Uv, "uv.ndjson")] { + let urls = binary + .manifest_urls_with_astral_mirror(Some( + "https://nexus.example.com/repository/releases.astral.sh/", + )) + .expect("manifest URLs should be valid"); + + let urls = urls + .into_iter() + .map(|url| url.to_string()) + .collect::>(); + assert_eq!( + urls, + vec![format!( + "https://nexus.example.com/repository/releases.astral.sh/github/versions/main/v1/{filename}" + )] + ); + } + } + + #[test] + fn test_ruff_mirror_urls_custom_astral_mirror() { + let canonical_url = DisplaySafeUrl::parse( + "https://github.com/astral-sh/ruff/releases/download/0.15.1/ruff-x86_64-unknown-linux-gnu.tar.gz", + ) + .unwrap(); + let urls = Binary::Ruff + .mirror_urls_with_astral_mirror( + canonical_url, + Some("https://nexus.example.com/repository/releases.astral.sh/"), + ) + .expect("mirror URLs should be valid"); + + let urls = urls + .into_iter() + .map(|url| url.to_string()) + .collect::>(); + assert_eq!( + urls, + vec![ + "https://nexus.example.com/repository/releases.astral.sh/github/ruff/releases/download/0.15.1/ruff-x86_64-unknown-linux-gnu.tar.gz" + .to_string(), + ] + ); + } + + #[test] + fn test_manifest_urls_empty_astral_mirror_uses_default() { + for binary in [Binary::Ruff, Binary::Uv] { + let default_urls = binary + .manifest_urls_with_astral_mirror(None) + .expect("manifest URLs should be valid"); + let empty_urls = binary + .manifest_urls_with_astral_mirror(Some("")) + .expect("manifest URLs should be valid"); + assert_eq!(default_urls, empty_urls); + } + } + + #[test] + fn test_ruff_mirror_urls_empty_astral_mirror_uses_default() { + let canonical_url = DisplaySafeUrl::parse( + "https://github.com/astral-sh/ruff/releases/download/0.15.1/ruff-x86_64-unknown-linux-gnu.tar.gz", + ) + .unwrap(); + let default_urls = Binary::Ruff + .mirror_urls_with_astral_mirror(canonical_url.clone(), None) + .expect("mirror URLs should be valid"); + let empty_urls = Binary::Ruff + .mirror_urls_with_astral_mirror(canonical_url, Some("")) + .expect("mirror URLs should be valid"); + + assert_eq!(default_urls, empty_urls); + } + #[tokio::test] async fn test_manifest_falls_back_on_404() { let platform = Platform::from_env().unwrap(); diff --git a/crates/uv-python/src/downloads.rs b/crates/uv-python/src/downloads.rs index 79da28da6927d..a899063716781 100644 --- a/crates/uv-python/src/downloads.rs +++ b/crates/uv-python/src/downloads.rs @@ -31,7 +31,9 @@ use uv_fs::{Simplified, rename_with_retry}; use uv_platform::{self as platform, Arch, Libc, Os, Platform}; use uv_pypi_types::{HashAlgorithm, HashDigest}; use uv_redacted::{DisplaySafeUrl, DisplaySafeUrlError}; -use uv_static::EnvVars; +use uv_static::{ + EnvVars, astral_mirror_base_url, astral_mirror_url_from_env, custom_astral_mirror_url, +}; use crate::PythonVariant; use crate::implementation::{ @@ -185,12 +187,16 @@ impl RetriableError for Error { const CPYTHON_DOWNLOADS_URL_PREFIX: &str = "https://github.com/astral-sh/python-build-standalone/releases/download/"; -/// The default Astral mirror for `python-build-standalone` releases. -/// -/// This mirror is tried first for CPython downloads when no user-configured mirror is set. -/// If the mirror fails, uv falls back to the canonical GitHub URL. -const CPYTHON_DOWNLOAD_DEFAULT_MIRROR: &str = - "https://releases.astral.sh/github/python-build-standalone/releases/download/"; +/// The suffix appended to the Astral mirror base for `python-build-standalone` releases. +const CPYTHON_MIRROR_SUFFIX: &str = "/github/python-build-standalone/releases/download/"; + +/// Return the Astral mirror base URL for CPython downloads. +fn effective_cpython_mirror(astral_mirror_url: Option<&str>) -> String { + format!( + "{}{CPYTHON_MIRROR_SUFFIX}", + astral_mirror_base_url(astral_mirror_url) + ) +} #[derive(Debug, PartialEq, Eq, Clone, Hash)] pub struct ManagedPythonDownload { @@ -1523,6 +1529,21 @@ impl ManagedPythonDownload { python_install_mirror: Option<&str>, pypy_install_mirror: Option<&str>, ) -> Result, Error> { + let custom_astral_mirror = astral_mirror_url_from_env(); + self.download_urls_with_astral_mirror( + python_install_mirror, + pypy_install_mirror, + custom_astral_mirror.as_deref(), + ) + } + + fn download_urls_with_astral_mirror( + &self, + python_install_mirror: Option<&str>, + pypy_install_mirror: Option<&str>, + astral_mirror_url: Option<&str>, + ) -> Result, Error> { + let astral_mirror_url = custom_astral_mirror_url(astral_mirror_url); match self.key.implementation { LenientImplementationName::Known(ImplementationName::CPython) => { if let Some(mirror) = python_install_mirror { @@ -1537,16 +1558,17 @@ impl ManagedPythonDownload { format!("{}/{}", mirror.trim_end_matches('/'), suffix).as_str(), )?]); } - // No user mirror: try the default Astral mirror first, fall back to GitHub. + // No user mirror: try the default/custom Astral mirror first. if let Some(suffix) = self.url.strip_prefix(CPYTHON_DOWNLOADS_URL_PREFIX) { + let effective_mirror = effective_cpython_mirror(astral_mirror_url); let mirror_url = DisplaySafeUrl::parse( - format!( - "{}/{}", - CPYTHON_DOWNLOAD_DEFAULT_MIRROR.trim_end_matches('/'), - suffix - ) - .as_str(), + format!("{}/{}", effective_mirror.trim_end_matches('/'), suffix).as_str(), )?; + // When a custom Astral mirror is set, use it exclusively. + if astral_mirror_url.is_some() { + return Ok(vec![mirror_url]); + } + // Otherwise fall back to the canonical GitHub URL. let canonical_url = DisplaySafeUrl::parse(&self.url)?; return Ok(vec![mirror_url, canonical_url]); } @@ -2275,6 +2297,97 @@ mod tests { ); } + fn cpython_download_for_url(url: &'static str) -> ManagedPythonDownload { + let key = PythonInstallationKey::new( + LenientImplementationName::Known(crate::implementation::ImplementationName::CPython), + 3, + 12, + 4, + None, + Platform::new( + Os::from_str("linux").unwrap(), + Arch::from_str("x86_64").unwrap(), + Libc::from_str("gnu").unwrap(), + ), + crate::PythonVariant::default(), + ); + + ManagedPythonDownload { + key, + url: Cow::Borrowed(url), + sha256: Some(Cow::Borrowed("abc123")), + build: Some("20240713"), + } + } + + #[test] + fn test_cpython_download_urls_custom_astral_mirror() { + let download = cpython_download_for_url( + "https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-x86_64-unknown-linux-gnu-install_only.tar.gz", + ); + + let urls = download + .download_urls_with_astral_mirror( + None, + None, + Some("https://nexus.example.com/repository/releases.astral.sh/"), + ) + .expect("download URLs should be valid"); + let urls = urls + .into_iter() + .map(|url| url.to_string()) + .collect::>(); + assert_eq!( + urls, + vec![ + "https://nexus.example.com/repository/releases.astral.sh/github/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-x86_64-unknown-linux-gnu-install_only.tar.gz" + .to_string(), + ] + ); + } + + #[test] + fn test_cpython_specific_mirror_takes_precedence_over_astral_mirror() { + let download = cpython_download_for_url( + "https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-x86_64-unknown-linux-gnu-install_only.tar.gz", + ); + + let urls = download + .download_urls_with_astral_mirror( + Some("https://python-mirror.example.com/releases/"), + None, + Some("https://nexus.example.com/repository/releases.astral.sh/"), + ) + .expect("download URLs should be valid"); + let urls = urls + .into_iter() + .map(|url| url.to_string()) + .collect::>(); + assert_eq!( + urls, + vec![ + "https://python-mirror.example.com/releases/20240713/cpython-3.12.4%2B20240713-x86_64-unknown-linux-gnu-install_only.tar.gz" + .to_string(), + ] + ); + } + + #[test] + fn test_cpython_download_urls_empty_astral_mirror_uses_default() { + let download = cpython_download_for_url( + "https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-x86_64-unknown-linux-gnu-install_only.tar.gz", + ); + + let default_urls = download + .download_urls_with_astral_mirror(None, None, None) + .expect("download URLs should be valid"); + let empty_urls = download + .download_urls_with_astral_mirror(None, None, Some("")) + .expect("download URLs should be valid"); + + assert_eq!(default_urls, empty_urls); + } + /// Test build display #[test] fn test_managed_python_download_build_display() { diff --git a/crates/uv-static/src/env_vars.rs b/crates/uv-static/src/env_vars.rs index 4bf0a8e75e532..93f2beb4f3e76 100644 --- a/crates/uv-static/src/env_vars.rs +++ b/crates/uv-static/src/env_vars.rs @@ -452,6 +452,9 @@ impl EnvVars { /// The provided URL will replace `https://github.com/astral-sh/python-build-standalone/releases/download` in, e.g., /// `https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-aarch64-apple-darwin-install_only.tar.gz`. /// Distributions can be read from a local directory by using the `file://` URL scheme. + /// + /// This more-specific mirror takes precedence over + /// [`UV_ASTRAL_MIRROR_URL`](Self::UV_ASTRAL_MIRROR_URL) for CPython downloads. #[attr_added_in("0.2.35")] pub const UV_PYTHON_INSTALL_MIRROR: &'static str = "UV_PYTHON_INSTALL_MIRROR"; @@ -465,6 +468,26 @@ impl EnvVars { #[attr_added_in("0.2.35")] pub const UV_PYPY_INSTALL_MIRROR: &'static str = "UV_PYPY_INSTALL_MIRROR"; + /// Replaces the `https://releases.astral.sh` base URL for all Astral-mirrored + /// metadata and artifact downloads. + /// + /// When set, uv uses only the configured mirror URL and does not fall back to + /// GitHub or raw GitHub. Path components in the URL are preserved: only + /// trailing slashes are trimmed before appending the normal path suffix + /// (e.g., `/github/versions/main/v1/uv.ndjson`). + /// + /// This is useful for proxy repositories (e.g., Artifactory, Nexus) that + /// mirror `releases.astral.sh`. + /// + /// More-specific sources take precedence: + /// [`UV_PYTHON_INSTALL_MIRROR`](Self::UV_PYTHON_INSTALL_MIRROR) and + /// `python-install-mirror` override this variable for CPython downloads, while + /// [`UV_INSTALLER_GITHUB_BASE_URL`](Self::UV_INSTALLER_GITHUB_BASE_URL) and + /// [`UV_INSTALLER_GHE_BASE_URL`](Self::UV_INSTALLER_GHE_BASE_URL) override this + /// variable for `uv self update`. + #[attr_added_in("next release")] + pub const UV_ASTRAL_MIRROR_URL: &'static str = "UV_ASTRAL_MIRROR_URL"; + /// Pin managed CPython versions to a specific build version. /// /// For CPython, this should be the build date (e.g., "20250814"). @@ -1209,11 +1232,17 @@ impl EnvVars { /// The URL from which to download uv using the standalone installer and `self update` feature, /// in lieu of the default GitHub URL. + /// + /// This more-specific installer source takes precedence over + /// [`UV_ASTRAL_MIRROR_URL`](Self::UV_ASTRAL_MIRROR_URL) for `uv self update`. #[attr_added_in("0.5.0")] pub const UV_INSTALLER_GITHUB_BASE_URL: &'static str = "UV_INSTALLER_GITHUB_BASE_URL"; /// The URL from which to download uv using the standalone installer and `self update` feature, /// in lieu of the default GitHub Enterprise URL. + /// + /// This more-specific installer source takes precedence over + /// [`UV_ASTRAL_MIRROR_URL`](Self::UV_ASTRAL_MIRROR_URL) for `uv self update`. #[attr_added_in("0.5.0")] pub const UV_INSTALLER_GHE_BASE_URL: &'static str = "UV_INSTALLER_GHE_BASE_URL"; diff --git a/crates/uv-static/src/lib.rs b/crates/uv-static/src/lib.rs index 2a347d4c732a7..3710b799e6f22 100644 --- a/crates/uv-static/src/lib.rs +++ b/crates/uv-static/src/lib.rs @@ -2,8 +2,36 @@ pub use env_vars::*; mod env_vars; +use std::borrow::Cow; + use thiserror::Error; +/// The base URL for the default Astral mirror. +pub const ASTRAL_MIRROR_BASE_URL: &str = "https://releases.astral.sh"; + +/// Read the user-configured Astral mirror URL from the environment, if set. +pub fn astral_mirror_url_from_env() -> Option { + std::env::var_os(EnvVars::UV_ASTRAL_MIRROR_URL).and_then(|url| { + if url.as_os_str().is_empty() { + None + } else { + Some(url.to_string_lossy().into_owned()) + } + }) +} + +/// Return the effective Astral mirror base URL, using the default mirror when unset. +pub fn astral_mirror_base_url(astral_mirror_url: Option<&str>) -> Cow<'_, str> { + custom_astral_mirror_url(astral_mirror_url) + .map(|url| Cow::Owned(url.trim_end_matches('/').to_string())) + .unwrap_or(Cow::Borrowed(ASTRAL_MIRROR_BASE_URL)) +} + +/// Return a user-configured Astral mirror URL, treating empty values as unset. +pub fn custom_astral_mirror_url(astral_mirror_url: Option<&str>) -> Option<&str> { + astral_mirror_url.filter(|url| !url.is_empty()) +} + #[derive(Debug, Error)] #[error("Failed to parse environment variable `{name}` with invalid value `{value}`: {err}")] pub struct InvalidEnvironmentVariable { diff --git a/crates/uv/src/commands/self_update.rs b/crates/uv/src/commands/self_update.rs index 998b26ee551e4..565b499e8dcff 100644 --- a/crates/uv/src/commands/self_update.rs +++ b/crates/uv/src/commands/self_update.rs @@ -20,15 +20,42 @@ use uv_client::{BaseClientBuilder, RetriableError, WrappedReqwestError, fetch_wi use uv_fs::Simplified; use uv_pep440::{Version as Pep440Version, VersionSpecifier, VersionSpecifiers}; use uv_redacted::DisplaySafeUrl; -use uv_static::EnvVars; +use uv_static::{ + EnvVars, astral_mirror_base_url, astral_mirror_url_from_env, custom_astral_mirror_url, +}; use crate::commands::ExitStatus; use crate::printer::Printer; const UV_GITHUB_RELEASES_DOWNLOAD_PREFIX: &str = "https://github.com/astral-sh/uv/releases/download/"; -const UV_MIRROR_RELEASES_DOWNLOAD_PREFIX: &str = - "https://releases.astral.sh/github/uv/releases/download/"; + +/// The suffix appended to the Astral mirror base for uv release downloads. +const UV_MIRROR_SUFFIX: &str = "/github/uv/releases/download/"; + +/// Return the effective Astral mirror prefix for uv release downloads. +fn effective_uv_mirror_prefix(astral_mirror_url: Option<&str>) -> String { + format!( + "{}{UV_MIRROR_SUFFIX}", + astral_mirror_base_url(astral_mirror_url) + ) +} + +/// Return the `UV_DOWNLOAD_URL` value for the standalone installer when a custom Astral mirror is +/// configured. +fn installer_download_url( + target_version: &Pep440Version, + astral_mirror_url: Option<&str>, +) -> Option { + let mirror = custom_astral_mirror_url(astral_mirror_url)?; + Some(format!( + "{}{}{}", + mirror.trim_end_matches('/'), + UV_MIRROR_SUFFIX, + target_version + )) +} + const AXOUPDATER_CONFIG_PATH: &str = "AXOUPDATER_CONFIG_PATH"; const AXOUPDATER_CONFIG_WORKING_DIR: &str = "AXOUPDATER_CONFIG_WORKING_DIR"; @@ -318,7 +345,9 @@ async fn run_official_updater( client_builder: BaseClientBuilder<'_>, github_token: Option<&str>, ) -> Result { - let installer_urls = official_installer_urls(target_version)?; + let custom_astral_mirror = astral_mirror_url_from_env(); + let installer_urls = + official_installer_urls_with_mirror(target_version, custom_astral_mirror.as_deref())?; let temp_dir = TempDir::new()?; let installer_path = temp_dir.path().join(installer_filename()); let install_prefix = PathBuf::from(updater.install_prefix_root()?.as_str()); @@ -335,7 +364,14 @@ async fn run_official_updater( ) .await?; - execute_official_installer(&installer_path, &install_prefix, modify_path).await?; + execute_official_installer( + &installer_path, + &install_prefix, + modify_path, + target_version, + custom_astral_mirror.as_deref(), + ) + .await?; let direction = if current_version > target_version { "Downgraded" @@ -368,19 +404,31 @@ fn installer_filename() -> &'static str { } /// Build the mirror-first URL list for the official standalone installer. -fn official_installer_urls(version: &Pep440Version) -> Result> { +fn official_installer_urls_with_mirror( + version: &Pep440Version, + astral_mirror_url: Option<&str>, +) -> Result> { + let astral_mirror_url = custom_astral_mirror_url(astral_mirror_url); let filename = installer_filename(); - let mirror = format!("{UV_MIRROR_RELEASES_DOWNLOAD_PREFIX}{version}/{filename}"); - let canonical = format!("{UV_GITHUB_RELEASES_DOWNLOAD_PREFIX}{version}/{filename}"); + let mirror_prefix = effective_uv_mirror_prefix(astral_mirror_url); + let mirror = format!("{mirror_prefix}{version}/{filename}"); - Ok(vec![ + let mut urls = vec![ DisplaySafeUrl::parse(&mirror).with_context(|| format!("Failed to parse `{mirror}`"))?, - DisplaySafeUrl::parse(&canonical) - .with_context(|| format!("Failed to parse `{canonical}`"))?, - ]) + ]; + + // When using the default mirror, also fall back to the canonical GitHub URL. + if astral_mirror_url.is_none() { + let canonical = format!("{UV_GITHUB_RELEASES_DOWNLOAD_PREFIX}{version}/{filename}"); + urls.push( + DisplaySafeUrl::parse(&canonical) + .with_context(|| format!("Failed to parse `{canonical}`"))?, + ); + } + Ok(urls) } -/// Download the official installer from the mirror first, then fall back to GitHub. +/// Download the official installer from the provided mirror/canonical URL list. async fn download_installer_from_urls( urls: &[DisplaySafeUrl], installer_path: &Path, @@ -459,10 +507,16 @@ fn installer_download_github_token<'a>( /// Execute the standalone installer while preserving the existing install location and PATH /// behavior. +/// +/// When [`UV_ASTRAL_MIRROR_URL`](EnvVars::UV_ASTRAL_MIRROR_URL) is set, the installer is also +/// given `UV_DOWNLOAD_URL` pointing at the mirror's uv release directory so the installer itself +/// fetches the uv archive from the mirror. async fn execute_official_installer( installer_path: &Path, install_prefix: &Path, modify_path: bool, + target_version: &Pep440Version, + astral_mirror_url: Option<&str>, ) -> Result<(), AxoupdateError> { let mut command = if cfg!(windows) { let mut command = Command::new("powershell"); @@ -487,6 +541,11 @@ async fn execute_official_installer( command.env_remove(EnvVars::PS_MODULE_PATH); command.env("CARGO_DIST_FORCE_INSTALL_DIR", install_prefix); command.env(EnvVars::UV_INSTALL_DIR, install_prefix); + // When a custom Astral mirror is configured, point the installer at the mirrored + // uv release directory so it downloads the archive from the mirror too. + if let Some(download_url) = installer_download_url(target_version, astral_mirror_url) { + command.env(EnvVars::UV_DOWNLOAD_URL, download_url); + } if !modify_path { let app_name_env_var = app_name_to_env_var("uv"); command.env(format!("{app_name_env_var}_NO_MODIFY_PATH"), "1"); @@ -929,7 +988,7 @@ mod tests { #[test] fn test_official_installer_urls() { - let urls = official_installer_urls(&Pep440Version::new([1, 2, 3])) + let urls = official_installer_urls_with_mirror(&Pep440Version::new([1, 2, 3]), None) .unwrap() .into_iter() .map(|url| url.to_string()) @@ -949,6 +1008,56 @@ mod tests { ); } + #[test] + fn test_official_installer_urls_custom_astral_mirror() { + let urls = official_installer_urls_with_mirror( + &Pep440Version::new([1, 2, 3]), + Some("https://nexus.example.com/repository/releases.astral.sh/"), + ) + .unwrap() + .into_iter() + .map(|url| url.to_string()) + .collect::>(); + assert_eq!( + urls, + vec![format!( + "https://nexus.example.com/repository/releases.astral.sh/github/uv/releases/download/1.2.3/{}", + installer_filename() + )] + ); + } + + #[test] + fn test_official_installer_urls_empty_astral_mirror_uses_default() { + let default_urls = + official_installer_urls_with_mirror(&Pep440Version::new([1, 2, 3]), None).unwrap(); + let empty_urls = + official_installer_urls_with_mirror(&Pep440Version::new([1, 2, 3]), Some("")).unwrap(); + assert_eq!(default_urls, empty_urls); + } + + #[test] + fn test_installer_download_url_custom_astral_mirror() { + assert_eq!( + installer_download_url( + &Pep440Version::new([1, 2, 3]), + Some("https://nexus.example.com/repository/releases.astral.sh/") + ) + .as_deref(), + Some( + "https://nexus.example.com/repository/releases.astral.sh/github/uv/releases/download/1.2.3" + ) + ); + } + + #[test] + fn test_installer_download_url_empty_astral_mirror_uses_default() { + assert_eq!( + installer_download_url(&Pep440Version::new([1, 2, 3]), Some("")), + None + ); + } + #[test] fn test_installer_download_github_token() { let mirror = DisplaySafeUrl::parse( @@ -1053,9 +1162,15 @@ mod tests { .unwrap(); fs_err::set_permissions(&installer_path, std::fs::Permissions::from_mode(0o744)).unwrap(); - let err = execute_official_installer(&installer_path, &install_prefix, true) - .await - .expect_err("failing installer should return an error"); + let err = execute_official_installer( + &installer_path, + &install_prefix, + true, + &Pep440Version::new([1, 2, 3]), + None, + ) + .await + .expect_err("failing installer should return an error"); let AxoupdateError::InstallFailed { status, stdout, @@ -1090,9 +1205,15 @@ mod tests { .unwrap(); fs_err::set_permissions(&installer_path, std::fs::Permissions::from_mode(0o744)).unwrap(); - execute_official_installer(&installer_path, &install_prefix, false) - .await - .unwrap(); + execute_official_installer( + &installer_path, + &install_prefix, + false, + &Pep440Version::new([1, 2, 3]), + None, + ) + .await + .unwrap(); assert_eq!( fs_err::read_to_string(&output_path).unwrap(), @@ -1104,6 +1225,42 @@ mod tests { ); } + #[cfg(unix)] + #[tokio::test] + async fn test_execute_official_installer_sets_download_url_for_astral_mirror() { + use std::os::unix::fs::PermissionsExt; + + let temp_dir = TempDir::new().unwrap(); + let output_path = temp_dir.path().join("env.txt"); + let installer_path = temp_dir.path().join("installer.sh"); + let install_prefix = temp_dir.path().join("install-prefix"); + + fs_err::write( + &installer_path, + format!( + "#!/bin/sh\nset -eu\n{{\nprintf 'UV_DOWNLOAD_URL=%s\\n' \"${{UV_DOWNLOAD_URL-}}\"\n}} > \"{}\"\n", + output_path.display() + ), + ) + .unwrap(); + fs_err::set_permissions(&installer_path, std::fs::Permissions::from_mode(0o744)).unwrap(); + + execute_official_installer( + &installer_path, + &install_prefix, + true, + &Pep440Version::new([1, 2, 3]), + Some("https://nexus.example.com/repository/releases.astral.sh/"), + ) + .await + .unwrap(); + + assert_eq!( + fs_err::read_to_string(&output_path).unwrap(), + "UV_DOWNLOAD_URL=https://nexus.example.com/repository/releases.astral.sh/github/uv/releases/download/1.2.3\n" + ); + } + #[cfg(unix)] #[tokio::test] async fn test_execute_official_installer_preserves_modify_path_default() { @@ -1124,9 +1281,15 @@ mod tests { .unwrap(); fs_err::set_permissions(&installer_path, std::fs::Permissions::from_mode(0o744)).unwrap(); - execute_official_installer(&installer_path, &install_prefix, true) - .await - .unwrap(); + execute_official_installer( + &installer_path, + &install_prefix, + true, + &Pep440Version::new([1, 2, 3]), + None, + ) + .await + .unwrap(); assert_eq!( fs_err::read_to_string(&output_path).unwrap(), From 601c2b80421544fc0f18bedd2d141308e8acbfd1 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 12 May 2026 12:10:24 -0400 Subject: [PATCH 14/16] Respect build options (e.g., `--no-build`) during lock validation (#19366) ## Summary Right now, `--no-build` et al are ignored during lockfile validation. This PR wires them up, and improves lockfile validation to reuse static metadata in one case that was surfaced by the change. --- crates/uv-distribution/src/error.rs | 2 + crates/uv-distribution/src/source/mod.rs | 16 ++ crates/uv-resolver/src/lock/mod.rs | 264 +++++++++++++++-------- crates/uv/src/commands/project/lock.rs | 7 +- crates/uv/tests/it/lock.rs | 4 +- crates/uv/tests/it/pip_install.rs | 30 +++ crates/uv/tests/it/sync.rs | 62 ++++++ 7 files changed, 290 insertions(+), 95 deletions(-) diff --git a/crates/uv-distribution/src/error.rs b/crates/uv-distribution/src/error.rs index b9f85c98929ea..5e9b265cfd642 100644 --- a/crates/uv-distribution/src/error.rs +++ b/crates/uv-distribution/src/error.rs @@ -37,6 +37,8 @@ impl fmt::Display for PythonVersion { pub enum Error { #[error("Building source distributions is disabled")] NoBuild, + #[error("Building source distributions for `{0}` is disabled")] + NoBuildPackage(PackageName), // Network error #[error(transparent)] diff --git a/crates/uv-distribution/src/source/mod.rs b/crates/uv-distribution/src/source/mod.rs index 49d9da75edd00..80df8bac38a86 100644 --- a/crates/uv-distribution/src/source/mod.rs +++ b/crates/uv-distribution/src/source/mod.rs @@ -2616,6 +2616,22 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { ) -> Result, Error> { debug!("Preparing metadata for: {source}"); + let source_name = source.name(); + if self + .build_context + .build_options() + .no_build_requirement(source_name) + // Editable requirements without a known name need metadata to apply + // package-specific build settings; named editables must respect `--no-build`. + && !(source_name.is_none() && source.is_editable()) + { + return if let Some(name) = source_name { + Err(Error::NoBuildPackage(name.clone())) + } else { + Err(Error::NoBuild) + }; + } + // Ensure that the _installed_ Python version is compatible with the `requires-python` // specifier. if let Some(requires_python) = source.requires_python() { diff --git a/crates/uv-resolver/src/lock/mod.rs b/crates/uv-resolver/src/lock/mod.rs index aa138a9ad3143..893e75074e946 100644 --- a/crates/uv-resolver/src/lock/mod.rs +++ b/crates/uv-resolver/src/lock/mod.rs @@ -23,7 +23,7 @@ use uv_configuration::{ BuildOptions, Constraints, DependencyGroupsWithDefaults, ExtrasSpecificationWithDefaults, InstallTarget, }; -use uv_distribution::{DistributionDatabase, FlatRequiresDist}; +use uv_distribution::{DistributionDatabase, FlatRequiresDist, RequiresDist}; use uv_distribution_filename::{ BuildTag, DistExtension, ExtensionError, SourceDistExtension, WheelFilename, }; @@ -1627,6 +1627,7 @@ impl Lock { indexes: Option<&IndexLocations>, tags: &Tags, markers: &MarkerEnvironment, + build_options: &BuildOptions, hasher: &HashStrategy, index: &InMemoryIndex, database: &DistributionDatabase<'_, Context>, @@ -1986,84 +1987,135 @@ impl Lock { } if let Some(version) = package.id.version.as_ref() { - // For a non-dynamic package, fetch the metadata from the distribution database. - let HashedDist { dist, .. } = package.to_dist( - root, - TagPolicy::Preferred(tags), - &BuildOptions::default(), - markers, - )?; - - let metadata = { - let id = dist.distribution_id(); - if let Some(archive) = - index - .distributions() - .get(&id) - .as_deref() - .and_then(|response| { - if let MetadataResponse::Found(archive, ..) = response { - Some(archive) - } else { - None - } - }) - { - // If the metadata is already in the index, return it. - archive.metadata.clone() - } else { - // Run the PEP 517 build process to extract metadata from the source distribution. - let archive = database - .get_or_build_wheel_metadata(&dist, hasher.get(&dist)) - .await - .map_err(|err| LockErrorKind::Resolution { - id: package.id.clone(), - err, - })?; + // If the distribution is a source tree, attempt to validate it from statically + // available `pyproject.toml` metadata before converting it to an installable + // distribution. This avoids requiring build permission for static local packages. + let statically_satisfied = if let Some(source_tree) = + package.id.source.as_source_tree() + && let Some(SourceTreeRequiresDist { + version: static_version, + metadata, + }) = Self::source_tree_requires_dist(source_tree, root, package, database) + .await? + { + // If this local package has become dynamic, the locked package should + // no longer contain a version. + if metadata.dynamic { + return Ok(SatisfiesResult::MismatchedDynamic(&package.id.name, false)); + } - let metadata = archive.metadata.clone(); + if let Some(static_version) = static_version { + // Validate the static `version` metadata. + if static_version != *version { + return Ok(SatisfiesResult::MismatchedVersion( + &package.id.name, + version.clone(), + Some(static_version), + )); + } - // Insert the metadata into the index. - index - .distributions() - .done(id, Arc::new(MetadataResponse::Found(archive))); + // Validate the static `provides-extras` metadata. + match self.satisfies_provides_extra(metadata.provides_extra, package) { + SatisfiesResult::Satisfied => {} + result => return Ok(result), + } - metadata + // Validate that the static requirements are unchanged. + match self.satisfies_requires_dist( + metadata.requires_dist, + metadata.dependency_groups, + package, + root, + )? { + SatisfiesResult::Satisfied => true, + result => return Ok(result), + } + } else { + false } + } else { + false }; - // If this is a local package, validate that it hasn't become dynamic (in which - // case, we'd expect the version to be omitted). - if package.id.source.is_source_tree() { - if metadata.dynamic { + if !statically_satisfied { + // For a non-dynamic package without usable static metadata, fetch the metadata + // from the distribution database. + let HashedDist { dist, .. } = package.to_dist( + root, + TagPolicy::Preferred(tags), + build_options, + markers, + )?; + + let metadata = { + let id = dist.distribution_id(); + if let Some(archive) = + index + .distributions() + .get(&id) + .as_deref() + .and_then(|response| { + if let MetadataResponse::Found(archive, ..) = response { + Some(archive) + } else { + None + } + }) + { + // If the metadata is already in the index, return it. + archive.metadata.clone() + } else { + // Run the PEP 517 build process to extract metadata from the source distribution. + let archive = database + .get_or_build_wheel_metadata(&dist, hasher.get(&dist)) + .await + .map_err(|err| LockErrorKind::Resolution { + id: package.id.clone(), + err, + })?; + + let metadata = archive.metadata.clone(); + + // Insert the metadata into the index. + index + .distributions() + .done(id, Arc::new(MetadataResponse::Found(archive))); + + metadata + } + }; + + // If this is a local package, validate that it hasn't become dynamic (in which + // case, we'd expect the version to be omitted). + if package.id.source.is_source_tree() && metadata.dynamic { return Ok(SatisfiesResult::MismatchedDynamic(&package.id.name, false)); } - } - // Validate the `version` metadata. - if metadata.version != *version { - return Ok(SatisfiesResult::MismatchedVersion( - &package.id.name, - version.clone(), - Some(metadata.version.clone()), - )); - } + // Validate the `version` metadata. + if metadata.version != *version { + return Ok(SatisfiesResult::MismatchedVersion( + &package.id.name, + version.clone(), + Some(metadata.version.clone()), + )); + } - // Validate the `provides-extras` metadata. - match self.satisfies_provides_extra(metadata.provides_extra, package) { - SatisfiesResult::Satisfied => {} - result => return Ok(result), - } + // Validate the `provides-extras` metadata. + match self.satisfies_provides_extra(metadata.provides_extra, package) { + SatisfiesResult::Satisfied => {} + result => return Ok(result), + } - // Validate that the requirements are unchanged. - match self.satisfies_requires_dist( - metadata.requires_dist, - metadata.dependency_groups, - package, - root, - )? { - SatisfiesResult::Satisfied => {} - result => return Ok(result), + // Validate that the requirements are unchanged. + match self.satisfies_requires_dist( + metadata.requires_dist, + metadata.dependency_groups, + package, + root, + )? { + SatisfiesResult::Satisfied => {} + result => return Ok(result), + } } } else if let Some(source_tree) = package.id.source.as_source_tree() { // For dynamic packages, we don't need the version. We only need to know that the @@ -2075,30 +2127,10 @@ impl Lock { // even if the version is dynamic, we can still extract the requirements without // performing a build, unlike in the database where we typically construct a "complete" // metadata object. - let parent = root.join(source_tree); - let path = parent.join("pyproject.toml"); - let metadata = match fs_err::tokio::read_to_string(&path).await { - Ok(contents) => { - let pyproject_toml = - PyProjectToml::from_toml(&contents, path.user_display()).map_err( - |err| LockErrorKind::InvalidPyprojectToml { - path: path.clone(), - err, - }, - )?; - database - .requires_dist(&parent, &pyproject_toml) - .await - .map_err(|err| LockErrorKind::Resolution { - id: package.id.clone(), - err, - })? - } - Err(err) if err.kind() == io::ErrorKind::NotFound => None, - Err(err) => { - return Err(LockErrorKind::UnreadablePyprojectToml { path, err }.into()); - } - }; + let metadata = + Self::source_tree_requires_dist(source_tree, root, package, database) + .await? + .map(|metadata| metadata.metadata); let satisfied = metadata.is_some_and(|metadata| { // Validate that the package is still dynamic. @@ -2142,7 +2174,7 @@ impl Lock { let HashedDist { dist, .. } = package.to_dist( root, TagPolicy::Preferred(tags), - &BuildOptions::default(), + build_options, markers, )?; @@ -2274,6 +2306,39 @@ impl Lock { Ok(SatisfiesResult::Satisfied) } + + async fn source_tree_requires_dist( + source_tree: &Path, + root: &Path, + package: &Package, + database: &DistributionDatabase<'_, Context>, + ) -> Result, LockError> { + let parent = root.join(source_tree); + let path = parent.join("pyproject.toml"); + match fs_err::tokio::read_to_string(&path).await { + Ok(contents) => { + let pyproject_toml = PyProjectToml::from_toml(&contents, path.user_display()) + .map_err(|err| LockErrorKind::InvalidPyprojectToml { + path: path.clone(), + err, + })?; + let version = pyproject_toml + .project + .as_ref() + .and_then(|project| project.version.clone()); + let metadata = database + .requires_dist(&parent, &pyproject_toml) + .await + .map_err(|err| LockErrorKind::Resolution { + id: package.id.clone(), + err, + })?; + Ok(metadata.map(|metadata| SourceTreeRequiresDist { version, metadata })) + } + Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(None), + Err(err) => Err(LockErrorKind::UnreadablePyprojectToml { path, err }.into()), + } + } } /// The set of lockfile packages that should be audited, materialized from a @@ -2289,6 +2354,11 @@ pub struct Auditable<'lock> { packages: Vec<(&'lock Package, &'lock Version)>, } +struct SourceTreeRequiresDist { + version: Option, + metadata: RequiresDist, +} + impl<'lock> Auditable<'lock> { /// Return the number of distinct `(name, version)` pairs to audit. pub fn len(&self) -> usize { @@ -5644,6 +5714,14 @@ impl LockError { pub fn is_resolution(&self) -> bool { matches!(&*self.kind, LockErrorKind::Resolution { .. }) } + + /// Returns true if the [`LockError`] is caused by disabled builds. + pub fn is_no_build(&self) -> bool { + matches!( + &*self.kind, + LockErrorKind::NoBuild { .. } | LockErrorKind::NoBinaryNoBuild { .. } + ) + } } impl From for LockError diff --git a/crates/uv/src/commands/project/lock.rs b/crates/uv/src/commands/project/lock.rs index 35f40c5ac0cb0..344b072d5b81e 100644 --- a/crates/uv/src/commands/project/lock.rs +++ b/crates/uv/src/commands/project/lock.rs @@ -853,9 +853,13 @@ async fn do_lock( .await { Ok(result) => Some(result), - Err(ProjectError::Lock(err)) if err.is_resolution() => { + Err(ProjectError::Lock(err)) if err.is_resolution() || err.is_no_build() => { // Resolver errors are not recoverable, as such errors can leave the resolver in a // broken state. Specifically, tasks that fail with an error can be left as pending. + // + // Disabled builds are user policy errors. Static local projects are validated + // before this point, so reaching this case means validation genuinely needs + // metadata that cannot be obtained under `--no-build`. return Err(ProjectError::Lock(err)); } Err(err) => { @@ -1259,6 +1263,7 @@ impl ValidatedLock { indexes, interpreter.tags()?, interpreter.markers(), + &options.build_options, hasher, index, database, diff --git a/crates/uv/tests/it/lock.rs b/crates/uv/tests/it/lock.rs index 8c97df3acb7b2..3850490f5cddd 100644 --- a/crates/uv/tests/it/lock.rs +++ b/crates/uv/tests/it/lock.rs @@ -19981,11 +19981,13 @@ fn lock_explicit_default_index() -> Result<()> { DEBUG Checking for Python environment at: `.venv` DEBUG The project environment's Python version satisfies the request: `Python >=3.12` DEBUG Using request connect timeout of [TIME] and read timeout of [TIME] - DEBUG Found static `pyproject.toml` for: project @ file://[TEMP_DIR]/ + DEBUG Found static `requires-dist` for: [TEMP_DIR]/ DEBUG No workspace root found, using project root DEBUG Resolving despite existing lockfile due to mismatched requirements for: `project==0.1.0` Requested: {Requirement { name: PackageName("anyio"), extras: [], groups: [], marker: true, source: Registry { specifier: VersionSpecifiers([]), index: None, conflict: None }, origin: None }} Existing: {Requirement { name: PackageName("iniconfig"), extras: [], groups: [], marker: true, source: Registry { specifier: VersionSpecifiers([VersionSpecifier { operator: Equal, version: "2.0.0" }]), index: Some(IndexMetadata { url: Url(VerbatimUrl { url: DisplaySafeUrl { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("test.pypi.org")), port: None, path: "/simple", query: None, fragment: None }, given: None, expanded: false }), format: Simple }), conflict: None }, origin: None }} + DEBUG Found static `pyproject.toml` for: project @ file://[TEMP_DIR]/ + DEBUG No workspace root found, using project root DEBUG Solving with installed Python version: 3.12.[X] DEBUG Solving with target Python version: >=3.12 DEBUG Solving with exclude-newer: global: 2024-03-25T00:00:00Z diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs index 65312fdbc369c..9ac05a06d8165 100644 --- a/crates/uv/tests/it/pip_install.rs +++ b/crates/uv/tests/it/pip_install.rs @@ -1996,6 +1996,36 @@ fn install_editable_bare_cli() { ); } +#[test] +fn install_editable_unnamed_no_build() -> Result<()> { + let context = uv_test::test_context!("3.12"); + + let editable_dir = context.temp_dir.child("editable"); + editable_dir.child("setup.py").write_str(indoc! {r#" + from setuptools import setup + + setup(name="example", version="0.1.0") + "#})?; + + uv_snapshot!(context.filters(), context.pip_install() + .arg("--no-build") + .arg("-e") + .arg("editable"), @" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 1 package in [TIME] + Prepared 1 package in [TIME] + Installed 1 package in [TIME] + + example==0.1.0 (from file://[TEMP_DIR]/editable) + " + ); + + Ok(()) +} + #[test] fn install_editable_bare_requirements_txt() -> Result<()> { let context = uv_test::test_context!("3.12"); diff --git a/crates/uv/tests/it/sync.rs b/crates/uv/tests/it/sync.rs index fd524a6992bc6..a9bbc519bffd7 100644 --- a/crates/uv/tests/it/sync.rs +++ b/crates/uv/tests/it/sync.rs @@ -6116,6 +6116,68 @@ fn no_install_project_no_build() -> Result<()> { Ok(()) } +/// Ensure that lock validation respects `--no-build` when the project itself won't be installed. +#[test] +fn no_install_project_no_build_locked_dynamic_metadata() -> Result<()> { + let context = uv_test::test_context!("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str(indoc! {r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dynamic = ["dependencies"] + + [build-system] + requires = [] + backend-path = ["."] + build-backend = "build_backend" + "#})?; + + let build_backend = context.temp_dir.child("build_backend.py"); + build_backend.write_str(indoc! {r#" + import pathlib + + def prepare_metadata_for_build_editable(metadata_directory, config_settings=None): + pathlib.Path("validation-hook-called").write_text("called") + dist_info = pathlib.Path(metadata_directory, "project-0.1.0.dist-info") + dist_info.mkdir() + dist_info.joinpath("METADATA").write_text( + "Metadata-Version: 2.1\n" + "Name: project\n" + "Version: 0.1.0\n" + "Requires-Dist: anyio==3.7.0\n" + ) + return dist_info.name + "#})?; + + // Generate a lockfile, then remove the cached metadata so validation would need to invoke the + // build backend again if it ignored `--no-build`. + context.lock().assert().success(); + + let marker = context.temp_dir.child("validation-hook-called"); + assert!(marker.exists()); + fs_err::remove_file(marker.path())?; + fs_err::remove_dir_all(&context.cache_dir)?; + + uv_snapshot!(context.filters(), context.sync() + .arg("--no-install-project") + .arg("--no-build") + .arg("--locked"), @" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Distribution `project==0.1.0 @ editable+.` can't be installed because it is marked as `--no-build` but has no binary distribution + "); + + assert!(!marker.exists()); + + Ok(()) +} + #[test] fn sync_extra_build_dependencies_script() -> Result<()> { let context = uv_test::test_context!("3.12").with_filtered_counts(); From 634b03f972330183295adae438ec90e76105593e Mon Sep 17 00:00:00 2001 From: Zsolt Dollenstein Date: Tue, 12 May 2026 09:15:08 -0700 Subject: [PATCH 15/16] Document `uv auth helper` for Bazel credential helper use (#19358) --- docs/concepts/authentication/cli.md | 57 +++++++++++++++++++++++++++++ docs/concepts/preview.md | 1 + 2 files changed, 58 insertions(+) diff --git a/docs/concepts/authentication/cli.md b/docs/concepts/authentication/cli.md index fd35b2e7bab08..2a8d85661d0c4 100644 --- a/docs/concepts/authentication/cli.md +++ b/docs/concepts/authentication/cli.md @@ -61,6 +61,63 @@ If a username was used to log in, it will need to be provided as well, e.g.: $ uv auth token --username foo example.com ``` +## Using credentials with external tools + +`uv auth helper` allows tools that support credential helpers to request HTTP credentials from uv. +At this time, uv supports the +[Bazel credential helper protocol](https://github.com/bazelbuild/proposals/blob/main/designs/2022-06-07-bazel-credential-helpers.md). + +The command is intended to be invoked by external tools. It reads a JSON request from stdin and +writes a JSON response to stdout. When matching credentials are available, the response includes the +`Authorization` header: + +```console +$ echo '{"uri": "https://example.com/path"}' | uv --preview-features auth-helper auth helper --protocol=bazel get +{"headers":{"Authorization":["Basic ..."]}} +``` + +If no credentials are found, uv will return an empty set of headers: + +```json +{ "headers": {} } +``` + +!!! note + + `uv auth helper` is experimental. Use `--preview-features auth-helper` or + `UV_PREVIEW_FEATURES=auth-helper` to disable the warning. + +### Bazel + +Bazel 7 and newer supports credential helpers via the `--credential_helper` option. First, +authenticate uv with the service that hosts the files Bazel needs to fetch: + +```console +$ uv auth login https://packages.example.com +``` + +Then, configure Bazel to invoke uv for matching hosts: + +```text title=".bazelrc" +common --credential_helper=packages.example.com=%workspace%/bazel/uv-auth-helper +common --credential_helper=files.example.com=%workspace%/bazel/uv-auth-helper +``` + +Replace the host patterns with the hosts that serve the index and files Bazel will fetch. + +Finally, add the wrapper script referenced by `.bazelrc`: + +```bash title="bazel/uv-auth-helper" +#!/usr/bin/env bash +exec uv --preview-features auth-helper auth helper --protocol=bazel "$@" +``` + +The script must be executable: + +```console +$ chmod +x bazel/uv-auth-helper +``` + ## Configuring the storage backend Credentials are persisted to the uv [credentials store](./http.md#the-uv-credentials-store). diff --git a/docs/concepts/preview.md b/docs/concepts/preview.md index b5b23fd4bb777..46c7eb99cc24f 100644 --- a/docs/concepts/preview.md +++ b/docs/concepts/preview.md @@ -66,6 +66,7 @@ The following preview features are available: - `index-exclude-newer`: Allows setting `exclude-newer` on configured package indexes. - `native-auth`: Enables storage of credentials in a [system-native location](../concepts/authentication/http.md#the-uv-credentials-store). +- `auth-helper`: Allows using `uv auth helper` as a credential helper for external tools. - `workspace-metadata`: Allows using `uv workspace metadata`. - `workspace-dir`: Allows using `uv workspace dir`. - `workspace-list`: Allows using `uv workspace list`. From 3fdfdc7d4a63c9f283eb751823b7628b13116684 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 12:29:37 -0500 Subject: [PATCH 16/16] Bump version to 0.11.14 (#19377) Co-authored-by: github-actions[bot] Co-authored-by: Zanie Blue --- CHANGELOG.md | 18 +++ Cargo.lock | 134 +++++++++--------- Cargo.toml | 126 ++++++++-------- crates/uv-audit/Cargo.toml | 2 +- crates/uv-audit/README.md | 4 +- crates/uv-auth/Cargo.toml | 2 +- crates/uv-auth/README.md | 4 +- crates/uv-bench/Cargo.toml | 2 +- crates/uv-bench/README.md | 4 +- crates/uv-bin-install/Cargo.toml | 2 +- crates/uv-bin-install/README.md | 4 +- crates/uv-build-backend/Cargo.toml | 2 +- crates/uv-build-backend/README.md | 4 +- crates/uv-build-frontend/Cargo.toml | 2 +- crates/uv-build-frontend/README.md | 4 +- crates/uv-build/Cargo.toml | 2 +- crates/uv-build/pyproject.toml | 2 +- crates/uv-cache-info/Cargo.toml | 2 +- crates/uv-cache-info/README.md | 4 +- crates/uv-cache-key/Cargo.toml | 2 +- crates/uv-cache-key/README.md | 4 +- crates/uv-cache/Cargo.toml | 2 +- crates/uv-cache/README.md | 4 +- crates/uv-cli/Cargo.toml | 2 +- crates/uv-cli/README.md | 4 +- crates/uv-client/Cargo.toml | 2 +- crates/uv-client/README.md | 4 +- crates/uv-configuration/Cargo.toml | 2 +- crates/uv-configuration/README.md | 4 +- crates/uv-console/Cargo.toml | 2 +- crates/uv-console/README.md | 4 +- crates/uv-dev/Cargo.toml | 2 +- crates/uv-dev/README.md | 4 +- crates/uv-dirs/Cargo.toml | 2 +- crates/uv-dirs/README.md | 4 +- crates/uv-dispatch/Cargo.toml | 2 +- crates/uv-dispatch/README.md | 4 +- crates/uv-distribution-filename/Cargo.toml | 2 +- crates/uv-distribution-filename/README.md | 4 +- crates/uv-distribution-types/Cargo.toml | 2 +- crates/uv-distribution-types/README.md | 4 +- crates/uv-distribution/Cargo.toml | 2 +- crates/uv-distribution/README.md | 4 +- crates/uv-extract/Cargo.toml | 2 +- crates/uv-extract/README.md | 4 +- crates/uv-fastid/Cargo.toml | 2 +- crates/uv-fastid/README.md | 4 +- crates/uv-flags/Cargo.toml | 2 +- crates/uv-flags/README.md | 4 +- crates/uv-fs/Cargo.toml | 2 +- crates/uv-fs/README.md | 4 +- crates/uv-git-types/Cargo.toml | 2 +- crates/uv-git-types/README.md | 4 +- crates/uv-git/Cargo.toml | 2 +- crates/uv-git/README.md | 4 +- crates/uv-globfilter/Cargo.toml | 2 +- crates/uv-install-wheel/Cargo.toml | 2 +- crates/uv-install-wheel/README.md | 4 +- crates/uv-installer/Cargo.toml | 2 +- crates/uv-installer/README.md | 4 +- crates/uv-keyring/Cargo.toml | 2 +- crates/uv-logging/Cargo.toml | 2 +- crates/uv-logging/README.md | 4 +- crates/uv-macros/Cargo.toml | 2 +- crates/uv-macros/README.md | 4 +- crates/uv-metadata/Cargo.toml | 2 +- crates/uv-metadata/README.md | 4 +- crates/uv-normalize/Cargo.toml | 2 +- crates/uv-normalize/README.md | 4 +- crates/uv-once-map/Cargo.toml | 2 +- crates/uv-once-map/README.md | 4 +- crates/uv-options-metadata/Cargo.toml | 2 +- crates/uv-options-metadata/README.md | 4 +- crates/uv-pep440/Cargo.toml | 2 +- crates/uv-pep440/README.md | 4 +- crates/uv-pep508/Cargo.toml | 2 +- crates/uv-pep508/README.md | 4 +- .../Cargo.toml | 2 +- .../uv-performance-memory-allocator/README.md | 4 +- crates/uv-platform-tags/Cargo.toml | 2 +- crates/uv-platform-tags/README.md | 4 +- crates/uv-platform/Cargo.toml | 2 +- crates/uv-platform/README.md | 4 +- crates/uv-preview/Cargo.toml | 2 +- crates/uv-preview/README.md | 4 +- crates/uv-publish/Cargo.toml | 2 +- crates/uv-publish/README.md | 4 +- crates/uv-pypi-types/Cargo.toml | 2 +- crates/uv-pypi-types/README.md | 4 +- crates/uv-python/Cargo.toml | 2 +- crates/uv-python/README.md | 4 +- crates/uv-redacted/Cargo.toml | 2 +- crates/uv-redacted/README.md | 4 +- crates/uv-requirements-txt/Cargo.toml | 2 +- crates/uv-requirements-txt/README.md | 4 +- crates/uv-requirements/Cargo.toml | 2 +- crates/uv-requirements/README.md | 4 +- crates/uv-resolver/Cargo.toml | 2 +- crates/uv-resolver/README.md | 4 +- crates/uv-scripts/Cargo.toml | 2 +- crates/uv-scripts/README.md | 4 +- crates/uv-settings/Cargo.toml | 2 +- crates/uv-settings/README.md | 4 +- crates/uv-shell/Cargo.toml | 2 +- crates/uv-shell/README.md | 4 +- crates/uv-small-str/Cargo.toml | 2 +- crates/uv-small-str/README.md | 4 +- crates/uv-state/Cargo.toml | 2 +- crates/uv-state/README.md | 4 +- crates/uv-static/Cargo.toml | 2 +- crates/uv-static/README.md | 4 +- crates/uv-static/src/env_vars.rs | 2 +- crates/uv-test/Cargo.toml | 2 +- crates/uv-test/README.md | 4 +- crates/uv-tool/Cargo.toml | 2 +- crates/uv-tool/README.md | 4 +- crates/uv-torch/Cargo.toml | 2 +- crates/uv-torch/README.md | 4 +- crates/uv-trampoline-builder/Cargo.toml | 2 +- crates/uv-trampoline-builder/README.md | 4 +- crates/uv-trampoline/Cargo.lock | 6 +- crates/uv-types/Cargo.toml | 2 +- crates/uv-types/README.md | 4 +- crates/uv-unix/Cargo.toml | 2 +- crates/uv-unix/README.md | 4 +- crates/uv-version/Cargo.toml | 2 +- crates/uv-version/README.md | 4 +- crates/uv-virtualenv/Cargo.toml | 2 +- crates/uv-warnings/Cargo.toml | 2 +- crates/uv-warnings/README.md | 4 +- crates/uv-windows/Cargo.toml | 2 +- crates/uv-windows/README.md | 4 +- crates/uv-workspace/Cargo.toml | 2 +- crates/uv-workspace/README.md | 4 +- crates/uv/Cargo.toml | 2 +- crates/uv/README.md | 4 +- docs/concepts/build-backend.md | 2 +- docs/concepts/projects/init.md | 6 +- docs/concepts/projects/workspaces.md | 6 +- docs/getting-started/installation.md | 4 +- docs/guides/integration/aws-lambda.md | 4 +- docs/guides/integration/docker.md | 10 +- docs/guides/integration/github.md | 2 +- docs/guides/integration/gitlab.md | 2 +- docs/guides/integration/pre-commit.md | 10 +- pyproject.toml | 2 +- uv.lock | 2 +- 147 files changed, 371 insertions(+), 353 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0e0c21392e30..204770206f648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,22 @@ +## 0.11.14 + +Released on 2026-05-12. + +### Enhancements + +- Add Astral mirror URL override ([#19206](https://github.com/astral-sh/uv/pull/19206)) +- Ignore `top_level.txt` entries in uninstall that are not valid Python identifiers ([#19340](https://github.com/astral-sh/uv/pull/19340)) + +### Bug fixes + +- Avoid applying `.env` files in parent process ([#19343](https://github.com/astral-sh/uv/pull/19343)) +- Filter ANSI codes in logging output ([#19311](https://github.com/astral-sh/uv/pull/19311)) +- Fix `uv tree` showing extra-conditional deps for packages required without extras ([#19332](https://github.com/astral-sh/uv/pull/19332)) +- Respect build options (e.g., `--no-build`) during lock validation ([#19366](https://github.com/astral-sh/uv/pull/19366)) + ## 0.11.13 Released on 2026-05-10. @@ -13,6 +29,8 @@ Released on 2026-05-10. - Respect `--require-hashes` when installing from `pylock.toml` files ([#19334](https://github.com/astral-sh/uv/pull/19334)) ### Python +### Python + - Add CPython 3.14.5 ## 0.11.12 diff --git a/Cargo.lock b/Cargo.lock index ce48fa8cbe7ba..2f1d639b5fd82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5743,7 +5743,7 @@ dependencies = [ [[package]] name = "uv" -version = "0.11.13" +version = "0.11.14" dependencies = [ "anstream", "anyhow", @@ -5868,7 +5868,7 @@ dependencies = [ [[package]] name = "uv-audit" -version = "0.0.46" +version = "0.0.47" dependencies = [ "astral-reqwest-middleware", "clap", @@ -5896,7 +5896,7 @@ dependencies = [ [[package]] name = "uv-auth" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "arcstr", @@ -5939,7 +5939,7 @@ dependencies = [ [[package]] name = "uv-bench" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "codspeed-criterion-compat", @@ -5966,7 +5966,7 @@ dependencies = [ [[package]] name = "uv-bin-install" -version = "0.0.46" +version = "0.0.47" dependencies = [ "astral-reqwest-middleware", "astral-reqwest-retry", @@ -5994,7 +5994,7 @@ dependencies = [ [[package]] name = "uv-build" -version = "0.11.13" +version = "0.11.14" dependencies = [ "anstream", "anyhow", @@ -6009,7 +6009,7 @@ dependencies = [ [[package]] name = "uv-build-backend" -version = "0.0.46" +version = "0.0.47" dependencies = [ "astral-version-ranges", "base64 0.22.1", @@ -6052,7 +6052,7 @@ dependencies = [ [[package]] name = "uv-build-frontend" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anstream", "fs-err", @@ -6089,7 +6089,7 @@ dependencies = [ [[package]] name = "uv-cache" -version = "0.0.46" +version = "0.0.47" dependencies = [ "clap", "fs-err", @@ -6115,7 +6115,7 @@ dependencies = [ [[package]] name = "uv-cache-info" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "fs-err", @@ -6132,7 +6132,7 @@ dependencies = [ [[package]] name = "uv-cache-key" -version = "0.0.46" +version = "0.0.47" dependencies = [ "hex", "memchr", @@ -6144,7 +6144,7 @@ dependencies = [ [[package]] name = "uv-cli" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anstream", "anyhow", @@ -6177,7 +6177,7 @@ dependencies = [ [[package]] name = "uv-client" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "astral-reqwest-middleware", @@ -6247,7 +6247,7 @@ dependencies = [ [[package]] name = "uv-configuration" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "clap", @@ -6281,14 +6281,14 @@ dependencies = [ [[package]] name = "uv-console" -version = "0.0.46" +version = "0.0.47" dependencies = [ "console", ] [[package]] name = "uv-dev" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anstream", "anyhow", @@ -6337,7 +6337,7 @@ dependencies = [ [[package]] name = "uv-dirs" -version = "0.0.46" +version = "0.0.47" dependencies = [ "assert_fs", "etcetera", @@ -6349,7 +6349,7 @@ dependencies = [ [[package]] name = "uv-dispatch" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "futures", @@ -6382,7 +6382,7 @@ dependencies = [ [[package]] name = "uv-distribution" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "astral-reqwest-middleware", @@ -6434,7 +6434,7 @@ dependencies = [ [[package]] name = "uv-distribution-filename" -version = "0.0.46" +version = "0.0.47" dependencies = [ "insta", "memchr", @@ -6451,7 +6451,7 @@ dependencies = [ [[package]] name = "uv-distribution-types" -version = "0.0.46" +version = "0.0.47" dependencies = [ "arcstr", "astral-version-ranges", @@ -6491,7 +6491,7 @@ dependencies = [ [[package]] name = "uv-extract" -version = "0.0.46" +version = "0.0.47" dependencies = [ "astral-tokio-tar", "astral_async_zip", @@ -6520,7 +6520,7 @@ dependencies = [ [[package]] name = "uv-fastid" -version = "0.0.46" +version = "0.0.47" dependencies = [ "fastrand", "rand 0.9.4", @@ -6530,14 +6530,14 @@ dependencies = [ [[package]] name = "uv-flags" -version = "0.0.46" +version = "0.0.47" dependencies = [ "bitflags 2.11.1", ] [[package]] name = "uv-fs" -version = "0.0.46" +version = "0.0.47" dependencies = [ "backon", "clap", @@ -6567,7 +6567,7 @@ dependencies = [ [[package]] name = "uv-git" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "astral-reqwest-middleware", @@ -6592,7 +6592,7 @@ dependencies = [ [[package]] name = "uv-git-types" -version = "0.0.46" +version = "0.0.47" dependencies = [ "percent-encoding", "serde", @@ -6606,7 +6606,7 @@ dependencies = [ [[package]] name = "uv-globfilter" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anstream", "fs-err", @@ -6623,7 +6623,7 @@ dependencies = [ [[package]] name = "uv-install-wheel" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "assert_fs", @@ -6660,7 +6660,7 @@ dependencies = [ [[package]] name = "uv-installer" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anstream", "anyhow", @@ -6703,7 +6703,7 @@ dependencies = [ [[package]] name = "uv-keyring" -version = "0.0.46" +version = "0.0.47" dependencies = [ "async-trait", "byteorder", @@ -6719,7 +6719,7 @@ dependencies = [ [[package]] name = "uv-logging" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anstream", "jiff", @@ -6730,7 +6730,7 @@ dependencies = [ [[package]] name = "uv-macros" -version = "0.0.46" +version = "0.0.47" dependencies = [ "proc-macro2", "quote", @@ -6740,7 +6740,7 @@ dependencies = [ [[package]] name = "uv-metadata" -version = "0.0.46" +version = "0.0.47" dependencies = [ "astral_async_zip", "fs-err", @@ -6757,7 +6757,7 @@ dependencies = [ [[package]] name = "uv-normalize" -version = "0.0.46" +version = "0.0.47" dependencies = [ "rkyv", "schemars", @@ -6767,7 +6767,7 @@ dependencies = [ [[package]] name = "uv-once-map" -version = "0.0.46" +version = "0.0.47" dependencies = [ "dashmap", "futures", @@ -6776,14 +6776,14 @@ dependencies = [ [[package]] name = "uv-options-metadata" -version = "0.0.46" +version = "0.0.47" dependencies = [ "serde", ] [[package]] name = "uv-pep440" -version = "0.0.46" +version = "0.0.47" dependencies = [ "astral-version-ranges", "indoc", @@ -6797,7 +6797,7 @@ dependencies = [ [[package]] name = "uv-pep508" -version = "0.0.46" +version = "0.0.47" dependencies = [ "arcstr", "astral-version-ranges", @@ -6827,7 +6827,7 @@ dependencies = [ [[package]] name = "uv-performance-memory-allocator" -version = "0.0.46" +version = "0.0.47" dependencies = [ "mimalloc", "tikv-jemallocator", @@ -6835,7 +6835,7 @@ dependencies = [ [[package]] name = "uv-platform" -version = "0.0.46" +version = "0.0.47" dependencies = [ "fs-err", "goblin", @@ -6856,7 +6856,7 @@ dependencies = [ [[package]] name = "uv-platform-tags" -version = "0.0.46" +version = "0.0.47" dependencies = [ "bitflags 2.11.1", "insta", @@ -6870,7 +6870,7 @@ dependencies = [ [[package]] name = "uv-preview" -version = "0.0.46" +version = "0.0.47" dependencies = [ "enumflags2", "itertools 0.14.0", @@ -6881,7 +6881,7 @@ dependencies = [ [[package]] name = "uv-publish" -version = "0.0.46" +version = "0.0.47" dependencies = [ "ambient-id", "anstream", @@ -6923,7 +6923,7 @@ dependencies = [ [[package]] name = "uv-pypi-types" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "hashbrown 0.17.0", @@ -6956,7 +6956,7 @@ dependencies = [ [[package]] name = "uv-python" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "assert_fs", @@ -7018,7 +7018,7 @@ dependencies = [ [[package]] name = "uv-redacted" -version = "0.0.46" +version = "0.0.47" dependencies = [ "ref-cast", "schemars", @@ -7029,7 +7029,7 @@ dependencies = [ [[package]] name = "uv-requirements" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "configparser", @@ -7063,7 +7063,7 @@ dependencies = [ [[package]] name = "uv-requirements-txt" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "assert_fs", @@ -7096,7 +7096,7 @@ dependencies = [ [[package]] name = "uv-resolver" -version = "0.0.46" +version = "0.0.47" dependencies = [ "arcstr", "astral-pubgrub", @@ -7162,7 +7162,7 @@ dependencies = [ [[package]] name = "uv-scripts" -version = "0.0.46" +version = "0.0.47" dependencies = [ "fs-err", "indoc", @@ -7187,7 +7187,7 @@ dependencies = [ [[package]] name = "uv-settings" -version = "0.0.46" +version = "0.0.47" dependencies = [ "clap", "fs-err", @@ -7224,7 +7224,7 @@ dependencies = [ [[package]] name = "uv-shell" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "fs-err", @@ -7241,7 +7241,7 @@ dependencies = [ [[package]] name = "uv-small-str" -version = "0.0.46" +version = "0.0.47" dependencies = [ "arcstr", "rkyv", @@ -7251,7 +7251,7 @@ dependencies = [ [[package]] name = "uv-state" -version = "0.0.46" +version = "0.0.47" dependencies = [ "fs-err", "tempfile", @@ -7260,7 +7260,7 @@ dependencies = [ [[package]] name = "uv-static" -version = "0.0.46" +version = "0.0.47" dependencies = [ "thiserror 2.0.18", "uv-macros", @@ -7268,7 +7268,7 @@ dependencies = [ [[package]] name = "uv-test" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "assert_cmd", @@ -7298,7 +7298,7 @@ dependencies = [ [[package]] name = "uv-tool" -version = "0.0.46" +version = "0.0.47" dependencies = [ "fs-err", "owo-colors", @@ -7327,7 +7327,7 @@ dependencies = [ [[package]] name = "uv-torch" -version = "0.0.46" +version = "0.0.47" dependencies = [ "clap", "either", @@ -7347,7 +7347,7 @@ dependencies = [ [[package]] name = "uv-trampoline-builder" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "assert_cmd", @@ -7365,7 +7365,7 @@ dependencies = [ [[package]] name = "uv-types" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "dashmap", @@ -7387,7 +7387,7 @@ dependencies = [ [[package]] name = "uv-unix" -version = "0.0.46" +version = "0.0.47" dependencies = [ "nix 0.31.2", "thiserror 2.0.18", @@ -7395,11 +7395,11 @@ dependencies = [ [[package]] name = "uv-version" -version = "0.11.13" +version = "0.11.14" [[package]] name = "uv-virtualenv" -version = "0.0.46" +version = "0.0.47" dependencies = [ "console", "fs-err", @@ -7420,7 +7420,7 @@ dependencies = [ [[package]] name = "uv-warnings" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anstream", "anyhow", @@ -7432,7 +7432,7 @@ dependencies = [ [[package]] name = "uv-windows" -version = "0.0.46" +version = "0.0.47" dependencies = [ "arrayvec", "windows", @@ -7440,7 +7440,7 @@ dependencies = [ [[package]] name = "uv-workspace" -version = "0.0.46" +version = "0.0.47" dependencies = [ "anyhow", "assert_fs", diff --git a/Cargo.toml b/Cargo.toml index d68b7fda0c42f..e639af0c61184 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,78 +16,78 @@ authors = ["uv"] license = "MIT OR Apache-2.0" [workspace.dependencies] -uv-audit = { version = "0.0.46", path = "crates/uv-audit" } -uv-auth = { version = "0.0.46", path = "crates/uv-auth" } -uv-bin-install = { version = "0.0.46", path = "crates/uv-bin-install" } -uv-build-backend = { version = "0.0.46", path = "crates/uv-build-backend" } -uv-build-frontend = { version = "0.0.46", path = "crates/uv-build-frontend" } -uv-cache = { version = "0.0.46", path = "crates/uv-cache" } -uv-cache-info = { version = "0.0.46", path = "crates/uv-cache-info" } -uv-cache-key = { version = "0.0.46", path = "crates/uv-cache-key" } -uv-cli = { version = "0.0.46", path = "crates/uv-cli" } -uv-client = { version = "0.0.46", path = "crates/uv-client" } -uv-configuration = { version = "0.0.46", path = "crates/uv-configuration" } -uv-console = { version = "0.0.46", path = "crates/uv-console" } -uv-dirs = { version = "0.0.46", path = "crates/uv-dirs" } -uv-dispatch = { version = "0.0.46", path = "crates/uv-dispatch" } -uv-distribution = { version = "0.0.46", path = "crates/uv-distribution" } -uv-distribution-filename = { version = "0.0.46", path = "crates/uv-distribution-filename" } -uv-distribution-types = { version = "0.0.46", path = "crates/uv-distribution-types" } -uv-extract = { version = "0.0.46", path = "crates/uv-extract" } -uv-fastid = { version = "0.0.46", path = "crates/uv-fastid" } -uv-flags = { version = "0.0.46", path = "crates/uv-flags" } -uv-fs = { version = "0.0.46", path = "crates/uv-fs", features = [ +uv-audit = { version = "0.0.47", path = "crates/uv-audit" } +uv-auth = { version = "0.0.47", path = "crates/uv-auth" } +uv-bin-install = { version = "0.0.47", path = "crates/uv-bin-install" } +uv-build-backend = { version = "0.0.47", path = "crates/uv-build-backend" } +uv-build-frontend = { version = "0.0.47", path = "crates/uv-build-frontend" } +uv-cache = { version = "0.0.47", path = "crates/uv-cache" } +uv-cache-info = { version = "0.0.47", path = "crates/uv-cache-info" } +uv-cache-key = { version = "0.0.47", path = "crates/uv-cache-key" } +uv-cli = { version = "0.0.47", path = "crates/uv-cli" } +uv-client = { version = "0.0.47", path = "crates/uv-client" } +uv-configuration = { version = "0.0.47", path = "crates/uv-configuration" } +uv-console = { version = "0.0.47", path = "crates/uv-console" } +uv-dirs = { version = "0.0.47", path = "crates/uv-dirs" } +uv-dispatch = { version = "0.0.47", path = "crates/uv-dispatch" } +uv-distribution = { version = "0.0.47", path = "crates/uv-distribution" } +uv-distribution-filename = { version = "0.0.47", path = "crates/uv-distribution-filename" } +uv-distribution-types = { version = "0.0.47", path = "crates/uv-distribution-types" } +uv-extract = { version = "0.0.47", path = "crates/uv-extract" } +uv-fastid = { version = "0.0.47", path = "crates/uv-fastid" } +uv-flags = { version = "0.0.47", path = "crates/uv-flags" } +uv-fs = { version = "0.0.47", path = "crates/uv-fs", features = [ "serde", "tokio", ] } -uv-git = { version = "0.0.46", path = "crates/uv-git" } -uv-git-types = { version = "0.0.46", path = "crates/uv-git-types" } -uv-globfilter = { version = "0.0.46", path = "crates/uv-globfilter" } -uv-install-wheel = { version = "0.0.46", path = "crates/uv-install-wheel", default-features = false } -uv-installer = { version = "0.0.46", path = "crates/uv-installer" } -uv-keyring = { version = "0.0.46", path = "crates/uv-keyring" } -uv-logging = { version = "0.0.46", path = "crates/uv-logging" } -uv-macros = { version = "0.0.46", path = "crates/uv-macros" } -uv-metadata = { version = "0.0.46", path = "crates/uv-metadata" } -uv-normalize = { version = "0.0.46", path = "crates/uv-normalize" } -uv-once-map = { version = "0.0.46", path = "crates/uv-once-map" } -uv-options-metadata = { version = "0.0.46", path = "crates/uv-options-metadata" } -uv-performance-memory-allocator = { version = "0.0.46", path = "crates/uv-performance-memory-allocator" } -uv-pep440 = { version = "0.0.46", path = "crates/uv-pep440", features = [ +uv-git = { version = "0.0.47", path = "crates/uv-git" } +uv-git-types = { version = "0.0.47", path = "crates/uv-git-types" } +uv-globfilter = { version = "0.0.47", path = "crates/uv-globfilter" } +uv-install-wheel = { version = "0.0.47", path = "crates/uv-install-wheel", default-features = false } +uv-installer = { version = "0.0.47", path = "crates/uv-installer" } +uv-keyring = { version = "0.0.47", path = "crates/uv-keyring" } +uv-logging = { version = "0.0.47", path = "crates/uv-logging" } +uv-macros = { version = "0.0.47", path = "crates/uv-macros" } +uv-metadata = { version = "0.0.47", path = "crates/uv-metadata" } +uv-normalize = { version = "0.0.47", path = "crates/uv-normalize" } +uv-once-map = { version = "0.0.47", path = "crates/uv-once-map" } +uv-options-metadata = { version = "0.0.47", path = "crates/uv-options-metadata" } +uv-performance-memory-allocator = { version = "0.0.47", path = "crates/uv-performance-memory-allocator" } +uv-pep440 = { version = "0.0.47", path = "crates/uv-pep440", features = [ "tracing", "rkyv", "version-ranges", ] } -uv-pep508 = { version = "0.0.46", path = "crates/uv-pep508", features = [ +uv-pep508 = { version = "0.0.47", path = "crates/uv-pep508", features = [ "non-pep508-extensions", ] } -uv-platform = { version = "0.0.46", path = "crates/uv-platform" } -uv-platform-tags = { version = "0.0.46", path = "crates/uv-platform-tags" } -uv-preview = { version = "0.0.46", path = "crates/uv-preview" } -uv-publish = { version = "0.0.46", path = "crates/uv-publish" } -uv-pypi-types = { version = "0.0.46", path = "crates/uv-pypi-types" } -uv-python = { version = "0.0.46", path = "crates/uv-python" } -uv-redacted = { version = "0.0.46", path = "crates/uv-redacted" } -uv-requirements = { version = "0.0.46", path = "crates/uv-requirements" } -uv-requirements-txt = { version = "0.0.46", path = "crates/uv-requirements-txt" } -uv-resolver = { version = "0.0.46", path = "crates/uv-resolver" } -uv-scripts = { version = "0.0.46", path = "crates/uv-scripts" } -uv-settings = { version = "0.0.46", path = "crates/uv-settings" } -uv-shell = { version = "0.0.46", path = "crates/uv-shell" } -uv-small-str = { version = "0.0.46", path = "crates/uv-small-str" } -uv-state = { version = "0.0.46", path = "crates/uv-state" } -uv-static = { version = "0.0.46", path = "crates/uv-static" } -uv-test = { version = "0.0.46", path = "crates/uv-test" } -uv-tool = { version = "0.0.46", path = "crates/uv-tool" } -uv-torch = { version = "0.0.46", path = "crates/uv-torch" } -uv-trampoline-builder = { version = "0.0.46", path = "crates/uv-trampoline-builder" } -uv-types = { version = "0.0.46", path = "crates/uv-types" } -uv-unix = { version = "0.0.46", path = "crates/uv-unix" } -uv-version = { version = "0.11.13", path = "crates/uv-version" } -uv-virtualenv = { version = "0.0.46", path = "crates/uv-virtualenv" } -uv-warnings = { version = "0.0.46", path = "crates/uv-warnings" } -uv-windows = { version = "0.0.46", path = "crates/uv-windows" } -uv-workspace = { version = "0.0.46", path = "crates/uv-workspace" } +uv-platform = { version = "0.0.47", path = "crates/uv-platform" } +uv-platform-tags = { version = "0.0.47", path = "crates/uv-platform-tags" } +uv-preview = { version = "0.0.47", path = "crates/uv-preview" } +uv-publish = { version = "0.0.47", path = "crates/uv-publish" } +uv-pypi-types = { version = "0.0.47", path = "crates/uv-pypi-types" } +uv-python = { version = "0.0.47", path = "crates/uv-python" } +uv-redacted = { version = "0.0.47", path = "crates/uv-redacted" } +uv-requirements = { version = "0.0.47", path = "crates/uv-requirements" } +uv-requirements-txt = { version = "0.0.47", path = "crates/uv-requirements-txt" } +uv-resolver = { version = "0.0.47", path = "crates/uv-resolver" } +uv-scripts = { version = "0.0.47", path = "crates/uv-scripts" } +uv-settings = { version = "0.0.47", path = "crates/uv-settings" } +uv-shell = { version = "0.0.47", path = "crates/uv-shell" } +uv-small-str = { version = "0.0.47", path = "crates/uv-small-str" } +uv-state = { version = "0.0.47", path = "crates/uv-state" } +uv-static = { version = "0.0.47", path = "crates/uv-static" } +uv-test = { version = "0.0.47", path = "crates/uv-test" } +uv-tool = { version = "0.0.47", path = "crates/uv-tool" } +uv-torch = { version = "0.0.47", path = "crates/uv-torch" } +uv-trampoline-builder = { version = "0.0.47", path = "crates/uv-trampoline-builder" } +uv-types = { version = "0.0.47", path = "crates/uv-types" } +uv-unix = { version = "0.0.47", path = "crates/uv-unix" } +uv-version = { version = "0.11.14", path = "crates/uv-version" } +uv-virtualenv = { version = "0.0.47", path = "crates/uv-virtualenv" } +uv-warnings = { version = "0.0.47", path = "crates/uv-warnings" } +uv-windows = { version = "0.0.47", path = "crates/uv-windows" } +uv-workspace = { version = "0.0.47", path = "crates/uv-workspace" } ambient-id = { version = "0.0.11", default-features = false, features = [ "reqwest-middleware", diff --git a/crates/uv-audit/Cargo.toml b/crates/uv-audit/Cargo.toml index 7c5762ee6965a..e4691f5b69883 100644 --- a/crates/uv-audit/Cargo.toml +++ b/crates/uv-audit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-audit" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition.workspace = true rust-version.workspace = true diff --git a/crates/uv-audit/README.md b/crates/uv-audit/README.md index 9ceb542590967..53c6c8492e237 100644 --- a/crates/uv-audit/README.md +++ b/crates/uv-audit/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-audit). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-audit). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-auth/Cargo.toml b/crates/uv-auth/Cargo.toml index ec51485ced99b..974cebf6a744f 100644 --- a/crates/uv-auth/Cargo.toml +++ b/crates/uv-auth/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-auth" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-auth/README.md b/crates/uv-auth/README.md index e734ed29788ed..6f50dc1deeb9a 100644 --- a/crates/uv-auth/README.md +++ b/crates/uv-auth/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-auth). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-auth). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-bench/Cargo.toml b/crates/uv-bench/Cargo.toml index fe1ba6f79c37a..ed23cae288d9d 100644 --- a/crates/uv-bench/Cargo.toml +++ b/crates/uv-bench/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-bench" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" publish = false authors = { workspace = true } diff --git a/crates/uv-bench/README.md b/crates/uv-bench/README.md index 1b0924c452e83..dabed125e5c86 100644 --- a/crates/uv-bench/README.md +++ b/crates/uv-bench/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-bench). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-bench). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-bin-install/Cargo.toml b/crates/uv-bin-install/Cargo.toml index 4f049b5d4dc6e..be8afea45a9a1 100644 --- a/crates/uv-bin-install/Cargo.toml +++ b/crates/uv-bin-install/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-bin-install" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-bin-install/README.md b/crates/uv-bin-install/README.md index fb48cbfe6198c..f974e640a1916 100644 --- a/crates/uv-bin-install/README.md +++ b/crates/uv-bin-install/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-bin-install). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-bin-install). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-build-backend/Cargo.toml b/crates/uv-build-backend/Cargo.toml index 78bde37c7a248..7695d8992f679 100644 --- a/crates/uv-build-backend/Cargo.toml +++ b/crates/uv-build-backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-build-backend" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-build-backend/README.md b/crates/uv-build-backend/README.md index 08fe674010cd7..db38d7fb69669 100644 --- a/crates/uv-build-backend/README.md +++ b/crates/uv-build-backend/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-build-backend). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-build-backend). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-build-frontend/Cargo.toml b/crates/uv-build-frontend/Cargo.toml index e3ab662631101..0097898a35e56 100644 --- a/crates/uv-build-frontend/Cargo.toml +++ b/crates/uv-build-frontend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-build-frontend" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-build-frontend/README.md b/crates/uv-build-frontend/README.md index 3f4b80569396b..84c7f7d6eb44b 100644 --- a/crates/uv-build-frontend/README.md +++ b/crates/uv-build-frontend/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-build-frontend). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-build-frontend). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-build/Cargo.toml b/crates/uv-build/Cargo.toml index d615915180f2d..7e0dba0cb3c23 100644 --- a/crates/uv-build/Cargo.toml +++ b/crates/uv-build/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-build" -version = "0.11.13" +version = "0.11.14" description = "A Python build backend" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-build/pyproject.toml b/crates/uv-build/pyproject.toml index c89fefac50c9f..7da9f56d78c8e 100644 --- a/crates/uv-build/pyproject.toml +++ b/crates/uv-build/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "uv-build" -version = "0.11.13" +version = "0.11.14" description = "The uv build backend" authors = [{ name = "Astral Software Inc.", email = "hey@astral.sh" }] requires-python = ">=3.8" diff --git a/crates/uv-cache-info/Cargo.toml b/crates/uv-cache-info/Cargo.toml index 5a80becd25734..15746c2d93d24 100644 --- a/crates/uv-cache-info/Cargo.toml +++ b/crates/uv-cache-info/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-cache-info" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-cache-info/README.md b/crates/uv-cache-info/README.md index e8a0d033a6f42..06d54251772d6 100644 --- a/crates/uv-cache-info/README.md +++ b/crates/uv-cache-info/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-cache-info). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-cache-info). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-cache-key/Cargo.toml b/crates/uv-cache-key/Cargo.toml index f7010e0b95339..8d2df75036e09 100644 --- a/crates/uv-cache-key/Cargo.toml +++ b/crates/uv-cache-key/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-cache-key" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-cache-key/README.md b/crates/uv-cache-key/README.md index 05563a8c2a843..47699c6277c08 100644 --- a/crates/uv-cache-key/README.md +++ b/crates/uv-cache-key/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-cache-key). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-cache-key). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-cache/Cargo.toml b/crates/uv-cache/Cargo.toml index 581cfeaa0c891..837b96005c099 100644 --- a/crates/uv-cache/Cargo.toml +++ b/crates/uv-cache/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-cache" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-cache/README.md b/crates/uv-cache/README.md index c7fd1f2bffe51..6f0801f2d351e 100644 --- a/crates/uv-cache/README.md +++ b/crates/uv-cache/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-cache). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-cache). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-cli/Cargo.toml b/crates/uv-cli/Cargo.toml index cb25ebf785564..ceeb27719fa14 100644 --- a/crates/uv-cli/Cargo.toml +++ b/crates/uv-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-cli" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-cli/README.md b/crates/uv-cli/README.md index 874badd00e1ad..6253f38e24fbe 100644 --- a/crates/uv-cli/README.md +++ b/crates/uv-cli/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-cli). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-cli). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-client/Cargo.toml b/crates/uv-client/Cargo.toml index a5a58b2b3e039..6c37f0b16a31e 100644 --- a/crates/uv-client/Cargo.toml +++ b/crates/uv-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-client" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-client/README.md b/crates/uv-client/README.md index 5177379727abb..d687060b5cd56 100644 --- a/crates/uv-client/README.md +++ b/crates/uv-client/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-client). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-client). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-configuration/Cargo.toml b/crates/uv-configuration/Cargo.toml index 15192ceb13e2f..16ea2582d8bfd 100644 --- a/crates/uv-configuration/Cargo.toml +++ b/crates/uv-configuration/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-configuration" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-configuration/README.md b/crates/uv-configuration/README.md index 300c4d43e525d..8fa375038e0c3 100644 --- a/crates/uv-configuration/README.md +++ b/crates/uv-configuration/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-configuration). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-configuration). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-console/Cargo.toml b/crates/uv-console/Cargo.toml index 384f34225ce6e..d30743468a653 100644 --- a/crates/uv-console/Cargo.toml +++ b/crates/uv-console/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-console" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-console/README.md b/crates/uv-console/README.md index 8ac1041fef5c5..e8ca22f35847a 100644 --- a/crates/uv-console/README.md +++ b/crates/uv-console/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-console). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-console). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-dev/Cargo.toml b/crates/uv-dev/Cargo.toml index b9b9df7ebc711..f937d13f1287a 100644 --- a/crates/uv-dev/Cargo.toml +++ b/crates/uv-dev/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-dev" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" publish = false diff --git a/crates/uv-dev/README.md b/crates/uv-dev/README.md index fb092911a553b..f4159e420f432 100644 --- a/crates/uv-dev/README.md +++ b/crates/uv-dev/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-dev). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-dev). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-dirs/Cargo.toml b/crates/uv-dirs/Cargo.toml index 48f391f1afe9f..5bc5cc54f138e 100644 --- a/crates/uv-dirs/Cargo.toml +++ b/crates/uv-dirs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-dirs" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-dirs/README.md b/crates/uv-dirs/README.md index c9cf636d8bd04..9ff9697f3a157 100644 --- a/crates/uv-dirs/README.md +++ b/crates/uv-dirs/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-dirs). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-dirs). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-dispatch/Cargo.toml b/crates/uv-dispatch/Cargo.toml index ea775632d1a7d..b811145ab93a6 100644 --- a/crates/uv-dispatch/Cargo.toml +++ b/crates/uv-dispatch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-dispatch" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-dispatch/README.md b/crates/uv-dispatch/README.md index d4d8529c37de1..61b2377e0010c 100644 --- a/crates/uv-dispatch/README.md +++ b/crates/uv-dispatch/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-dispatch). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-dispatch). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-distribution-filename/Cargo.toml b/crates/uv-distribution-filename/Cargo.toml index 89f57985fda5d..22745b0c7e6bb 100644 --- a/crates/uv-distribution-filename/Cargo.toml +++ b/crates/uv-distribution-filename/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-distribution-filename" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-distribution-filename/README.md b/crates/uv-distribution-filename/README.md index 59b328db279a0..7beca5b03db82 100644 --- a/crates/uv-distribution-filename/README.md +++ b/crates/uv-distribution-filename/README.md @@ -5,9 +5,9 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The source can be found -[here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-distribution-filename). +[here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-distribution-filename). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-distribution-types/Cargo.toml b/crates/uv-distribution-types/Cargo.toml index 689604c3c5086..479935861ccf9 100644 --- a/crates/uv-distribution-types/Cargo.toml +++ b/crates/uv-distribution-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-distribution-types" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-distribution-types/README.md b/crates/uv-distribution-types/README.md index 2901f079b8607..dcca5f7b0fbad 100644 --- a/crates/uv-distribution-types/README.md +++ b/crates/uv-distribution-types/README.md @@ -5,9 +5,9 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The source can be found -[here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-distribution-types). +[here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-distribution-types). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-distribution/Cargo.toml b/crates/uv-distribution/Cargo.toml index 9a124391092d6..f33ee254bae04 100644 --- a/crates/uv-distribution/Cargo.toml +++ b/crates/uv-distribution/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-distribution" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-distribution/README.md b/crates/uv-distribution/README.md index eb242db555023..a211fca660531 100644 --- a/crates/uv-distribution/README.md +++ b/crates/uv-distribution/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-distribution). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-distribution). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-extract/Cargo.toml b/crates/uv-extract/Cargo.toml index 78238aaa33298..552baa7596cd2 100644 --- a/crates/uv-extract/Cargo.toml +++ b/crates/uv-extract/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-extract" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-extract/README.md b/crates/uv-extract/README.md index 7d4239e0f8cdf..8a3271b977aad 100644 --- a/crates/uv-extract/README.md +++ b/crates/uv-extract/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-extract). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-extract). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-fastid/Cargo.toml b/crates/uv-fastid/Cargo.toml index e42b416b65165..54ca554df6162 100644 --- a/crates/uv-fastid/Cargo.toml +++ b/crates/uv-fastid/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "uv-fastid" description = "This is an internal component crate of uv" -version = "0.0.46" +version = "0.0.47" edition.workspace = true rust-version.workspace = true homepage.workspace = true diff --git a/crates/uv-fastid/README.md b/crates/uv-fastid/README.md index 5e7adc5ef6071..c68037bb52e72 100644 --- a/crates/uv-fastid/README.md +++ b/crates/uv-fastid/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-fastid). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-fastid). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-flags/Cargo.toml b/crates/uv-flags/Cargo.toml index 89a9d07d39f0d..4bb1844c4a799 100644 --- a/crates/uv-flags/Cargo.toml +++ b/crates/uv-flags/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-flags" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-flags/README.md b/crates/uv-flags/README.md index 8f43dab1aea44..a643db9b5295c 100644 --- a/crates/uv-flags/README.md +++ b/crates/uv-flags/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-flags). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-flags). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-fs/Cargo.toml b/crates/uv-fs/Cargo.toml index 264c0d811c8d3..198dc95440563 100644 --- a/crates/uv-fs/Cargo.toml +++ b/crates/uv-fs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-fs" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-fs/README.md b/crates/uv-fs/README.md index 15717b7ef5e83..41e08b024948e 100644 --- a/crates/uv-fs/README.md +++ b/crates/uv-fs/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-fs). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-fs). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-git-types/Cargo.toml b/crates/uv-git-types/Cargo.toml index 84dccc5a5e273..fc9483688be5f 100644 --- a/crates/uv-git-types/Cargo.toml +++ b/crates/uv-git-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-git-types" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-git-types/README.md b/crates/uv-git-types/README.md index 84a99a57d83d8..6b27833068dda 100644 --- a/crates/uv-git-types/README.md +++ b/crates/uv-git-types/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-git-types). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-git-types). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-git/Cargo.toml b/crates/uv-git/Cargo.toml index 651ea7de4b31b..105e129b6e8b7 100644 --- a/crates/uv-git/Cargo.toml +++ b/crates/uv-git/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-git" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-git/README.md b/crates/uv-git/README.md index 8a46a97e4581d..640fe1d4a04e2 100644 --- a/crates/uv-git/README.md +++ b/crates/uv-git/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-git). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-git). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-globfilter/Cargo.toml b/crates/uv-globfilter/Cargo.toml index 2cdf32854a25a..cba40aed4867b 100644 --- a/crates/uv-globfilter/Cargo.toml +++ b/crates/uv-globfilter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-globfilter" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" readme = "README.md" edition = { workspace = true } diff --git a/crates/uv-install-wheel/Cargo.toml b/crates/uv-install-wheel/Cargo.toml index c09ee975e27bf..d3cab10e6e1ae 100644 --- a/crates/uv-install-wheel/Cargo.toml +++ b/crates/uv-install-wheel/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-install-wheel" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" keywords = ["wheel", "python"] diff --git a/crates/uv-install-wheel/README.md b/crates/uv-install-wheel/README.md index aa0ed40d65ba5..020f68cf0c9a1 100644 --- a/crates/uv-install-wheel/README.md +++ b/crates/uv-install-wheel/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-install-wheel). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-install-wheel). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-installer/Cargo.toml b/crates/uv-installer/Cargo.toml index cbac73fb770b2..57f8fb8fc5881 100644 --- a/crates/uv-installer/Cargo.toml +++ b/crates/uv-installer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-installer" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-installer/README.md b/crates/uv-installer/README.md index 86a3d6f5a8d41..c6b03d37b32d9 100644 --- a/crates/uv-installer/README.md +++ b/crates/uv-installer/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-installer). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-installer). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-keyring/Cargo.toml b/crates/uv-keyring/Cargo.toml index 0c96454593466..01e7a32bbe52c 100644 --- a/crates/uv-keyring/Cargo.toml +++ b/crates/uv-keyring/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-keyring" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-logging/Cargo.toml b/crates/uv-logging/Cargo.toml index 4898522e34a7c..90820f48fc1bf 100644 --- a/crates/uv-logging/Cargo.toml +++ b/crates/uv-logging/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-logging" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-logging/README.md b/crates/uv-logging/README.md index 55d7b855f216e..1c86615c85347 100644 --- a/crates/uv-logging/README.md +++ b/crates/uv-logging/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-logging). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-logging). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-macros/Cargo.toml b/crates/uv-macros/Cargo.toml index c8489293f892f..ca878cf6cad26 100644 --- a/crates/uv-macros/Cargo.toml +++ b/crates/uv-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-macros" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-macros/README.md b/crates/uv-macros/README.md index ec221b25350bd..3f8f5db0a321c 100644 --- a/crates/uv-macros/README.md +++ b/crates/uv-macros/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-macros). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-macros). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-metadata/Cargo.toml b/crates/uv-metadata/Cargo.toml index 9eaf7d6e0d9fa..8c4633aa8c7df 100644 --- a/crates/uv-metadata/Cargo.toml +++ b/crates/uv-metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-metadata" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-metadata/README.md b/crates/uv-metadata/README.md index 0516b2fea9a20..445fd325c13db 100644 --- a/crates/uv-metadata/README.md +++ b/crates/uv-metadata/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-metadata). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-metadata). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-normalize/Cargo.toml b/crates/uv-normalize/Cargo.toml index 31546096fb431..3f762d5993853 100644 --- a/crates/uv-normalize/Cargo.toml +++ b/crates/uv-normalize/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-normalize" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-normalize/README.md b/crates/uv-normalize/README.md index 7a3ede9d01122..5c11268357616 100644 --- a/crates/uv-normalize/README.md +++ b/crates/uv-normalize/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-normalize). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-normalize). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-once-map/Cargo.toml b/crates/uv-once-map/Cargo.toml index f67255539dec9..fd503dc10a5fc 100644 --- a/crates/uv-once-map/Cargo.toml +++ b/crates/uv-once-map/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-once-map" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-once-map/README.md b/crates/uv-once-map/README.md index f02ba36624838..43027329b6cdb 100644 --- a/crates/uv-once-map/README.md +++ b/crates/uv-once-map/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-once-map). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-once-map). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-options-metadata/Cargo.toml b/crates/uv-options-metadata/Cargo.toml index 11576d0475399..fd32f9a33bdbc 100644 --- a/crates/uv-options-metadata/Cargo.toml +++ b/crates/uv-options-metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-options-metadata" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-options-metadata/README.md b/crates/uv-options-metadata/README.md index b217eae900dba..e4e212aeef2e2 100644 --- a/crates/uv-options-metadata/README.md +++ b/crates/uv-options-metadata/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-options-metadata). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-options-metadata). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-pep440/Cargo.toml b/crates/uv-pep440/Cargo.toml index cd10fa2f8b783..09073094e6f66 100644 --- a/crates/uv-pep440/Cargo.toml +++ b/crates/uv-pep440/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-pep440" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" license = "Apache-2.0 OR BSD-2-Clause" include = ["/src", "Changelog.md", "License-Apache", "License-BSD", "Readme.md", "pyproject.toml"] diff --git a/crates/uv-pep440/README.md b/crates/uv-pep440/README.md index b3eb878e3de9e..4ffcbebebce03 100644 --- a/crates/uv-pep440/README.md +++ b/crates/uv-pep440/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-pep440). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-pep440). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-pep508/Cargo.toml b/crates/uv-pep508/Cargo.toml index 5c0449651fd7b..9bdf6c74d042f 100644 --- a/crates/uv-pep508/Cargo.toml +++ b/crates/uv-pep508/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-pep508" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" include = ["/src", "Changelog.md", "License-Apache", "License-BSD", "Readme.md", "pyproject.toml"] license = "Apache-2.0 OR BSD-2-Clause" diff --git a/crates/uv-pep508/README.md b/crates/uv-pep508/README.md index dda1cff321208..4aa3a87a34de6 100644 --- a/crates/uv-pep508/README.md +++ b/crates/uv-pep508/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-pep508). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-pep508). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-performance-memory-allocator/Cargo.toml b/crates/uv-performance-memory-allocator/Cargo.toml index 28a2b5de4f4ce..cf802bfa2c701 100644 --- a/crates/uv-performance-memory-allocator/Cargo.toml +++ b/crates/uv-performance-memory-allocator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-performance-memory-allocator" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-performance-memory-allocator/README.md b/crates/uv-performance-memory-allocator/README.md index 40ca9a73bbe88..f50b7ebb0eb5c 100644 --- a/crates/uv-performance-memory-allocator/README.md +++ b/crates/uv-performance-memory-allocator/README.md @@ -5,9 +5,9 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The source can be found -[here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-performance-memory-allocator). +[here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-performance-memory-allocator). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-platform-tags/Cargo.toml b/crates/uv-platform-tags/Cargo.toml index 50961b5a05760..0dddef195f746 100644 --- a/crates/uv-platform-tags/Cargo.toml +++ b/crates/uv-platform-tags/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-platform-tags" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-platform-tags/README.md b/crates/uv-platform-tags/README.md index 1dd8d178940d1..da189a410edd6 100644 --- a/crates/uv-platform-tags/README.md +++ b/crates/uv-platform-tags/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-platform-tags). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-platform-tags). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-platform/Cargo.toml b/crates/uv-platform/Cargo.toml index b818020bdc965..97835b70733de 100644 --- a/crates/uv-platform/Cargo.toml +++ b/crates/uv-platform/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-platform" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-platform/README.md b/crates/uv-platform/README.md index e329b0bcbc648..4f59359de3a20 100644 --- a/crates/uv-platform/README.md +++ b/crates/uv-platform/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-platform). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-platform). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-preview/Cargo.toml b/crates/uv-preview/Cargo.toml index e9d3cc40e685c..0010259c6dea0 100644 --- a/crates/uv-preview/Cargo.toml +++ b/crates/uv-preview/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-preview" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-preview/README.md b/crates/uv-preview/README.md index 3363299bfac67..5458d78ff3055 100644 --- a/crates/uv-preview/README.md +++ b/crates/uv-preview/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-preview). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-preview). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-publish/Cargo.toml b/crates/uv-publish/Cargo.toml index 1b4fa3fdb6c2d..429e251fe608e 100644 --- a/crates/uv-publish/Cargo.toml +++ b/crates/uv-publish/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-publish" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-publish/README.md b/crates/uv-publish/README.md index 68cad4a06f4be..5cebfa6808ad0 100644 --- a/crates/uv-publish/README.md +++ b/crates/uv-publish/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-publish). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-publish). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-pypi-types/Cargo.toml b/crates/uv-pypi-types/Cargo.toml index 2cf0e0c0e8813..c7fe39296aede 100644 --- a/crates/uv-pypi-types/Cargo.toml +++ b/crates/uv-pypi-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-pypi-types" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-pypi-types/README.md b/crates/uv-pypi-types/README.md index 334d87f4803c4..a648780fa31e3 100644 --- a/crates/uv-pypi-types/README.md +++ b/crates/uv-pypi-types/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-pypi-types). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-pypi-types). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-python/Cargo.toml b/crates/uv-python/Cargo.toml index ebd53d9c409ce..392ff09750948 100644 --- a/crates/uv-python/Cargo.toml +++ b/crates/uv-python/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-python" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-python/README.md b/crates/uv-python/README.md index 23b243261bfe3..b0c6062ddfd5a 100644 --- a/crates/uv-python/README.md +++ b/crates/uv-python/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-python). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-python). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-redacted/Cargo.toml b/crates/uv-redacted/Cargo.toml index 6fd84dacaa05d..a91d67097aeb0 100644 --- a/crates/uv-redacted/Cargo.toml +++ b/crates/uv-redacted/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-redacted" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-redacted/README.md b/crates/uv-redacted/README.md index 9c0d4ba0c06aa..10623c92b626b 100644 --- a/crates/uv-redacted/README.md +++ b/crates/uv-redacted/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-redacted). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-redacted). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-requirements-txt/Cargo.toml b/crates/uv-requirements-txt/Cargo.toml index f6235261d72b5..801b1824263cf 100644 --- a/crates/uv-requirements-txt/Cargo.toml +++ b/crates/uv-requirements-txt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-requirements-txt" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-requirements-txt/README.md b/crates/uv-requirements-txt/README.md index 21fb2b05e0bc4..f9c48835190e4 100644 --- a/crates/uv-requirements-txt/README.md +++ b/crates/uv-requirements-txt/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-requirements-txt). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-requirements-txt). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-requirements/Cargo.toml b/crates/uv-requirements/Cargo.toml index c44f71b67c032..01f3450fa299c 100644 --- a/crates/uv-requirements/Cargo.toml +++ b/crates/uv-requirements/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-requirements" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-requirements/README.md b/crates/uv-requirements/README.md index f95d56f0b864d..ec13c52f8d27e 100644 --- a/crates/uv-requirements/README.md +++ b/crates/uv-requirements/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-requirements). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-requirements). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-resolver/Cargo.toml b/crates/uv-resolver/Cargo.toml index 97110ee60d4b2..6bf5259dc03fd 100644 --- a/crates/uv-resolver/Cargo.toml +++ b/crates/uv-resolver/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-resolver" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-resolver/README.md b/crates/uv-resolver/README.md index 4d2ad14d6e2dc..b3915f9409e7d 100644 --- a/crates/uv-resolver/README.md +++ b/crates/uv-resolver/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-resolver). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-resolver). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-scripts/Cargo.toml b/crates/uv-scripts/Cargo.toml index e6a7cd0fb5dc6..d368bb67f4f63 100644 --- a/crates/uv-scripts/Cargo.toml +++ b/crates/uv-scripts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-scripts" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-scripts/README.md b/crates/uv-scripts/README.md index 9dba3db1ef1ee..b0f7ea6a3b4dd 100644 --- a/crates/uv-scripts/README.md +++ b/crates/uv-scripts/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-scripts). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-scripts). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-settings/Cargo.toml b/crates/uv-settings/Cargo.toml index 3ca3a7f7a52bf..16980df9b4522 100644 --- a/crates/uv-settings/Cargo.toml +++ b/crates/uv-settings/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-settings" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-settings/README.md b/crates/uv-settings/README.md index b1ef264367f96..e8e94c88435cf 100644 --- a/crates/uv-settings/README.md +++ b/crates/uv-settings/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-settings). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-settings). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-shell/Cargo.toml b/crates/uv-shell/Cargo.toml index f744d2b94e835..ff07135725788 100644 --- a/crates/uv-shell/Cargo.toml +++ b/crates/uv-shell/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-shell" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-shell/README.md b/crates/uv-shell/README.md index 30f5a83a8409a..9a5c15dcdc991 100644 --- a/crates/uv-shell/README.md +++ b/crates/uv-shell/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-shell). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-shell). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-small-str/Cargo.toml b/crates/uv-small-str/Cargo.toml index 744e7c4bcb386..88ab05a0ca0f6 100644 --- a/crates/uv-small-str/Cargo.toml +++ b/crates/uv-small-str/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-small-str" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-small-str/README.md b/crates/uv-small-str/README.md index 65e169f33fcdf..fa193f463ee84 100644 --- a/crates/uv-small-str/README.md +++ b/crates/uv-small-str/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-small-str). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-small-str). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-state/Cargo.toml b/crates/uv-state/Cargo.toml index 35cb1b4f13ff6..18b77ba029d6f 100644 --- a/crates/uv-state/Cargo.toml +++ b/crates/uv-state/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-state" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-state/README.md b/crates/uv-state/README.md index 23d32e0a29a76..ebaeee0a4066d 100644 --- a/crates/uv-state/README.md +++ b/crates/uv-state/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-state). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-state). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-static/Cargo.toml b/crates/uv-static/Cargo.toml index 8a8808c40686d..0885f94f6621b 100644 --- a/crates/uv-static/Cargo.toml +++ b/crates/uv-static/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-static" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-static/README.md b/crates/uv-static/README.md index 9ea4ec3cf7c4d..bf81631b92948 100644 --- a/crates/uv-static/README.md +++ b/crates/uv-static/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-static). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-static). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-static/src/env_vars.rs b/crates/uv-static/src/env_vars.rs index 93f2beb4f3e76..0a3e9f7b0d2c7 100644 --- a/crates/uv-static/src/env_vars.rs +++ b/crates/uv-static/src/env_vars.rs @@ -485,7 +485,7 @@ impl EnvVars { /// [`UV_INSTALLER_GITHUB_BASE_URL`](Self::UV_INSTALLER_GITHUB_BASE_URL) and /// [`UV_INSTALLER_GHE_BASE_URL`](Self::UV_INSTALLER_GHE_BASE_URL) override this /// variable for `uv self update`. - #[attr_added_in("next release")] + #[attr_added_in("0.11.14")] pub const UV_ASTRAL_MIRROR_URL: &'static str = "UV_ASTRAL_MIRROR_URL"; /// Pin managed CPython versions to a specific build version. diff --git a/crates/uv-test/Cargo.toml b/crates/uv-test/Cargo.toml index 3a35be2784b6a..bd2e9066b564e 100644 --- a/crates/uv-test/Cargo.toml +++ b/crates/uv-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-test" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-test/README.md b/crates/uv-test/README.md index 51396a2ee9538..ee878705187c9 100644 --- a/crates/uv-test/README.md +++ b/crates/uv-test/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-test). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-test). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-tool/Cargo.toml b/crates/uv-tool/Cargo.toml index 7269aa850b5a4..9a45843a73588 100644 --- a/crates/uv-tool/Cargo.toml +++ b/crates/uv-tool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-tool" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-tool/README.md b/crates/uv-tool/README.md index 73bebb3ccec98..5375384048d57 100644 --- a/crates/uv-tool/README.md +++ b/crates/uv-tool/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-tool). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-tool). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-torch/Cargo.toml b/crates/uv-torch/Cargo.toml index 6ee36e820052d..199e0a1ad7827 100644 --- a/crates/uv-torch/Cargo.toml +++ b/crates/uv-torch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-torch" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-torch/README.md b/crates/uv-torch/README.md index eb43957e18b6b..67c8128d28d1f 100644 --- a/crates/uv-torch/README.md +++ b/crates/uv-torch/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-torch). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-torch). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-trampoline-builder/Cargo.toml b/crates/uv-trampoline-builder/Cargo.toml index 74bb5e682485a..189c31d001912 100644 --- a/crates/uv-trampoline-builder/Cargo.toml +++ b/crates/uv-trampoline-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-trampoline-builder" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } diff --git a/crates/uv-trampoline-builder/README.md b/crates/uv-trampoline-builder/README.md index 279bb1ea2989f..11e4a6cfe6318 100644 --- a/crates/uv-trampoline-builder/README.md +++ b/crates/uv-trampoline-builder/README.md @@ -5,9 +5,9 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The source can be found -[here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-trampoline-builder). +[here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-trampoline-builder). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-trampoline/Cargo.lock b/crates/uv-trampoline/Cargo.lock index dc8ea620fbea1..fc7daf4c84c5e 100644 --- a/crates/uv-trampoline/Cargo.lock +++ b/crates/uv-trampoline/Cargo.lock @@ -138,7 +138,7 @@ checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "uv-macros" -version = "0.0.46" +version = "0.0.47" dependencies = [ "proc-macro2", "quote", @@ -148,7 +148,7 @@ dependencies = [ [[package]] name = "uv-static" -version = "0.0.46" +version = "0.0.47" dependencies = [ "thiserror", "uv-macros", @@ -169,7 +169,7 @@ dependencies = [ [[package]] name = "uv-windows" -version = "0.0.46" +version = "0.0.47" dependencies = [ "windows", ] diff --git a/crates/uv-types/Cargo.toml b/crates/uv-types/Cargo.toml index fdf1a5418debe..86a836276b7b9 100644 --- a/crates/uv-types/Cargo.toml +++ b/crates/uv-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-types" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-types/README.md b/crates/uv-types/README.md index 32c953bafb0e0..906734ad75c1b 100644 --- a/crates/uv-types/README.md +++ b/crates/uv-types/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-types). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-types). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-unix/Cargo.toml b/crates/uv-unix/Cargo.toml index a9c9688985d93..48c054a89e4db 100644 --- a/crates/uv-unix/Cargo.toml +++ b/crates/uv-unix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-unix" -version = "0.0.46" +version = "0.0.47" description = "Unix-specific functionality for uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-unix/README.md b/crates/uv-unix/README.md index 10fdd2f2a953c..35cc05c3d9134 100644 --- a/crates/uv-unix/README.md +++ b/crates/uv-unix/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-unix). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-unix). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-version/Cargo.toml b/crates/uv-version/Cargo.toml index 8c574188d5206..21ca77db23948 100644 --- a/crates/uv-version/Cargo.toml +++ b/crates/uv-version/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-version" -version = "0.11.13" +version = "0.11.14" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-version/README.md b/crates/uv-version/README.md index 16792d8864f50..97915fc04b4c0 100644 --- a/crates/uv-version/README.md +++ b/crates/uv-version/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.11.13) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-version). +This version (0.11.14) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-version). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-virtualenv/Cargo.toml b/crates/uv-virtualenv/Cargo.toml index 75816305abac2..9d57f3a7c8259 100644 --- a/crates/uv-virtualenv/Cargo.toml +++ b/crates/uv-virtualenv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-virtualenv" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" keywords = ["virtualenv", "venv", "python"] diff --git a/crates/uv-warnings/Cargo.toml b/crates/uv-warnings/Cargo.toml index 20fdab75052e7..7a19513cd4b47 100644 --- a/crates/uv-warnings/Cargo.toml +++ b/crates/uv-warnings/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-warnings" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-warnings/README.md b/crates/uv-warnings/README.md index 1e21489dd6006..1504e5d7395ee 100644 --- a/crates/uv-warnings/README.md +++ b/crates/uv-warnings/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-warnings). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-warnings). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-windows/Cargo.toml b/crates/uv-windows/Cargo.toml index 7e2284e2cfb39..a2a525685ca5a 100644 --- a/crates/uv-windows/Cargo.toml +++ b/crates/uv-windows/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-windows" -version = "0.0.46" +version = "0.0.47" edition = { workspace = true } rust-version = { workspace = true } homepage = { workspace = true } diff --git a/crates/uv-windows/README.md b/crates/uv-windows/README.md index f929d6899525f..26e149411eaaf 100644 --- a/crates/uv-windows/README.md +++ b/crates/uv-windows/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-windows). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-windows). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv-workspace/Cargo.toml b/crates/uv-workspace/Cargo.toml index 02b573d4b0a9b..caa8adcc392c6 100644 --- a/crates/uv-workspace/Cargo.toml +++ b/crates/uv-workspace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv-workspace" -version = "0.0.46" +version = "0.0.47" description = "This is an internal component crate of uv" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv-workspace/README.md b/crates/uv-workspace/README.md index b2742d247a3bb..172b0ecd5c583 100644 --- a/crates/uv-workspace/README.md +++ b/crates/uv-workspace/README.md @@ -5,8 +5,8 @@ This crate is an internal component of [uv](https://crates.io/crates/uv). The Rust API exposed here is unstable and will have frequent breaking changes. -This version (0.0.46) is a component of [uv 0.11.13](https://crates.io/crates/uv/0.11.13). The -source can be found [here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv-workspace). +This version (0.0.47) is a component of [uv 0.11.14](https://crates.io/crates/uv/0.11.14). The +source can be found [here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv-workspace). See uv's [crate versioning policy](https://docs.astral.sh/uv/reference/policies/versioning/#crate-versioning) diff --git a/crates/uv/Cargo.toml b/crates/uv/Cargo.toml index da88e35920e7f..10a25b19e9b24 100644 --- a/crates/uv/Cargo.toml +++ b/crates/uv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uv" -version = "0.11.13" +version = "0.11.14" description = "A Python package and project manager" edition = { workspace = true } rust-version = { workspace = true } diff --git a/crates/uv/README.md b/crates/uv/README.md index a46e5c745d740..378557859e352 100644 --- a/crates/uv/README.md +++ b/crates/uv/README.md @@ -10,8 +10,8 @@ for more information. This crate is the entry point to the uv command-line interface. The Rust API exposed here is not considered public interface. -This is version 0.11.13. The source can be found -[here](https://github.com/astral-sh/uv/blob/0.11.13/crates/uv). +This is version 0.11.14. The source can be found +[here](https://github.com/astral-sh/uv/blob/0.11.14/crates/uv). The following uv workspace members are also available: diff --git a/docs/concepts/build-backend.md b/docs/concepts/build-backend.md index 4f69293f7b77c..2547c25087110 100644 --- a/docs/concepts/build-backend.md +++ b/docs/concepts/build-backend.md @@ -31,7 +31,7 @@ To use uv as a build backend in an existing project, add `uv_build` to the ```toml title="pyproject.toml" [build-system] -requires = ["uv_build>=0.11.13,<0.12"] +requires = ["uv_build>=0.11.14,<0.12"] build-backend = "uv_build" ``` diff --git a/docs/concepts/projects/init.md b/docs/concepts/projects/init.md index 973cac70c47c6..2a939b5279943 100644 --- a/docs/concepts/projects/init.md +++ b/docs/concepts/projects/init.md @@ -113,7 +113,7 @@ dependencies = [] example-pkg = "example_pkg:main" [build-system] -requires = ["uv_build>=0.11.13,<0.12"] +requires = ["uv_build>=0.11.14,<0.12"] build-backend = "uv_build" ``` @@ -136,7 +136,7 @@ dependencies = [] example-pkg = "example_pkg:main" [build-system] -requires = ["uv_build>=0.11.13,<0.12"] +requires = ["uv_build>=0.11.14,<0.12"] build-backend = "uv_build" ``` @@ -197,7 +197,7 @@ requires-python = ">=3.11" dependencies = [] [build-system] -requires = ["uv_build>=0.11.13,<0.12"] +requires = ["uv_build>=0.11.14,<0.12"] build-backend = "uv_build" ``` diff --git a/docs/concepts/projects/workspaces.md b/docs/concepts/projects/workspaces.md index e948dba22e33e..008b92f5d27e0 100644 --- a/docs/concepts/projects/workspaces.md +++ b/docs/concepts/projects/workspaces.md @@ -75,7 +75,7 @@ bird-feeder = { workspace = true } members = ["packages/*"] [build-system] -requires = ["uv_build>=0.11.13,<0.12"] +requires = ["uv_build>=0.11.14,<0.12"] build-backend = "uv_build" ``` @@ -106,7 +106,7 @@ tqdm = { git = "https://github.com/tqdm/tqdm" } members = ["packages/*"] [build-system] -requires = ["uv_build>=0.11.13,<0.12"] +requires = ["uv_build>=0.11.14,<0.12"] build-backend = "uv_build" ``` @@ -188,7 +188,7 @@ dependencies = ["bird-feeder", "tqdm>=4,<5"] bird-feeder = { path = "packages/bird-feeder" } [build-system] -requires = ["uv_build>=0.11.13,<0.12"] +requires = ["uv_build>=0.11.14,<0.12"] build-backend = "uv_build" ``` diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index a726963bab61e..8abf83325eb8c 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -25,7 +25,7 @@ uv provides a standalone installer to download and install uv: Request a specific version by including it in the URL: ```console - $ curl -LsSf https://astral.sh/uv/0.11.13/install.sh | sh + $ curl -LsSf https://astral.sh/uv/0.11.14/install.sh | sh ``` === "Windows" @@ -41,7 +41,7 @@ uv provides a standalone installer to download and install uv: Request a specific version by including it in the URL: ```pwsh-session - PS> powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/0.11.13/install.ps1 | iex" + PS> powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/0.11.14/install.ps1 | iex" ``` !!! tip diff --git a/docs/guides/integration/aws-lambda.md b/docs/guides/integration/aws-lambda.md index 4e0c134973f75..197fb8cbc4e8f 100644 --- a/docs/guides/integration/aws-lambda.md +++ b/docs/guides/integration/aws-lambda.md @@ -92,7 +92,7 @@ the second stage, we'll copy this directory over to the final image, omitting th other unnecessary files. ```dockerfile title="Dockerfile" -FROM ghcr.io/astral-sh/uv:0.11.13 AS uv +FROM ghcr.io/astral-sh/uv:0.11.14 AS uv # First, bundle the dependencies into the task root. FROM public.ecr.aws/lambda/python:3.13 AS builder @@ -334,7 +334,7 @@ And confirm that opening http://127.0.0.1:8000/ in a web browser displays, "Hell Finally, we'll update the Dockerfile to include the local library in the deployment package: ```dockerfile title="Dockerfile" -FROM ghcr.io/astral-sh/uv:0.11.13 AS uv +FROM ghcr.io/astral-sh/uv:0.11.14 AS uv # First, bundle the dependencies into the task root. FROM public.ecr.aws/lambda/python:3.13 AS builder diff --git a/docs/guides/integration/docker.md b/docs/guides/integration/docker.md index c9cd8bb7bd4cc..d9a0734d87e68 100644 --- a/docs/guides/integration/docker.md +++ b/docs/guides/integration/docker.md @@ -31,7 +31,7 @@ $ docker run --rm -it ghcr.io/astral-sh/uv:debian uv --help The following distroless images are available: - `ghcr.io/astral-sh/uv:latest` -- `ghcr.io/astral-sh/uv:{major}.{minor}.{patch}`, e.g., `ghcr.io/astral-sh/uv:0.11.13` +- `ghcr.io/astral-sh/uv:{major}.{minor}.{patch}`, e.g., `ghcr.io/astral-sh/uv:0.11.14` - `ghcr.io/astral-sh/uv:{major}.{minor}`, e.g., `ghcr.io/astral-sh/uv:0.8` (the latest patch version) @@ -92,7 +92,7 @@ And the following derived images are available: As with the distroless image, each derived image is published with uv version tags as `ghcr.io/astral-sh/uv:{major}.{minor}.{patch}-{base}` and -`ghcr.io/astral-sh/uv:{major}.{minor}-{base}`, e.g., `ghcr.io/astral-sh/uv:0.11.13-alpine`. +`ghcr.io/astral-sh/uv:{major}.{minor}-{base}`, e.g., `ghcr.io/astral-sh/uv:0.11.14-alpine`. In addition, starting with `0.8` each derived image also sets `UV_TOOL_BIN_DIR` to `/usr/local/bin` to allow `uv tool install` to work as expected with the default user. @@ -133,7 +133,7 @@ Note this requires `curl` to be available. In either case, it is best practice to pin to a specific uv version, e.g., with: ```dockerfile -COPY --from=ghcr.io/astral-sh/uv:0.11.13 /uv /uvx /bin/ +COPY --from=ghcr.io/astral-sh/uv:0.11.14 /uv /uvx /bin/ ``` !!! tip @@ -151,7 +151,7 @@ COPY --from=ghcr.io/astral-sh/uv:0.11.13 /uv /uvx /bin/ Or, with the installer: ```dockerfile -ADD https://astral.sh/uv/0.11.13/install.sh /uv-installer.sh +ADD https://astral.sh/uv/0.11.14/install.sh /uv-installer.sh ``` ### Installing a project @@ -619,5 +619,5 @@ Verified OK !!! tip These examples use `latest`, but best practice is to verify the attestation for a specific - version tag, e.g., `ghcr.io/astral-sh/uv:0.11.13`, or (even better) the specific image digest, + version tag, e.g., `ghcr.io/astral-sh/uv:0.11.14`, or (even better) the specific image digest, such as `ghcr.io/astral-sh/uv:0.5.27@sha256:5adf09a5a526f380237408032a9308000d14d5947eafa687ad6c6a2476787b4f`. diff --git a/docs/guides/integration/github.md b/docs/guides/integration/github.md index 95ba14a9fe7d0..bb761d8c1dd3f 100644 --- a/docs/guides/integration/github.md +++ b/docs/guides/integration/github.md @@ -47,7 +47,7 @@ jobs: uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: # Install a specific version of uv. - version: "0.11.13" + version: "0.11.14" ``` ## Setting up Python diff --git a/docs/guides/integration/gitlab.md b/docs/guides/integration/gitlab.md index 6bcc00a8bd68c..62bbaf037babc 100644 --- a/docs/guides/integration/gitlab.md +++ b/docs/guides/integration/gitlab.md @@ -13,7 +13,7 @@ Select a variant that is suitable for your workflow. ```yaml title=".gitlab-ci.yml" variables: - UV_VERSION: "0.11.13" + UV_VERSION: "0.11.14" PYTHON_VERSION: "3.12" BASE_LAYER: trixie-slim # GitLab CI creates a separate mountpoint for the build directory, diff --git a/docs/guides/integration/pre-commit.md b/docs/guides/integration/pre-commit.md index b68b9d4cda7e2..4df3dbbf98a15 100644 --- a/docs/guides/integration/pre-commit.md +++ b/docs/guides/integration/pre-commit.md @@ -19,7 +19,7 @@ To make sure your `uv.lock` file is up to date even if your `pyproject.toml` fil repos: - repo: https://github.com/astral-sh/uv-pre-commit # uv version. - rev: 0.11.13 + rev: 0.11.14 hooks: - id: uv-lock ``` @@ -30,7 +30,7 @@ To keep a `requirements.txt` file in sync with your `uv.lock` file: repos: - repo: https://github.com/astral-sh/uv-pre-commit # uv version. - rev: 0.11.13 + rev: 0.11.14 hooks: - id: uv-export ``` @@ -41,7 +41,7 @@ To compile requirements files: repos: - repo: https://github.com/astral-sh/uv-pre-commit # uv version. - rev: 0.11.13 + rev: 0.11.14 hooks: # Compile requirements - id: pip-compile @@ -54,7 +54,7 @@ To compile alternative requirements files, modify `args` and `files`: repos: - repo: https://github.com/astral-sh/uv-pre-commit # uv version. - rev: 0.11.13 + rev: 0.11.14 hooks: # Compile requirements - id: pip-compile @@ -68,7 +68,7 @@ To run the hook over multiple files at the same time, add additional entries: repos: - repo: https://github.com/astral-sh/uv-pre-commit # uv version. - rev: 0.11.13 + rev: 0.11.14 hooks: # Compile requirements - id: pip-compile diff --git a/pyproject.toml b/pyproject.toml index 956927b447984..a299e87be4945 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "uv" -version = "0.11.13" +version = "0.11.14" description = "An extremely fast Python package and project manager, written in Rust." authors = [{ name = "Astral Software Inc.", email = "hey@astral.sh" }] requires-python = ">=3.8" diff --git a/uv.lock b/uv.lock index f1bfb3608b61d..2decd091be45a 100644 --- a/uv.lock +++ b/uv.lock @@ -934,7 +934,7 @@ wheels = [ [[package]] name = "uv" -version = "0.11.13" +version = "0.11.14" source = { editable = "." } [package.dev-dependencies]