Avoid extra-only filtering for constraints (#4095)

## Summary

The "only include if relevant for the extra" filtering should _not_ be
applied to constraints. Otherwise, we'd only constrain when the extra
was included in the constraints file itself, which is incorrect.

Closes https://github.com/astral-sh/uv/issues/4091.
This commit is contained in:
Charlie Marsh 2024-06-06 09:58:46 -04:00 committed by GitHub
parent 39f8978920
commit 8798e91dd5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 3 deletions

View file

@ -97,6 +97,7 @@ fn add_requirements(
// If the requirement isn't relevant for the current platform, skip it. // If the requirement isn't relevant for the current platform, skip it.
match source_extra { match source_extra {
Some(source_extra) => { Some(source_extra) => {
// Only include requirements that are relevant for the current extra.
if requirement.evaluate_markers(env, &[]) { if requirement.evaluate_markers(env, &[]) {
continue; continue;
} }
@ -167,9 +168,6 @@ fn add_requirements(
// If the requirement isn't relevant for the current platform, skip it. // If the requirement isn't relevant for the current platform, skip it.
match source_extra { match source_extra {
Some(source_extra) => { Some(source_extra) => {
if constraint.evaluate_markers(env, &[]) {
continue;
}
if !constraint.evaluate_markers(env, std::slice::from_ref(source_extra)) { if !constraint.evaluate_markers(env, std::slice::from_ref(source_extra)) {
continue; continue;
} }

View file

@ -2315,6 +2315,44 @@ fn install_constraints_inline_remote() -> Result<()> {
Ok(()) Ok(())
} }
/// Constrain a package that's included via an extra.
#[test]
fn install_constraints_extra() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("flask[dotenv]")?;
let constraints_txt = context.temp_dir.child("constraints.txt");
constraints_txt.write_str("python-dotenv==1.0.0")?;
uv_snapshot!(context.install()
.arg("-r")
.arg("requirements.txt")
.arg("-c")
.arg("constraints.txt"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 8 packages in [TIME]
Downloaded 8 packages in [TIME]
Installed 8 packages in [TIME]
+ blinker==1.7.0
+ click==8.1.7
+ flask==3.0.2
+ itsdangerous==2.1.2
+ jinja2==3.1.3
+ markupsafe==2.1.5
+ python-dotenv==1.0.0
+ werkzeug==3.0.1
"###
);
Ok(())
}
#[test] #[test]
fn install_constraints_respects_offline_mode() { fn install_constraints_respects_offline_mode() {
let context = TestContext::new("3.12"); let context = TestContext::new("3.12");