Skip to content

Commit

Permalink
Filter incompatible deps
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed May 9, 2024
1 parent ff16b1a commit 4f6032b
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 38 deletions.
76 changes: 41 additions & 35 deletions crates/uv-resolver/src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,46 +102,52 @@ impl Manifest {
) -> impl Iterator<Item = &Requirement> {
match mode {
// Include all direct and transitive requirements, with constraints and overrides applied.
DependencyMode::Transitive => Either::Left( self
.lookaheads
.iter()
.flat_map(|lookahead| {
self.overrides
.apply(lookahead.requirements())
.filter(|requirement| {
requirement.evaluate_markers(markers, lookahead.extras())
DependencyMode::Transitive => {
Either::Left(
self.lookaheads
.iter()
.flat_map(|lookahead| {
self.overrides
.apply(lookahead.requirements())
.filter(|requirement| {
requirement.evaluate_markers(markers, lookahead.extras())
})
})
})
.chain(self.editables.iter().flat_map(|(editable, _metadata, requirements)| {
self.overrides
.apply(&requirements.dependencies)
.filter(|requirement| {
requirement.evaluate_markers(markers, &editable.extras)
})
}))
.chain(
self.overrides
.apply(&self.requirements)
.filter(|requirement| requirement.evaluate_markers(markers, &[])),
)
.chain(
self.constraints
.requirements()
.filter(|requirement| requirement.evaluate_markers(markers, &[])),
.chain(self.editables.iter().flat_map(
|(editable, _metadata, requirements)| {
self.overrides.apply(&requirements.dependencies).filter(
|requirement| {
requirement.evaluate_markers(markers, &editable.extras)
},
)
},
))
.chain(
self.overrides
.apply(&self.requirements)
.filter(|requirement| requirement.evaluate_markers(markers, &[])),
)
.chain(
self.constraints
.requirements()
.filter(|requirement| requirement.evaluate_markers(markers, &[])),
)
.chain(
self.overrides
.requirements()
.filter(|requirement| requirement.evaluate_markers(markers, &[])),
),
)
.chain(
self.overrides
.requirements()
.filter(|requirement| requirement.evaluate_markers(markers, &[])),
))
,
}

// Include direct requirements, with constraints and overrides applied.
DependencyMode::Direct => Either::Right(
self.overrides.apply(& self.requirements)
.chain(self.constraints.requirements())
.chain(self.overrides.requirements())
.filter(|requirement| requirement.evaluate_markers(markers, &[]))),
self.overrides
.apply(&self.requirements)
.chain(self.constraints.requirements())
.chain(self.overrides.requirements())
.filter(|requirement| requirement.evaluate_markers(markers, &[])),
),
}
}

Expand Down
15 changes: 12 additions & 3 deletions crates/uv/src/commands/pip_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,10 @@ pub(crate) async fn pip_compile(
// Generate a map from requirement to originating source file.
let mut sources = SourceAnnotations::default();

for requirement in &requirements {
for requirement in requirements
.iter()
.filter(|requirement| requirement.evaluate_markers(&markers, &[]))
{
if let Some(path) = &requirement.path {
if path.ends_with("pyproject.toml") {
sources.add(
Expand All @@ -376,7 +379,10 @@ pub(crate) async fn pip_compile(
}
}

for requirement in &constraints {
for requirement in constraints
.iter()
.filter(|requirement| requirement.evaluate_markers(&markers, &[]))
{
if let Some(path) = &requirement.path {
sources.add(
&requirement.name,
Expand All @@ -385,7 +391,10 @@ pub(crate) async fn pip_compile(
}
}

for requirement in &overrides {
for requirement in overrides
.iter()
.filter(|requirement| requirement.evaluate_markers(&markers, &[]))
{
if let Some(path) = &requirement.path {
sources.add(&requirement.name, SourceAnnotation::Override(path.clone()));
}
Expand Down
35 changes: 35 additions & 0 deletions crates/uv/tests/pip_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,41 @@ fn compile_python_dev_version() -> Result<()> {
Ok(())
}

/// Omit the constraint annotation (e.g., `# from -c constraints.txt`) when the constraint is not
/// applicable due to a marker expression.
#[test]
fn omit_non_matching_annotation() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("anyio")?;

let constraints_txt = context.temp_dir.child("constraints.txt");
constraints_txt.write_str("idna <3.7; python_version < '3.7'")?;

uv_snapshot!(context.compile()
.arg("requirements.in")
.arg("-c")
.arg("constraints.txt"), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in -c constraints.txt
anyio==4.3.0
# via -r requirements.in
idna==3.6
# via anyio
sniffio==1.3.1
# via anyio
----- stderr -----
Resolved 3 packages in [TIME]
"###
);

Ok(())
}

/// Test that we select the last 3.8 compatible numpy version instead of trying to compile an
/// incompatible sdist <https://github.com/astral-sh/uv/issues/388>
#[test]
Expand Down

0 comments on commit 4f6032b

Please sign in to comment.