mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Make version selection wheel-vs.-sdist-agnostic (#232)
Closes https://github.com/astral-sh/puffin/issues/231.
This commit is contained in:
parent
8d992dca3f
commit
0be20a41a4
4 changed files with 49 additions and 98 deletions
|
@ -156,96 +156,63 @@ impl CandidateSelector {
|
||||||
range: &Range<PubGrubVersion>,
|
range: &Range<PubGrubVersion>,
|
||||||
allow_prerelease: AllowPreRelease,
|
allow_prerelease: AllowPreRelease,
|
||||||
) -> Option<Candidate> {
|
) -> Option<Candidate> {
|
||||||
// We prefer a stable wheel, followed by a prerelease wheel, followed by a stable sdist,
|
#[derive(Debug)]
|
||||||
// followed by a prerelease sdist.
|
enum PreReleaseCandidate<'a> {
|
||||||
let mut sdist = None;
|
NotNecessary,
|
||||||
let mut prerelease_sdist = None;
|
IfNecessary(&'a PubGrubVersion, &'a DistributionFile),
|
||||||
let mut prerelease_wheel = None;
|
}
|
||||||
|
|
||||||
|
let mut prerelease = None;
|
||||||
for (version, file) in versions {
|
for (version, file) in versions {
|
||||||
if range.contains(version) {
|
if version.any_prerelease() {
|
||||||
match file {
|
if range.contains(version) {
|
||||||
DistributionFile::Wheel(_) => {
|
match allow_prerelease {
|
||||||
if version.any_prerelease() {
|
AllowPreRelease::Yes => {
|
||||||
match allow_prerelease {
|
// If pre-releases are allowed, treat them equivalently
|
||||||
AllowPreRelease::Yes => {
|
// to stable distributions.
|
||||||
// If prereleases are allowed, treat them equivalently
|
|
||||||
// to stable wheels.
|
|
||||||
return Some(Candidate {
|
|
||||||
package_name: package_name.clone(),
|
|
||||||
version: version.clone(),
|
|
||||||
file: file.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
AllowPreRelease::IfNecessary => {
|
|
||||||
// If prereleases are allowed as a fallback, store the
|
|
||||||
// first-matching prerelease wheel.
|
|
||||||
if prerelease_wheel.is_none() {
|
|
||||||
prerelease_wheel = Some(Candidate {
|
|
||||||
package_name: package_name.clone(),
|
|
||||||
version: version.clone(),
|
|
||||||
file: file.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AllowPreRelease::No => {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Always return the first-matching stable wheel.
|
|
||||||
return Some(Candidate {
|
return Some(Candidate {
|
||||||
package_name: package_name.clone(),
|
package_name: package_name.clone(),
|
||||||
version: version.clone(),
|
version: version.clone(),
|
||||||
file: file.clone(),
|
file: file.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
AllowPreRelease::IfNecessary => {
|
||||||
DistributionFile::Sdist(_) => {
|
// If pre-releases are allowed as a fallback, store the
|
||||||
if version.any_prerelease() {
|
// first-matching prerelease.
|
||||||
match allow_prerelease {
|
if prerelease.is_none() {
|
||||||
AllowPreRelease::Yes => {
|
prerelease = Some(PreReleaseCandidate::IfNecessary(version, file));
|
||||||
// If prereleases are allowed, treat them equivalently to
|
|
||||||
// stable sdists.
|
|
||||||
if sdist.is_none() {
|
|
||||||
sdist = Some(Candidate {
|
|
||||||
package_name: package_name.clone(),
|
|
||||||
version: version.clone(),
|
|
||||||
file: file.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AllowPreRelease::IfNecessary => {
|
|
||||||
// If prereleases are allowed as a fallback, store the
|
|
||||||
// first-matching prerelease sdist.
|
|
||||||
if prerelease_sdist.is_none() {
|
|
||||||
prerelease_sdist = Some(Candidate {
|
|
||||||
package_name: package_name.clone(),
|
|
||||||
version: version.clone(),
|
|
||||||
file: file.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AllowPreRelease::No => {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Store the first-matching stable sdist.
|
|
||||||
if sdist.is_none() {
|
|
||||||
sdist = Some(Candidate {
|
|
||||||
package_name: package_name.clone(),
|
|
||||||
version: version.clone(),
|
|
||||||
file: file.clone(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AllowPreRelease::No => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// If we have at least one stable release, we shouldn't allow the "if-necessary"
|
||||||
|
// pre-release strategy, regardless of whether that stable release satisfies the
|
||||||
|
// current range.
|
||||||
|
prerelease = Some(PreReleaseCandidate::NotNecessary);
|
||||||
|
|
||||||
|
// Always return the first-matching stable distribution.
|
||||||
|
if range.contains(version) {
|
||||||
|
return Some(Candidate {
|
||||||
|
package_name: package_name.clone(),
|
||||||
|
version: version.clone(),
|
||||||
|
file: file.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
match prerelease {
|
||||||
sdist.or(prerelease_wheel).or(prerelease_sdist)
|
None => None,
|
||||||
|
Some(PreReleaseCandidate::NotNecessary) => None,
|
||||||
|
Some(PreReleaseCandidate::IfNecessary(version, file)) => Some(Candidate {
|
||||||
|
package_name: package_name.clone(),
|
||||||
|
version: version.clone(),
|
||||||
|
file: file.clone(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -515,11 +515,10 @@ impl<'a, Context: BuildContext + Sync> Resolver<'a, Context> {
|
||||||
if let Ok(name) = WheelFilename::from_str(file.filename.as_str()) {
|
if let Ok(name) = WheelFilename::from_str(file.filename.as_str()) {
|
||||||
if name.is_compatible(self.tags) {
|
if name.is_compatible(self.tags) {
|
||||||
let version = PubGrubVersion::from(name.version);
|
let version = PubGrubVersion::from(name.version);
|
||||||
|
|
||||||
match version_map.entry(version) {
|
match version_map.entry(version) {
|
||||||
std::collections::btree_map::Entry::Occupied(mut entry) => {
|
std::collections::btree_map::Entry::Occupied(mut entry) => {
|
||||||
if let DistributionFile::Sdist(_) = entry.get() {
|
if matches!(entry.get(), DistributionFile::Sdist(_)) {
|
||||||
// Wheels get precedence over source distributions
|
// Wheels get precedence over source distributions.
|
||||||
entry.insert(DistributionFile::from(WheelFile::from(
|
entry.insert(DistributionFile::from(WheelFile::from(
|
||||||
file,
|
file,
|
||||||
)));
|
)));
|
||||||
|
|
|
@ -134,7 +134,7 @@ async fn black_mypy_extensions() -> Result<()> {
|
||||||
|
|
||||||
let manifest = Manifest::new(
|
let manifest = Manifest::new(
|
||||||
vec![Requirement::from_str("black<=23.9.1").unwrap()],
|
vec![Requirement::from_str("black<=23.9.1").unwrap()],
|
||||||
vec![Requirement::from_str("mypy-extensions<1").unwrap()],
|
vec![Requirement::from_str("mypy-extensions<0.4.4").unwrap()],
|
||||||
vec![],
|
vec![],
|
||||||
ResolutionMode::default(),
|
ResolutionMode::default(),
|
||||||
PreReleaseMode::default(),
|
PreReleaseMode::default(),
|
||||||
|
@ -158,7 +158,7 @@ async fn black_mypy_extensions_extra() -> Result<()> {
|
||||||
|
|
||||||
let manifest = Manifest::new(
|
let manifest = Manifest::new(
|
||||||
vec![Requirement::from_str("black<=23.9.1").unwrap()],
|
vec![Requirement::from_str("black<=23.9.1").unwrap()],
|
||||||
vec![Requirement::from_str("mypy-extensions[extra]<1").unwrap()],
|
vec![Requirement::from_str("mypy-extensions[extra]<0.4.4").unwrap()],
|
||||||
vec![],
|
vec![],
|
||||||
ResolutionMode::default(),
|
ResolutionMode::default(),
|
||||||
PreReleaseMode::default(),
|
PreReleaseMode::default(),
|
||||||
|
@ -321,7 +321,7 @@ async fn black_allow_prerelease_if_necessary() -> Result<()> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let resolver = Resolver::new(manifest, &MARKERS_311, &TAGS_311, &client, &DummyContext);
|
let resolver = Resolver::new(manifest, &MARKERS_311, &TAGS_311, &client, &DummyContext);
|
||||||
let resolution = resolver.resolve().await?;
|
let resolution = resolver.resolve().await.unwrap_err();
|
||||||
|
|
||||||
insta::assert_display_snapshot!(resolution);
|
insta::assert_display_snapshot!(resolution);
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,4 @@
|
||||||
source: crates/puffin-resolver/tests/resolver.rs
|
source: crates/puffin-resolver/tests/resolver.rs
|
||||||
expression: resolution
|
expression: resolution
|
||||||
---
|
---
|
||||||
appdirs==1.4.4
|
No solution
|
||||||
# via black
|
|
||||||
attrs==23.1.0
|
|
||||||
# via black
|
|
||||||
black==19.10b0
|
|
||||||
click==8.1.7
|
|
||||||
# via black
|
|
||||||
pathspec==0.11.2
|
|
||||||
# via black
|
|
||||||
regex==2023.10.3
|
|
||||||
# via black
|
|
||||||
toml==0.10.2
|
|
||||||
# via black
|
|
||||||
typed-ast==1.5.5
|
|
||||||
# via black
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue