Make direct dependency detection respect markers (#2207)

## Summary

When determining "direct" dependencies, we need to ensure that we
respect markers. In the linked issue, the user had an optional
dependency like:

```toml
[project.optional-dependencies]
dev = [
  "setuptools>=64",
  "setuptools_scm>=8"
]
```

By not respecting markers, we tried to resolve `setuptools` to the
lowest-available version. However, since `setuptools>=64` _isn't_
enabled (since it's optional), we won't respect _that_ constraint.

To be consistent, we need to omit optional dependencies just as we will
at resolution time.

Closes https://github.com/astral-sh/uv/issues/2203.

## Test Plan

`cargo test`
This commit is contained in:
Charlie Marsh 2024-03-05 09:25:06 -08:00 committed by GitHub
parent 7f07ada24c
commit 8620b5a52f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 135 additions and 57 deletions

View file

@ -1,5 +1,6 @@
use rustc_hash::FxHashSet;
use pep508_rs::MarkerEnvironment;
use uv_normalize::PackageName;
use crate::Manifest;
@ -31,7 +32,11 @@ pub(crate) enum ResolutionStrategy {
}
impl ResolutionStrategy {
pub(crate) fn from_mode(mode: ResolutionMode, manifest: &Manifest) -> Self {
pub(crate) fn from_mode(
mode: ResolutionMode,
manifest: &Manifest,
markers: &MarkerEnvironment,
) -> Self {
match mode {
ResolutionMode::Highest => Self::Highest,
ResolutionMode::Lowest => Self::Lowest,
@ -40,12 +45,12 @@ impl ResolutionStrategy {
manifest
.requirements
.iter()
.chain(
manifest
.editables
.iter()
.flat_map(|(_editable, metadata)| metadata.requires_dist.iter()),
)
.filter(|requirement| requirement.evaluate_markers(markers, &[]))
.chain(manifest.editables.iter().flat_map(|(editable, metadata)| {
metadata.requires_dist.iter().filter(|requirement| {
requirement.evaluate_markers(markers, &editable.extras)
})
}))
.map(|requirement| requirement.name.clone())
.collect(),
),