Filter irrelevant requirements from source annotations (#3479)
## Summary If a requirement is omitted due to a marker expression, we shouldn't include it as the "source" of a package in the output. For example, if your constraints include `pathspec ; python_version < '3.12'`, and you're on Python 3.12, we should _not_ include the constraint file as a "source" in the output annotations.
This commit is contained in:
@@ -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(
|
||||
@@ -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,
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user