From c946e472fb06c4266e53114eebc6964672df9817 Mon Sep 17 00:00:00 2001
From: Charlie Marsh <charlie.r.marsh@gmail.com>
Date: Mon, 13 Jan 2025 12:43:11 -0500
Subject: [PATCH] Don't treat `setuptools` and `wheel` as seed packages in uv
 sync on Python 3.12 (#10572)

## Summary

Closes https://github.com/astral-sh/uv/issues/10566.
---
 crates/uv-installer/src/plan.rs | 20 ++++++++++++++------
 crates/uv/src/commands/venv.rs  | 12 ++++++------
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/crates/uv-installer/src/plan.rs b/crates/uv-installer/src/plan.rs
index 4207e3bc1711..09b4af611e88 100644
--- a/crates/uv-installer/src/plan.rs
+++ b/crates/uv-installer/src/plan.rs
@@ -351,12 +351,7 @@ impl<'a> Planner<'a> {
             // (2) the `--seed` argument was not passed to `uv venv`.
             let seed_packages = !venv.cfg().is_ok_and(|cfg| cfg.is_uv() && !cfg.is_seed());
             for dist_info in site_packages {
-                if seed_packages
-                    && matches!(
-                        dist_info.name().as_ref(),
-                        "pip" | "setuptools" | "wheel" | "uv"
-                    )
-                {
+                if seed_packages && is_seed_package(&dist_info, venv) {
                     debug!("Preserving seed package: {dist_info}");
                     continue;
                 }
@@ -375,6 +370,19 @@ impl<'a> Planner<'a> {
     }
 }
 
+/// Returns `true` if the given distribution is a seed package.
+fn is_seed_package(dist_info: &InstalledDist, venv: &PythonEnvironment) -> bool {
+    if venv.interpreter().python_tuple() >= (3, 12) {
+        matches!(dist_info.name().as_ref(), "uv" | "pip")
+    } else {
+        // Include `setuptools` and `wheel` on Python <3.12.
+        matches!(
+            dist_info.name().as_ref(),
+            "pip" | "setuptools" | "wheel" | "uv"
+        )
+    }
+}
+
 #[derive(Debug, Default)]
 pub struct Plan {
     /// The distributions that are not already installed in the current environment, but are
diff --git a/crates/uv/src/commands/venv.rs b/crates/uv/src/commands/venv.rs
index 6b7c10f95f34..f6a731ebbfcb 100644
--- a/crates/uv/src/commands/venv.rs
+++ b/crates/uv/src/commands/venv.rs
@@ -340,17 +340,17 @@ async fn venv_impl(
         );
 
         // Resolve the seed packages.
-        let requirements = if interpreter.python_tuple() < (3, 12) {
-            // Only include `setuptools` and `wheel` on Python <3.12
+        let requirements = if interpreter.python_tuple() >= (3, 12) {
+            vec![Requirement::from(
+                uv_pep508::Requirement::from_str("pip").unwrap(),
+            )]
+        } else {
+            // Include `setuptools` and `wheel` on Python <3.12.
             vec![
                 Requirement::from(uv_pep508::Requirement::from_str("pip").unwrap()),
                 Requirement::from(uv_pep508::Requirement::from_str("setuptools").unwrap()),
                 Requirement::from(uv_pep508::Requirement::from_str("wheel").unwrap()),
             ]
-        } else {
-            vec![Requirement::from(
-                uv_pep508::Requirement::from_str("pip").unwrap(),
-            )]
         };
 
         let build_stack = BuildStack::default();