mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-22 08:12:44 +00:00
Refactor unavailable metadata to shrink the resolver (#9769)
The resolver methods are already too large and complex, especially `choose_version*`, so i wanted to shrink and simplify them a bit before adding new methods to them. I've split `MetadataResponse` into three variants: success, non-fatal error (reported through pubgrub), fatal error (reported as error trace). The resulting non-fatal `MetadataUnavailable` type is equivalent to the `IncompletePackage` type, so they are now merged. (`UnavailableVersion` is a bit different since, besides the extra `IncompatibleDist` variant, it have no error source attached). This shows that the missing metadata variant was unused, which I removed. Tagging as error messages for the logging format changes.
This commit is contained in:
parent
edf875e306
commit
b751648bfe
6 changed files with 138 additions and 256 deletions
|
@ -215,7 +215,7 @@ impl SitePackages {
|
||||||
|
|
||||||
// Determine the dependencies for the given package.
|
// Determine the dependencies for the given package.
|
||||||
let Ok(metadata) = distribution.metadata() else {
|
let Ok(metadata) = distribution.metadata() else {
|
||||||
diagnostics.push(SitePackagesDiagnostic::IncompletePackage {
|
diagnostics.push(SitePackagesDiagnostic::MetadataUnavailable {
|
||||||
package: package.clone(),
|
package: package.clone(),
|
||||||
path: distribution.path().to_owned(),
|
path: distribution.path().to_owned(),
|
||||||
});
|
});
|
||||||
|
@ -405,7 +405,7 @@ impl IntoIterator for SitePackages {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SitePackagesDiagnostic {
|
pub enum SitePackagesDiagnostic {
|
||||||
IncompletePackage {
|
MetadataUnavailable {
|
||||||
/// The package that is missing metadata.
|
/// The package that is missing metadata.
|
||||||
package: PackageName,
|
package: PackageName,
|
||||||
/// The path to the package.
|
/// The path to the package.
|
||||||
|
@ -445,7 +445,7 @@ impl Diagnostic for SitePackagesDiagnostic {
|
||||||
/// Convert the diagnostic into a user-facing message.
|
/// Convert the diagnostic into a user-facing message.
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::IncompletePackage { package, path } => format!(
|
Self::MetadataUnavailable { package, path } => format!(
|
||||||
"The package `{package}` is broken or incomplete (unable to read `METADATA`). Consider recreating the virtualenv, or removing the package directory at: {}.", path.display(),
|
"The package `{package}` is broken or incomplete (unable to read `METADATA`). Consider recreating the virtualenv, or removing the package directory at: {}.", path.display(),
|
||||||
),
|
),
|
||||||
Self::IncompatiblePythonVersion {
|
Self::IncompatiblePythonVersion {
|
||||||
|
@ -482,7 +482,7 @@ impl Diagnostic for SitePackagesDiagnostic {
|
||||||
/// Returns `true` if the [`PackageName`] is involved in this diagnostic.
|
/// Returns `true` if the [`PackageName`] is involved in this diagnostic.
|
||||||
fn includes(&self, name: &PackageName) -> bool {
|
fn includes(&self, name: &PackageName) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::IncompletePackage { package, .. } => name == package,
|
Self::MetadataUnavailable { package, .. } => name == package,
|
||||||
Self::IncompatiblePythonVersion { package, .. } => name == package,
|
Self::IncompatiblePythonVersion { package, .. } => name == package,
|
||||||
Self::MissingDependency { package, .. } => name == package,
|
Self::MissingDependency { package, .. } => name == package,
|
||||||
Self::IncompatibleDependency {
|
Self::IncompatibleDependency {
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::pubgrub::{PubGrubPackage, PubGrubPackageInner, PubGrubReportFormatter
|
||||||
use crate::python_requirement::PythonRequirement;
|
use crate::python_requirement::PythonRequirement;
|
||||||
use crate::resolution::ConflictingDistributionError;
|
use crate::resolution::ConflictingDistributionError;
|
||||||
use crate::resolver::{
|
use crate::resolver::{
|
||||||
IncompletePackage, ResolverEnvironment, UnavailablePackage, UnavailableReason,
|
MetadataUnavailable, ResolverEnvironment, UnavailablePackage, UnavailableReason,
|
||||||
};
|
};
|
||||||
use crate::Options;
|
use crate::Options;
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ pub struct NoSolutionError {
|
||||||
index_locations: IndexLocations,
|
index_locations: IndexLocations,
|
||||||
index_capabilities: IndexCapabilities,
|
index_capabilities: IndexCapabilities,
|
||||||
unavailable_packages: FxHashMap<PackageName, UnavailablePackage>,
|
unavailable_packages: FxHashMap<PackageName, UnavailablePackage>,
|
||||||
incomplete_packages: FxHashMap<PackageName, BTreeMap<Version, IncompletePackage>>,
|
incomplete_packages: FxHashMap<PackageName, BTreeMap<Version, MetadataUnavailable>>,
|
||||||
fork_urls: ForkUrls,
|
fork_urls: ForkUrls,
|
||||||
env: ResolverEnvironment,
|
env: ResolverEnvironment,
|
||||||
workspace_members: BTreeSet<PackageName>,
|
workspace_members: BTreeSet<PackageName>,
|
||||||
|
@ -163,7 +163,7 @@ impl NoSolutionError {
|
||||||
index_locations: IndexLocations,
|
index_locations: IndexLocations,
|
||||||
index_capabilities: IndexCapabilities,
|
index_capabilities: IndexCapabilities,
|
||||||
unavailable_packages: FxHashMap<PackageName, UnavailablePackage>,
|
unavailable_packages: FxHashMap<PackageName, UnavailablePackage>,
|
||||||
incomplete_packages: FxHashMap<PackageName, BTreeMap<Version, IncompletePackage>>,
|
incomplete_packages: FxHashMap<PackageName, BTreeMap<Version, MetadataUnavailable>>,
|
||||||
fork_urls: ForkUrls,
|
fork_urls: ForkUrls,
|
||||||
env: ResolverEnvironment,
|
env: ResolverEnvironment,
|
||||||
workspace_members: BTreeSet<PackageName>,
|
workspace_members: BTreeSet<PackageName>,
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::error::ErrorTree;
|
||||||
use crate::fork_urls::ForkUrls;
|
use crate::fork_urls::ForkUrls;
|
||||||
use crate::prerelease::AllowPrerelease;
|
use crate::prerelease::AllowPrerelease;
|
||||||
use crate::python_requirement::{PythonRequirement, PythonRequirementSource};
|
use crate::python_requirement::{PythonRequirement, PythonRequirementSource};
|
||||||
use crate::resolver::{IncompletePackage, UnavailablePackage, UnavailableReason};
|
use crate::resolver::{MetadataUnavailable, UnavailablePackage, UnavailableReason};
|
||||||
use crate::{Flexibility, Options, RequiresPython, ResolverEnvironment};
|
use crate::{Flexibility, Options, RequiresPython, ResolverEnvironment};
|
||||||
|
|
||||||
use super::{PubGrubPackage, PubGrubPackageInner, PubGrubPython};
|
use super::{PubGrubPackage, PubGrubPackageInner, PubGrubPython};
|
||||||
|
@ -548,7 +548,7 @@ impl PubGrubReportFormatter<'_> {
|
||||||
index_capabilities: &IndexCapabilities,
|
index_capabilities: &IndexCapabilities,
|
||||||
available_indexes: &FxHashMap<PackageName, BTreeSet<IndexUrl>>,
|
available_indexes: &FxHashMap<PackageName, BTreeSet<IndexUrl>>,
|
||||||
unavailable_packages: &FxHashMap<PackageName, UnavailablePackage>,
|
unavailable_packages: &FxHashMap<PackageName, UnavailablePackage>,
|
||||||
incomplete_packages: &FxHashMap<PackageName, BTreeMap<Version, IncompletePackage>>,
|
incomplete_packages: &FxHashMap<PackageName, BTreeMap<Version, MetadataUnavailable>>,
|
||||||
fork_urls: &ForkUrls,
|
fork_urls: &ForkUrls,
|
||||||
env: &ResolverEnvironment,
|
env: &ResolverEnvironment,
|
||||||
workspace_members: &BTreeSet<PackageName>,
|
workspace_members: &BTreeSet<PackageName>,
|
||||||
|
@ -679,7 +679,7 @@ impl PubGrubReportFormatter<'_> {
|
||||||
index_capabilities: &IndexCapabilities,
|
index_capabilities: &IndexCapabilities,
|
||||||
available_indexes: &FxHashMap<PackageName, BTreeSet<IndexUrl>>,
|
available_indexes: &FxHashMap<PackageName, BTreeSet<IndexUrl>>,
|
||||||
unavailable_packages: &FxHashMap<PackageName, UnavailablePackage>,
|
unavailable_packages: &FxHashMap<PackageName, UnavailablePackage>,
|
||||||
incomplete_packages: &FxHashMap<PackageName, BTreeMap<Version, IncompletePackage>>,
|
incomplete_packages: &FxHashMap<PackageName, BTreeMap<Version, MetadataUnavailable>>,
|
||||||
hints: &mut IndexSet<PubGrubHint>,
|
hints: &mut IndexSet<PubGrubHint>,
|
||||||
) {
|
) {
|
||||||
let no_find_links = index_locations.flat_indexes().peekable().peek().is_none();
|
let no_find_links = index_locations.flat_indexes().peekable().peek().is_none();
|
||||||
|
@ -694,11 +694,6 @@ impl PubGrubReportFormatter<'_> {
|
||||||
Some(UnavailablePackage::Offline) => {
|
Some(UnavailablePackage::Offline) => {
|
||||||
hints.insert(PubGrubHint::Offline);
|
hints.insert(PubGrubHint::Offline);
|
||||||
}
|
}
|
||||||
Some(UnavailablePackage::MissingMetadata) => {
|
|
||||||
hints.insert(PubGrubHint::MissingPackageMetadata {
|
|
||||||
package: package.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Some(UnavailablePackage::InvalidMetadata(reason)) => {
|
Some(UnavailablePackage::InvalidMetadata(reason)) => {
|
||||||
hints.insert(PubGrubHint::InvalidPackageMetadata {
|
hints.insert(PubGrubHint::InvalidPackageMetadata {
|
||||||
package: package.clone(),
|
package: package.clone(),
|
||||||
|
@ -720,37 +715,31 @@ impl PubGrubReportFormatter<'_> {
|
||||||
for (version, incomplete) in versions.iter().rev() {
|
for (version, incomplete) in versions.iter().rev() {
|
||||||
if set.contains(version) {
|
if set.contains(version) {
|
||||||
match incomplete {
|
match incomplete {
|
||||||
IncompletePackage::Offline => {
|
MetadataUnavailable::Offline => {
|
||||||
hints.insert(PubGrubHint::Offline);
|
hints.insert(PubGrubHint::Offline);
|
||||||
}
|
}
|
||||||
IncompletePackage::MissingMetadata => {
|
MetadataUnavailable::InvalidMetadata(reason) => {
|
||||||
hints.insert(PubGrubHint::MissingVersionMetadata {
|
|
||||||
package: package.clone(),
|
|
||||||
version: version.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
IncompletePackage::InvalidMetadata(reason) => {
|
|
||||||
hints.insert(PubGrubHint::InvalidVersionMetadata {
|
hints.insert(PubGrubHint::InvalidVersionMetadata {
|
||||||
package: package.clone(),
|
package: package.clone(),
|
||||||
version: version.clone(),
|
version: version.clone(),
|
||||||
reason: reason.clone(),
|
reason: reason.to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
IncompletePackage::InconsistentMetadata(reason) => {
|
MetadataUnavailable::InconsistentMetadata(reason) => {
|
||||||
hints.insert(PubGrubHint::InconsistentVersionMetadata {
|
hints.insert(PubGrubHint::InconsistentVersionMetadata {
|
||||||
package: package.clone(),
|
package: package.clone(),
|
||||||
version: version.clone(),
|
version: version.clone(),
|
||||||
reason: reason.clone(),
|
reason: reason.to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
IncompletePackage::InvalidStructure(reason) => {
|
MetadataUnavailable::InvalidStructure(reason) => {
|
||||||
hints.insert(PubGrubHint::InvalidVersionStructure {
|
hints.insert(PubGrubHint::InvalidVersionStructure {
|
||||||
package: package.clone(),
|
package: package.clone(),
|
||||||
version: version.clone(),
|
version: version.clone(),
|
||||||
reason: reason.clone(),
|
reason: reason.to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
IncompletePackage::RequiresPython(requires_python, python_version) => {
|
MetadataUnavailable::RequiresPython(requires_python, python_version) => {
|
||||||
hints.insert(PubGrubHint::IncompatibleBuildRequirement {
|
hints.insert(PubGrubHint::IncompatibleBuildRequirement {
|
||||||
package: package.clone(),
|
package: package.clone(),
|
||||||
version: version.clone(),
|
version: version.clone(),
|
||||||
|
@ -882,8 +871,6 @@ pub(crate) enum PubGrubHint {
|
||||||
NoIndex,
|
NoIndex,
|
||||||
/// A package was not found in the registry, but network access was disabled.
|
/// A package was not found in the registry, but network access was disabled.
|
||||||
Offline,
|
Offline,
|
||||||
/// Metadata for a package could not be found.
|
|
||||||
MissingPackageMetadata { package: PubGrubPackage },
|
|
||||||
/// Metadata for a package could not be parsed.
|
/// Metadata for a package could not be parsed.
|
||||||
InvalidPackageMetadata {
|
InvalidPackageMetadata {
|
||||||
package: PubGrubPackage,
|
package: PubGrubPackage,
|
||||||
|
@ -896,12 +883,6 @@ pub(crate) enum PubGrubHint {
|
||||||
// excluded from `PartialEq` and `Hash`
|
// excluded from `PartialEq` and `Hash`
|
||||||
reason: String,
|
reason: String,
|
||||||
},
|
},
|
||||||
/// Metadata for a package version could not be found.
|
|
||||||
MissingVersionMetadata {
|
|
||||||
package: PubGrubPackage,
|
|
||||||
// excluded from `PartialEq` and `Hash`
|
|
||||||
version: Version,
|
|
||||||
},
|
|
||||||
/// Metadata for a package version could not be parsed.
|
/// Metadata for a package version could not be parsed.
|
||||||
InvalidVersionMetadata {
|
InvalidVersionMetadata {
|
||||||
package: PubGrubPackage,
|
package: PubGrubPackage,
|
||||||
|
@ -992,18 +973,12 @@ enum PubGrubHintCore {
|
||||||
},
|
},
|
||||||
NoIndex,
|
NoIndex,
|
||||||
Offline,
|
Offline,
|
||||||
MissingPackageMetadata {
|
|
||||||
package: PubGrubPackage,
|
|
||||||
},
|
|
||||||
InvalidPackageMetadata {
|
InvalidPackageMetadata {
|
||||||
package: PubGrubPackage,
|
package: PubGrubPackage,
|
||||||
},
|
},
|
||||||
InvalidPackageStructure {
|
InvalidPackageStructure {
|
||||||
package: PubGrubPackage,
|
package: PubGrubPackage,
|
||||||
},
|
},
|
||||||
MissingVersionMetadata {
|
|
||||||
package: PubGrubPackage,
|
|
||||||
},
|
|
||||||
InvalidVersionMetadata {
|
InvalidVersionMetadata {
|
||||||
package: PubGrubPackage,
|
package: PubGrubPackage,
|
||||||
},
|
},
|
||||||
|
@ -1052,18 +1027,12 @@ impl From<PubGrubHint> for PubGrubHintCore {
|
||||||
}
|
}
|
||||||
PubGrubHint::NoIndex => Self::NoIndex,
|
PubGrubHint::NoIndex => Self::NoIndex,
|
||||||
PubGrubHint::Offline => Self::Offline,
|
PubGrubHint::Offline => Self::Offline,
|
||||||
PubGrubHint::MissingPackageMetadata { package, .. } => {
|
|
||||||
Self::MissingPackageMetadata { package }
|
|
||||||
}
|
|
||||||
PubGrubHint::InvalidPackageMetadata { package, .. } => {
|
PubGrubHint::InvalidPackageMetadata { package, .. } => {
|
||||||
Self::InvalidPackageMetadata { package }
|
Self::InvalidPackageMetadata { package }
|
||||||
}
|
}
|
||||||
PubGrubHint::InvalidPackageStructure { package, .. } => {
|
PubGrubHint::InvalidPackageStructure { package, .. } => {
|
||||||
Self::InvalidPackageStructure { package }
|
Self::InvalidPackageStructure { package }
|
||||||
}
|
}
|
||||||
PubGrubHint::MissingVersionMetadata { package, .. } => {
|
|
||||||
Self::MissingVersionMetadata { package }
|
|
||||||
}
|
|
||||||
PubGrubHint::InvalidVersionMetadata { package, .. } => {
|
PubGrubHint::InvalidVersionMetadata { package, .. } => {
|
||||||
Self::InvalidVersionMetadata { package }
|
Self::InvalidVersionMetadata { package }
|
||||||
}
|
}
|
||||||
|
@ -1162,15 +1131,6 @@ impl std::fmt::Display for PubGrubHint {
|
||||||
":".bold(),
|
":".bold(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Self::MissingPackageMetadata { package } => {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{}{} Metadata for `{}` could not be found, as the wheel is missing a `METADATA` file",
|
|
||||||
"hint".bold().cyan(),
|
|
||||||
":".bold(),
|
|
||||||
package.bold()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Self::InvalidPackageMetadata { package, reason } => {
|
Self::InvalidPackageMetadata { package, reason } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
@ -1191,16 +1151,6 @@ impl std::fmt::Display for PubGrubHint {
|
||||||
textwrap::indent(reason, " ")
|
textwrap::indent(reason, " ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Self::MissingVersionMetadata { package, version } => {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{}{} Metadata for `{}` ({}) could not be found, as the wheel is missing a `METADATA` file",
|
|
||||||
"hint".bold().cyan(),
|
|
||||||
":".bold(),
|
|
||||||
package.cyan(),
|
|
||||||
format!("v{version}").cyan(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Self::InvalidVersionMetadata {
|
Self::InvalidVersionMetadata {
|
||||||
package,
|
package,
|
||||||
version,
|
version,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
use crate::resolver::MetadataUnavailable;
|
||||||
use uv_distribution_types::IncompatibleDist;
|
use uv_distribution_types::IncompatibleDist;
|
||||||
use uv_pep440::{Version, VersionSpecifiers};
|
use uv_pep440::{Version, VersionSpecifiers};
|
||||||
|
|
||||||
|
@ -21,17 +22,15 @@ impl Display for UnavailableReason {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The package version is unavailable and cannot be used. Unlike [`PackageUnavailable`], this
|
/// The package version is unavailable and cannot be used. Unlike [`MetadataUnavailable`], this
|
||||||
/// applies to a single version of the package.
|
/// applies to a single version of the package.
|
||||||
///
|
///
|
||||||
/// Most variant are from [`MetadataResponse`] without the error source (since we don't format
|
/// Most variant are from [`MetadataResponse`] without the error source, since we don't format
|
||||||
/// the source).
|
/// the source and we want to merge unavailable messages across versions.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub(crate) enum UnavailableVersion {
|
pub(crate) enum UnavailableVersion {
|
||||||
/// Version is incompatible because it has no usable distributions
|
/// Version is incompatible because it has no usable distributions
|
||||||
IncompatibleDist(IncompatibleDist),
|
IncompatibleDist(IncompatibleDist),
|
||||||
/// The wheel metadata was not found.
|
|
||||||
MissingMetadata,
|
|
||||||
/// The wheel metadata was found, but could not be parsed.
|
/// The wheel metadata was found, but could not be parsed.
|
||||||
InvalidMetadata,
|
InvalidMetadata,
|
||||||
/// The wheel metadata was found, but the metadata was inconsistent.
|
/// The wheel metadata was found, but the metadata was inconsistent.
|
||||||
|
@ -49,7 +48,6 @@ impl UnavailableVersion {
|
||||||
pub(crate) fn message(&self) -> String {
|
pub(crate) fn message(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
UnavailableVersion::IncompatibleDist(invalid_dist) => format!("{invalid_dist}"),
|
UnavailableVersion::IncompatibleDist(invalid_dist) => format!("{invalid_dist}"),
|
||||||
UnavailableVersion::MissingMetadata => "not include a `METADATA` file".into(),
|
|
||||||
UnavailableVersion::InvalidMetadata => "invalid metadata".into(),
|
UnavailableVersion::InvalidMetadata => "invalid metadata".into(),
|
||||||
UnavailableVersion::InconsistentMetadata => "inconsistent metadata".into(),
|
UnavailableVersion::InconsistentMetadata => "inconsistent metadata".into(),
|
||||||
UnavailableVersion::InvalidStructure => "an invalid package format".into(),
|
UnavailableVersion::InvalidStructure => "an invalid package format".into(),
|
||||||
|
@ -63,7 +61,6 @@ impl UnavailableVersion {
|
||||||
pub(crate) fn singular_message(&self) -> String {
|
pub(crate) fn singular_message(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
UnavailableVersion::IncompatibleDist(invalid_dist) => invalid_dist.singular_message(),
|
UnavailableVersion::IncompatibleDist(invalid_dist) => invalid_dist.singular_message(),
|
||||||
UnavailableVersion::MissingMetadata => format!("does {self}"),
|
|
||||||
UnavailableVersion::InvalidMetadata => format!("has {self}"),
|
UnavailableVersion::InvalidMetadata => format!("has {self}"),
|
||||||
UnavailableVersion::InconsistentMetadata => format!("has {self}"),
|
UnavailableVersion::InconsistentMetadata => format!("has {self}"),
|
||||||
UnavailableVersion::InvalidStructure => format!("has {self}"),
|
UnavailableVersion::InvalidStructure => format!("has {self}"),
|
||||||
|
@ -75,7 +72,6 @@ impl UnavailableVersion {
|
||||||
pub(crate) fn plural_message(&self) -> String {
|
pub(crate) fn plural_message(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
UnavailableVersion::IncompatibleDist(invalid_dist) => invalid_dist.plural_message(),
|
UnavailableVersion::IncompatibleDist(invalid_dist) => invalid_dist.plural_message(),
|
||||||
UnavailableVersion::MissingMetadata => format!("do {self}"),
|
|
||||||
UnavailableVersion::InvalidMetadata => format!("have {self}"),
|
UnavailableVersion::InvalidMetadata => format!("have {self}"),
|
||||||
UnavailableVersion::InconsistentMetadata => format!("have {self}"),
|
UnavailableVersion::InconsistentMetadata => format!("have {self}"),
|
||||||
UnavailableVersion::InvalidStructure => format!("have {self}"),
|
UnavailableVersion::InvalidStructure => format!("have {self}"),
|
||||||
|
@ -91,6 +87,22 @@ impl Display for UnavailableVersion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&MetadataUnavailable> for UnavailableVersion {
|
||||||
|
fn from(reason: &MetadataUnavailable) -> Self {
|
||||||
|
match reason {
|
||||||
|
MetadataUnavailable::Offline => UnavailableVersion::Offline,
|
||||||
|
MetadataUnavailable::InvalidMetadata(_) => UnavailableVersion::InvalidMetadata,
|
||||||
|
MetadataUnavailable::InconsistentMetadata(_) => {
|
||||||
|
UnavailableVersion::InconsistentMetadata
|
||||||
|
}
|
||||||
|
MetadataUnavailable::InvalidStructure(_) => UnavailableVersion::InvalidStructure,
|
||||||
|
MetadataUnavailable::RequiresPython(requires_python, _python_version) => {
|
||||||
|
UnavailableVersion::RequiresPython(requires_python.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The package is unavailable and cannot be used.
|
/// The package is unavailable and cannot be used.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub(crate) enum UnavailablePackage {
|
pub(crate) enum UnavailablePackage {
|
||||||
|
@ -100,8 +112,6 @@ pub(crate) enum UnavailablePackage {
|
||||||
Offline,
|
Offline,
|
||||||
/// The package was not found in the registry.
|
/// The package was not found in the registry.
|
||||||
NotFound,
|
NotFound,
|
||||||
/// The package metadata was not found.
|
|
||||||
MissingMetadata,
|
|
||||||
/// The package metadata was found, but could not be parsed.
|
/// The package metadata was found, but could not be parsed.
|
||||||
InvalidMetadata(String),
|
InvalidMetadata(String),
|
||||||
/// The package has an invalid structure.
|
/// The package has an invalid structure.
|
||||||
|
@ -114,7 +124,6 @@ impl UnavailablePackage {
|
||||||
UnavailablePackage::NoIndex => "not found in the provided package locations",
|
UnavailablePackage::NoIndex => "not found in the provided package locations",
|
||||||
UnavailablePackage::Offline => "not found in the cache",
|
UnavailablePackage::Offline => "not found in the cache",
|
||||||
UnavailablePackage::NotFound => "not found in the package registry",
|
UnavailablePackage::NotFound => "not found in the package registry",
|
||||||
UnavailablePackage::MissingMetadata => "not include a `METADATA` file",
|
|
||||||
UnavailablePackage::InvalidMetadata(_) => "invalid metadata",
|
UnavailablePackage::InvalidMetadata(_) => "invalid metadata",
|
||||||
UnavailablePackage::InvalidStructure(_) => "an invalid package format",
|
UnavailablePackage::InvalidStructure(_) => "an invalid package format",
|
||||||
}
|
}
|
||||||
|
@ -125,7 +134,6 @@ impl UnavailablePackage {
|
||||||
UnavailablePackage::NoIndex => format!("was {self}"),
|
UnavailablePackage::NoIndex => format!("was {self}"),
|
||||||
UnavailablePackage::Offline => format!("was {self}"),
|
UnavailablePackage::Offline => format!("was {self}"),
|
||||||
UnavailablePackage::NotFound => format!("was {self}"),
|
UnavailablePackage::NotFound => format!("was {self}"),
|
||||||
UnavailablePackage::MissingMetadata => format!("does {self}"),
|
|
||||||
UnavailablePackage::InvalidMetadata(_) => format!("has {self}"),
|
UnavailablePackage::InvalidMetadata(_) => format!("has {self}"),
|
||||||
UnavailablePackage::InvalidStructure(_) => format!("has {self}"),
|
UnavailablePackage::InvalidStructure(_) => format!("has {self}"),
|
||||||
}
|
}
|
||||||
|
@ -138,22 +146,20 @@ impl Display for UnavailablePackage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The package is unavailable at specific versions.
|
impl From<&MetadataUnavailable> for UnavailablePackage {
|
||||||
#[derive(Debug, Clone)]
|
fn from(reason: &MetadataUnavailable) -> Self {
|
||||||
pub(crate) enum IncompletePackage {
|
match reason {
|
||||||
/// Network requests were disabled (i.e., `--offline`), and the wheel metadata was not found in the cache.
|
MetadataUnavailable::Offline => Self::Offline,
|
||||||
Offline,
|
MetadataUnavailable::InvalidMetadata(err) => Self::InvalidMetadata(err.to_string()),
|
||||||
/// The wheel metadata was not found.
|
MetadataUnavailable::InconsistentMetadata(err) => {
|
||||||
MissingMetadata,
|
Self::InvalidMetadata(err.to_string())
|
||||||
/// The wheel metadata was found, but could not be parsed.
|
}
|
||||||
InvalidMetadata(String),
|
MetadataUnavailable::InvalidStructure(err) => Self::InvalidStructure(err.to_string()),
|
||||||
/// The wheel metadata was found, but the metadata was inconsistent.
|
MetadataUnavailable::RequiresPython(..) => {
|
||||||
InconsistentMetadata(String),
|
unreachable!("`requires-python` is only known upfront for registry distributions")
|
||||||
/// The wheel has an invalid structure.
|
}
|
||||||
InvalidStructure(String),
|
}
|
||||||
/// The source distribution has a `requires-python` requirement that is not met by the installed
|
}
|
||||||
/// Python version (and static metadata is not available).
|
|
||||||
RequiresPython(VersionSpecifiers, Version),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -55,7 +55,7 @@ use crate::python_requirement::PythonRequirement;
|
||||||
use crate::resolution::ResolverOutput;
|
use crate::resolution::ResolverOutput;
|
||||||
use crate::resolution_mode::ResolutionStrategy;
|
use crate::resolution_mode::ResolutionStrategy;
|
||||||
pub(crate) use crate::resolver::availability::{
|
pub(crate) use crate::resolver::availability::{
|
||||||
IncompletePackage, ResolverVersion, UnavailablePackage, UnavailableReason, UnavailableVersion,
|
ResolverVersion, UnavailablePackage, UnavailableReason, UnavailableVersion,
|
||||||
};
|
};
|
||||||
use crate::resolver::batch_prefetch::BatchPrefetcher;
|
use crate::resolver::batch_prefetch::BatchPrefetcher;
|
||||||
pub use crate::resolver::derivation::DerivationChainBuilder;
|
pub use crate::resolver::derivation::DerivationChainBuilder;
|
||||||
|
@ -64,6 +64,7 @@ pub use crate::resolver::environment::ResolverEnvironment;
|
||||||
pub(crate) use crate::resolver::fork_map::{ForkMap, ForkSet};
|
pub(crate) use crate::resolver::fork_map::{ForkMap, ForkSet};
|
||||||
pub(crate) use crate::resolver::urls::Urls;
|
pub(crate) use crate::resolver::urls::Urls;
|
||||||
use crate::universal_marker::{ConflictMarker, UniversalMarker};
|
use crate::universal_marker::{ConflictMarker, UniversalMarker};
|
||||||
|
pub(crate) use provider::MetadataUnavailable;
|
||||||
|
|
||||||
pub use crate::resolver::index::InMemoryIndex;
|
pub use crate::resolver::index::InMemoryIndex;
|
||||||
use crate::resolver::indexes::Indexes;
|
use crate::resolver::indexes::Indexes;
|
||||||
|
@ -118,7 +119,7 @@ struct ResolverState<InstalledPackages: InstalledPackagesProvider> {
|
||||||
/// Incompatibilities for packages that are entirely unavailable.
|
/// Incompatibilities for packages that are entirely unavailable.
|
||||||
unavailable_packages: DashMap<PackageName, UnavailablePackage>,
|
unavailable_packages: DashMap<PackageName, UnavailablePackage>,
|
||||||
/// Incompatibilities for packages that are unavailable at specific versions.
|
/// Incompatibilities for packages that are unavailable at specific versions.
|
||||||
incomplete_packages: DashMap<PackageName, DashMap<Version, IncompletePackage>>,
|
incomplete_packages: DashMap<PackageName, DashMap<Version, MetadataUnavailable>>,
|
||||||
/// The options that were used to configure this resolver.
|
/// The options that were used to configure this resolver.
|
||||||
options: Options,
|
options: Options,
|
||||||
/// The reporter to use for this resolver.
|
/// The reporter to use for this resolver.
|
||||||
|
@ -354,6 +355,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
state.priorities.get(&state.pubgrub.package_store[id])
|
state.priorities.get(&state.pubgrub.package_store[id])
|
||||||
})
|
})
|
||||||
else {
|
else {
|
||||||
|
// All packages have been assigned, the fork has been successfully resolved
|
||||||
if tracing::enabled!(Level::DEBUG) {
|
if tracing::enabled!(Level::DEBUG) {
|
||||||
prefetcher.log_tried_versions();
|
prefetcher.log_tried_versions();
|
||||||
}
|
}
|
||||||
|
@ -919,40 +921,11 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
// If we failed to fetch the metadata for a URL, we can't proceed.
|
// If we failed to fetch the metadata for a URL, we can't proceed.
|
||||||
let metadata = match &*response {
|
let metadata = match &*response {
|
||||||
MetadataResponse::Found(archive) => &archive.metadata,
|
MetadataResponse::Found(archive) => &archive.metadata,
|
||||||
MetadataResponse::Offline => {
|
MetadataResponse::Unavailable(reason) => {
|
||||||
self.unavailable_packages
|
self.unavailable_packages
|
||||||
.insert(name.clone(), UnavailablePackage::Offline);
|
.insert(name.clone(), reason.into());
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
MetadataResponse::MissingMetadata => {
|
|
||||||
self.unavailable_packages
|
|
||||||
.insert(name.clone(), UnavailablePackage::MissingMetadata);
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
MetadataResponse::InvalidMetadata(err) => {
|
|
||||||
self.unavailable_packages.insert(
|
|
||||||
name.clone(),
|
|
||||||
UnavailablePackage::InvalidMetadata(err.to_string()),
|
|
||||||
);
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
MetadataResponse::InconsistentMetadata(err) => {
|
|
||||||
self.unavailable_packages.insert(
|
|
||||||
name.clone(),
|
|
||||||
UnavailablePackage::InvalidMetadata(err.to_string()),
|
|
||||||
);
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
MetadataResponse::InvalidStructure(err) => {
|
|
||||||
self.unavailable_packages.insert(
|
|
||||||
name.clone(),
|
|
||||||
UnavailablePackage::InvalidStructure(err.to_string()),
|
|
||||||
);
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
MetadataResponse::RequiresPython(..) => {
|
|
||||||
unreachable!("`requires-python` is only known upfront for registry distributions")
|
|
||||||
}
|
|
||||||
MetadataResponse::Error(dist, err) => {
|
MetadataResponse::Error(dist, err) => {
|
||||||
// TODO(charlie): Add derivation chain for URL dependencies. In practice, this isn't
|
// TODO(charlie): Add derivation chain for URL dependencies. In practice, this isn't
|
||||||
// critical since we fetch URL dependencies _prior_ to invoking the resolver.
|
// critical since we fetch URL dependencies _prior_ to invoking the resolver.
|
||||||
|
@ -1318,82 +1291,20 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
|
|
||||||
let metadata = match &*response {
|
let metadata = match &*response {
|
||||||
MetadataResponse::Found(archive) => &archive.metadata,
|
MetadataResponse::Found(archive) => &archive.metadata,
|
||||||
MetadataResponse::Offline => {
|
MetadataResponse::Unavailable(reason) => {
|
||||||
|
let unavailable_version = UnavailableVersion::from(reason);
|
||||||
|
let message = unavailable_version.singular_message();
|
||||||
|
if let Some(err) = reason.source() {
|
||||||
|
// Show the detailed error for metadata parse errors.
|
||||||
|
warn!("{name} {message}: {err}");
|
||||||
|
} else {
|
||||||
|
warn!("{name} {message}");
|
||||||
|
}
|
||||||
self.incomplete_packages
|
self.incomplete_packages
|
||||||
.entry(name.clone())
|
.entry(name.clone())
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(version.clone(), IncompletePackage::Offline);
|
.insert(version.clone(), reason.clone());
|
||||||
return Ok(Dependencies::Unavailable(UnavailableVersion::Offline));
|
return Ok(Dependencies::Unavailable(unavailable_version));
|
||||||
}
|
|
||||||
MetadataResponse::MissingMetadata => {
|
|
||||||
self.incomplete_packages
|
|
||||||
.entry(name.clone())
|
|
||||||
.or_default()
|
|
||||||
.insert(version.clone(), IncompletePackage::MissingMetadata);
|
|
||||||
return Ok(Dependencies::Unavailable(
|
|
||||||
UnavailableVersion::MissingMetadata,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
MetadataResponse::InvalidMetadata(err) => {
|
|
||||||
warn!("Unable to extract metadata for {name}: {err}");
|
|
||||||
self.incomplete_packages
|
|
||||||
.entry(name.clone())
|
|
||||||
.or_default()
|
|
||||||
.insert(
|
|
||||||
version.clone(),
|
|
||||||
IncompletePackage::InvalidMetadata(err.to_string()),
|
|
||||||
);
|
|
||||||
return Ok(Dependencies::Unavailable(
|
|
||||||
UnavailableVersion::InvalidMetadata,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
MetadataResponse::InconsistentMetadata(err) => {
|
|
||||||
warn!("Unable to extract metadata for {name}: {err}");
|
|
||||||
self.incomplete_packages
|
|
||||||
.entry(name.clone())
|
|
||||||
.or_default()
|
|
||||||
.insert(
|
|
||||||
version.clone(),
|
|
||||||
IncompletePackage::InconsistentMetadata(err.to_string()),
|
|
||||||
);
|
|
||||||
return Ok(Dependencies::Unavailable(
|
|
||||||
UnavailableVersion::InconsistentMetadata,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
MetadataResponse::InvalidStructure(err) => {
|
|
||||||
warn!("Unable to extract metadata for {name}: {err}");
|
|
||||||
self.incomplete_packages
|
|
||||||
.entry(name.clone())
|
|
||||||
.or_default()
|
|
||||||
.insert(
|
|
||||||
version.clone(),
|
|
||||||
IncompletePackage::InvalidStructure(err.to_string()),
|
|
||||||
);
|
|
||||||
return Ok(Dependencies::Unavailable(
|
|
||||||
UnavailableVersion::InvalidStructure,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
MetadataResponse::RequiresPython(requires_python, python_version) => {
|
|
||||||
warn!(
|
|
||||||
"Unable to extract metadata for {name}: {}",
|
|
||||||
uv_distribution::Error::RequiresPython(
|
|
||||||
requires_python.clone(),
|
|
||||||
python_version.clone()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
self.incomplete_packages
|
|
||||||
.entry(name.clone())
|
|
||||||
.or_default()
|
|
||||||
.insert(
|
|
||||||
version.clone(),
|
|
||||||
IncompletePackage::RequiresPython(
|
|
||||||
requires_python.clone(),
|
|
||||||
python_version.clone(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return Ok(Dependencies::Unavailable(
|
|
||||||
UnavailableVersion::RequiresPython(requires_python.clone()),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
MetadataResponse::Error(dist, err) => {
|
MetadataResponse::Error(dist, err) => {
|
||||||
let chain = DerivationChainBuilder::from_state(id, version, pubgrub)
|
let chain = DerivationChainBuilder::from_state(id, version, pubgrub)
|
||||||
|
@ -1856,37 +1767,20 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
))),
|
))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Some(Response::Dist {
|
Some(Response::Dist { dist, metadata }) => {
|
||||||
dist: Dist::Built(dist),
|
let dist_kind = match dist {
|
||||||
metadata,
|
Dist::Built(_) => "built",
|
||||||
}) => {
|
Dist::Source(_) => "source",
|
||||||
trace!("Received built distribution metadata for: {dist}");
|
};
|
||||||
match &metadata {
|
trace!("Received {dist_kind} distribution metadata for: {dist}");
|
||||||
MetadataResponse::InvalidMetadata(err) => {
|
if let MetadataResponse::Unavailable(reason) = &metadata {
|
||||||
warn!("Unable to extract metadata for {dist}: {err}");
|
let message = UnavailableVersion::from(reason).singular_message();
|
||||||
|
if let Some(err) = reason.source() {
|
||||||
|
// Show the detailed error for metadata parse errors.
|
||||||
|
warn!("{dist} {message}: {err}");
|
||||||
|
} else {
|
||||||
|
warn!("{dist} {message}");
|
||||||
}
|
}
|
||||||
MetadataResponse::InvalidStructure(err) => {
|
|
||||||
warn!("Unable to extract metadata for {dist}: {err}");
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
self.index
|
|
||||||
.distributions()
|
|
||||||
.done(dist.version_id(), Arc::new(metadata));
|
|
||||||
}
|
|
||||||
Some(Response::Dist {
|
|
||||||
dist: Dist::Source(dist),
|
|
||||||
metadata,
|
|
||||||
}) => {
|
|
||||||
trace!("Received source distribution metadata for: {dist}");
|
|
||||||
match &metadata {
|
|
||||||
MetadataResponse::InvalidMetadata(err) => {
|
|
||||||
warn!("Unable to extract metadata for {dist}: {err}");
|
|
||||||
}
|
|
||||||
MetadataResponse::InvalidStructure(err) => {
|
|
||||||
warn!("Unable to extract metadata for {dist}: {err}");
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
self.index
|
self.index
|
||||||
.distributions()
|
.distributions()
|
||||||
|
|
|
@ -34,21 +34,43 @@ pub enum VersionsResponse {
|
||||||
pub enum MetadataResponse {
|
pub enum MetadataResponse {
|
||||||
/// The wheel metadata was found and parsed successfully.
|
/// The wheel metadata was found and parsed successfully.
|
||||||
Found(ArchiveMetadata),
|
Found(ArchiveMetadata),
|
||||||
/// The wheel metadata was not found.
|
/// A non-fatal error.
|
||||||
MissingMetadata,
|
Unavailable(MetadataUnavailable),
|
||||||
/// The wheel metadata was found, but could not be parsed.
|
/// The distribution could not be built or downloaded, a fatal error.
|
||||||
InvalidMetadata(Box<uv_pypi_types::MetadataError>),
|
Error(Box<Dist>, Arc<uv_distribution::Error>),
|
||||||
/// The wheel metadata was found, but the metadata was inconsistent.
|
}
|
||||||
InconsistentMetadata(Box<uv_distribution::Error>),
|
|
||||||
/// The wheel has an invalid structure.
|
/// Non-fatal metadata fetching error.
|
||||||
InvalidStructure(Box<uv_metadata::Error>),
|
///
|
||||||
|
/// This is also the unavailability reasons for a package, while version unavailability is separate
|
||||||
|
/// in [`UnavailableVersion`].
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum MetadataUnavailable {
|
||||||
/// The wheel metadata was not found in the cache and the network is not available.
|
/// The wheel metadata was not found in the cache and the network is not available.
|
||||||
Offline,
|
Offline,
|
||||||
|
/// The wheel metadata was found, but could not be parsed.
|
||||||
|
InvalidMetadata(Arc<uv_pypi_types::MetadataError>),
|
||||||
|
/// The wheel metadata was found, but the metadata was inconsistent.
|
||||||
|
InconsistentMetadata(Arc<uv_distribution::Error>),
|
||||||
|
/// The wheel has an invalid structure.
|
||||||
|
InvalidStructure(Arc<uv_metadata::Error>),
|
||||||
/// The source distribution has a `requires-python` requirement that is not met by the installed
|
/// The source distribution has a `requires-python` requirement that is not met by the installed
|
||||||
/// Python version (and static metadata is not available).
|
/// Python version (and static metadata is not available).
|
||||||
RequiresPython(VersionSpecifiers, Version),
|
RequiresPython(VersionSpecifiers, Version),
|
||||||
/// The distribution could not be built or downloaded.
|
}
|
||||||
Error(Box<Dist>, Arc<uv_distribution::Error>),
|
|
||||||
|
impl MetadataUnavailable {
|
||||||
|
/// Like [`std::error::Error::source`], but we don't want to derive the std error since our
|
||||||
|
/// formatting system is more custom.
|
||||||
|
pub(crate) fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
match self {
|
||||||
|
MetadataUnavailable::Offline => None,
|
||||||
|
MetadataUnavailable::InvalidMetadata(err) => Some(err),
|
||||||
|
MetadataUnavailable::InconsistentMetadata(err) => Some(err),
|
||||||
|
MetadataUnavailable::InvalidStructure(err) => Some(err),
|
||||||
|
MetadataUnavailable::RequiresPython(_, _) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ResolverProvider {
|
pub trait ResolverProvider {
|
||||||
|
@ -189,29 +211,39 @@ impl<'a, Context: BuildContext> ResolverProvider for DefaultResolverProvider<'a,
|
||||||
Ok(metadata) => Ok(MetadataResponse::Found(metadata)),
|
Ok(metadata) => Ok(MetadataResponse::Found(metadata)),
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
uv_distribution::Error::Client(client) => match client.into_kind() {
|
uv_distribution::Error::Client(client) => match client.into_kind() {
|
||||||
uv_client::ErrorKind::Offline(_) => Ok(MetadataResponse::Offline),
|
uv_client::ErrorKind::Offline(_) => {
|
||||||
|
Ok(MetadataResponse::Unavailable(MetadataUnavailable::Offline))
|
||||||
|
}
|
||||||
uv_client::ErrorKind::MetadataParseError(_, _, err) => {
|
uv_client::ErrorKind::MetadataParseError(_, _, err) => {
|
||||||
Ok(MetadataResponse::InvalidMetadata(err))
|
Ok(MetadataResponse::Unavailable(
|
||||||
}
|
MetadataUnavailable::InvalidMetadata(Arc::new(*err)),
|
||||||
uv_client::ErrorKind::Metadata(_, err) => {
|
))
|
||||||
Ok(MetadataResponse::InvalidStructure(Box::new(err)))
|
|
||||||
}
|
}
|
||||||
|
uv_client::ErrorKind::Metadata(_, err) => Ok(MetadataResponse::Unavailable(
|
||||||
|
MetadataUnavailable::InvalidStructure(Arc::new(err)),
|
||||||
|
)),
|
||||||
kind => Err(uv_client::Error::from(kind).into()),
|
kind => Err(uv_client::Error::from(kind).into()),
|
||||||
},
|
},
|
||||||
uv_distribution::Error::WheelMetadataVersionMismatch { .. } => {
|
uv_distribution::Error::WheelMetadataVersionMismatch { .. } => {
|
||||||
Ok(MetadataResponse::InconsistentMetadata(Box::new(err)))
|
Ok(MetadataResponse::Unavailable(
|
||||||
|
MetadataUnavailable::InconsistentMetadata(Arc::new(err)),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
uv_distribution::Error::WheelMetadataNameMismatch { .. } => {
|
uv_distribution::Error::WheelMetadataNameMismatch { .. } => {
|
||||||
Ok(MetadataResponse::InconsistentMetadata(Box::new(err)))
|
Ok(MetadataResponse::Unavailable(
|
||||||
}
|
MetadataUnavailable::InconsistentMetadata(Arc::new(err)),
|
||||||
uv_distribution::Error::Metadata(err) => {
|
))
|
||||||
Ok(MetadataResponse::InvalidMetadata(Box::new(err)))
|
|
||||||
}
|
|
||||||
uv_distribution::Error::WheelMetadata(_, err) => {
|
|
||||||
Ok(MetadataResponse::InvalidStructure(err))
|
|
||||||
}
|
}
|
||||||
|
uv_distribution::Error::Metadata(err) => Ok(MetadataResponse::Unavailable(
|
||||||
|
MetadataUnavailable::InvalidMetadata(Arc::new(err)),
|
||||||
|
)),
|
||||||
|
uv_distribution::Error::WheelMetadata(_, err) => Ok(MetadataResponse::Unavailable(
|
||||||
|
MetadataUnavailable::InvalidStructure(Arc::new(*err)),
|
||||||
|
)),
|
||||||
uv_distribution::Error::RequiresPython(requires_python, version) => {
|
uv_distribution::Error::RequiresPython(requires_python, version) => {
|
||||||
Ok(MetadataResponse::RequiresPython(requires_python, version))
|
Ok(MetadataResponse::Unavailable(
|
||||||
|
MetadataUnavailable::RequiresPython(requires_python, version),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
err => Ok(MetadataResponse::Error(
|
err => Ok(MetadataResponse::Error(
|
||||||
Box::new(dist.clone()),
|
Box::new(dist.clone()),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue