Avoid hard-error for non-existent extras (#627)

## Summary

When resolving `transformers[tensorboard]`, the `[tensorboard]` extra
doesn't exist. Previously, we returned "unknown" dependencies for this
variant, which leads the resolution to try all versions, then fail. This
PR instead warns, but returns the base dependencies for the package,
which matches `pip`. (Poetry doesn't even warn, it just proceeds as
normal.)

Arguably, it would be better to return a custom incompatibility here and
then propagate... But this PR is better than the status quo, and I don't
know if we have support for that behavior yet...? (\cc @zanieb)

Closes #386.

Closes https://github.com/astral-sh/puffin/issues/423.
This commit is contained in:
Charlie Marsh 2023-12-13 12:36:27 -05:00 committed by GitHub
parent 5c38825b93
commit eb1a630db2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 351 additions and 96 deletions

View file

@ -19,7 +19,7 @@ use puffin_cache::Cache;
use puffin_client::RegistryClientBuilder;
use puffin_interpreter::{Interpreter, Virtualenv};
use puffin_resolver::{
Graph, Manifest, PreReleaseMode, ResolutionMode, ResolutionOptions, Resolver,
Manifest, PreReleaseMode, ResolutionGraph, ResolutionMode, ResolutionOptions, Resolver,
};
use puffin_traits::{BuildContext, SourceBuildTrait};
@ -97,7 +97,7 @@ async fn resolve(
options: ResolutionOptions,
markers: &'static MarkerEnvironment,
tags: &Tags,
) -> Result<Graph> {
) -> Result<ResolutionGraph> {
let client = RegistryClientBuilder::new(Cache::temp()?).build();
let build_context = DummyContext {
cache: Cache::temp()?,
@ -161,6 +161,31 @@ async fn black_colorama() -> Result<()> {
Ok(())
}
/// Resolve Black with an invalid extra. The resolver should ignore the extra.
#[tokio::test]
async fn black_tensorboard() -> Result<()> {
colored::control::set_override(false);
let manifest = Manifest::new(
vec![Requirement::from_str("black[tensorboard]<=23.9.1").unwrap()],
vec![],
vec![],
vec![],
None,
);
let options = ResolutionOptions::new(
ResolutionMode::default(),
PreReleaseMode::default(),
Some(*EXCLUDE_NEWER),
);
let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?;
insta::assert_display_snapshot!(resolution);
Ok(())
}
#[tokio::test]
async fn black_python_310() -> Result<()> {
colored::control::set_override(false);

View file

@ -0,0 +1,16 @@
---
source: crates/puffin-resolver/tests/resolver.rs
expression: resolution
---
black==23.9.1
click==8.1.7
# via black
mypy-extensions==1.0.0
# via black
packaging==23.2
# via black
pathspec==0.11.2
# via black
platformdirs==4.0.0
# via black