diff --git a/crates/uv-requirements/src/lookahead.rs b/crates/uv-requirements/src/lookahead.rs index 604b58147..83a3e018a 100644 --- a/crates/uv-requirements/src/lookahead.rs +++ b/crates/uv-requirements/src/lookahead.rs @@ -12,6 +12,7 @@ use pypi_types::{Requirement, RequirementSource}; use uv_configuration::{Constraints, Overrides}; use uv_distribution::{DistributionDatabase, Reporter}; use uv_git::GitUrl; +use uv_normalize::GroupName; use uv_resolver::{InMemoryIndex, MetadataResponse}; use uv_types::{BuildContext, HashStrategy, RequestedRequirements}; @@ -48,6 +49,8 @@ pub struct LookaheadResolver<'a, Context: BuildContext> { constraints: &'a Constraints, /// The overrides for the project. overrides: &'a Overrides, + /// The development dependency groups for the project. + dev: &'a [GroupName], /// The required hashes for the project. hasher: &'a HashStrategy, /// The in-memory index for resolving dependencies. @@ -63,6 +66,7 @@ impl<'a, Context: BuildContext> LookaheadResolver<'a, Context> { requirements: &'a [Requirement], constraints: &'a Constraints, overrides: &'a Overrides, + dev: &'a [GroupName], hasher: &'a HashStrategy, index: &'a InMemoryIndex, database: DistributionDatabase<'a, Context>, @@ -71,6 +75,7 @@ impl<'a, Context: BuildContext> LookaheadResolver<'a, Context> { requirements, constraints, overrides, + dev, hasher, index, database, @@ -149,7 +154,7 @@ impl<'a, Context: BuildContext> LookaheadResolver<'a, Context> { }; // Fetch the metadata for the distribution. - let requires_dist = { + let metadata = { let id = dist.version_id(); if let Some(archive) = self.index @@ -165,7 +170,7 @@ impl<'a, Context: BuildContext> LookaheadResolver<'a, Context> { }) { // If the metadata is already in the index, return it. - archive.metadata.requires_dist.clone() + archive.metadata.clone() } else { // Run the PEP 517 build process to extract metadata from the source distribution. let archive = self @@ -179,20 +184,34 @@ impl<'a, Context: BuildContext> LookaheadResolver<'a, Context> { } })?; - let requires_dist = archive.metadata.requires_dist.clone(); + let metadata = archive.metadata.clone(); // Insert the metadata into the index. self.index .distributions() .done(id, Arc::new(MetadataResponse::Found(archive))); - requires_dist + metadata } }; // Respect recursive extras by propagating the source extras to the dependencies. - let requires_dist = requires_dist + let requires_dist = metadata + .requires_dist .into_iter() + .chain( + metadata + .dev_dependencies + .into_iter() + .filter_map(|(group, dependencies)| { + if self.dev.contains(&group) { + Some(dependencies) + } else { + None + } + }) + .flatten(), + ) .map(|dependency| { if dependency.name == requirement.name { Requirement { diff --git a/crates/uv/src/commands/pip/compile.rs b/crates/uv/src/commands/pip/compile.rs index 1b021877f..f1deb01bf 100644 --- a/crates/uv/src/commands/pip/compile.rs +++ b/crates/uv/src/commands/pip/compile.rs @@ -437,6 +437,7 @@ pub(crate) async fn pip_compile( &requirements, &constraints, &overrides, + &dev, &hasher, &top_level_index, DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads, preview), diff --git a/crates/uv/src/commands/pip/operations.rs b/crates/uv/src/commands/pip/operations.rs index 0de3f08c0..17ca692e5 100644 --- a/crates/uv/src/commands/pip/operations.rs +++ b/crates/uv/src/commands/pip/operations.rs @@ -197,6 +197,7 @@ pub(crate) async fn resolve( &requirements, &constraints, &overrides, + &dev, hasher, index, DistributionDatabase::new(client, build_dispatch, concurrency.downloads, preview), diff --git a/crates/uv/tests/lock.rs b/crates/uv/tests/lock.rs index 5968be859..450c7e457 100644 --- a/crates/uv/tests/lock.rs +++ b/crates/uv/tests/lock.rs @@ -2443,7 +2443,7 @@ fn lock_dev() -> Result<()> { dependencies = ["iniconfig"] [tool.uv] - dev-dependencies = ["typing-extensions"] + dev-dependencies = ["typing-extensions @ https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl"] "#, )?; @@ -2489,15 +2489,14 @@ fn lock_dev() -> Result<()> { [[distribution.dev-dependencies.dev]] name = "typing-extensions" - version = "4.10.0" - source = "registry+https://pypi.org/simple" + version = "4.12.2" + source = "direct+https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl" [[distribution]] name = "typing-extensions" - version = "4.10.0" - source = "registry+https://pypi.org/simple" - sdist = { url = "https://files.pythonhosted.org/packages/16/3a/0d26ce356c7465a19c9ea8814b960f8a36c3b0d07c323176620b7b483e44/typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb", size = 77558 } - wheels = [{ url = "https://files.pythonhosted.org/packages/f9/de/dc04a3ea60b22624b51c703a84bbe0184abcd1d0b9bc8074b5d6b7ab90bb/typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", size = 33926 }] + version = "4.12.2" + source = "direct+https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl" + wheels = [{ url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d" }] "### ); }); @@ -2524,9 +2523,8 @@ fn lock_dev() -> Result<()> { ----- stderr ----- warning: `uv sync` is experimental and may change without warning. - Downloaded 1 package in [TIME] Installed 1 package in [TIME] - + typing-extensions==4.10.0 + + typing-extensions==4.12.2 (from https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl) "###); Ok(())