Skip to content

Commit

Permalink
Make missing METADATA a recoverable error
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jun 11, 2024
1 parent dce913c commit 6958c28
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 13 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion crates/uv-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ rmp-serde = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
sys-info = { workspace = true }
tempfile = { workspace = true }
thiserror = { workspace = true }
tl = { workspace = true }
tokio = { workspace = true }
Expand Down
11 changes: 0 additions & 11 deletions crates/uv-client/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ pub enum ErrorKind {
#[error("Metadata file `{0}` was not found in {1}")]
MetadataNotFound(WheelFilename, String),

/// The metadata file was not found in the registry.
#[error("File `{0}` was not found in the registry at {1}.")]
FileNotFound(String, #[source] BetterReqwestError),

/// A generic request error happened while making a request. Refer to the
/// error message for more details.
#[error(transparent)]
Expand All @@ -185,9 +181,6 @@ pub enum ErrorKind {
#[error(transparent)]
AsyncHttpRangeReader(#[from] AsyncHttpRangeReaderError),

#[error("Expected a single .dist-info directory in {0}, found {1}")]
InvalidDistInfo(WheelFilename, String),

#[error("{0} is not a valid wheel filename")]
WheelFilename(#[source] WheelFilenameError),

Expand All @@ -212,10 +205,6 @@ pub enum ErrorKind {
#[error("Cache serialization failed")]
Encode(#[source] rmp_serde::encode::Error),

/// An [`io::Error`] with a filename attached
#[error(transparent)]
Persist(#[from] tempfile::PersistError),

#[error("Missing `Content-Type` header for {0}")]
MissingContentType(Url),

Expand Down
38 changes: 38 additions & 0 deletions crates/uv-resolver/src/pubgrub/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,11 @@ impl PubGrubReportFormatter<'_> {
Some(UnavailablePackage::Offline) => {
hints.insert(PubGrubHint::Offline);
}
Some(UnavailablePackage::MissingMetadata) => {
hints.insert(PubGrubHint::MissingPackageMetadata {
package: package.clone(),
});
}
Some(UnavailablePackage::InvalidMetadata(reason)) => {
hints.insert(PubGrubHint::InvalidPackageMetadata {
package: package.clone(),
Expand All @@ -500,6 +505,12 @@ impl PubGrubReportFormatter<'_> {
IncompletePackage::Offline => {
hints.insert(PubGrubHint::Offline);
}
IncompletePackage::MissingMetadata => {
hints.insert(PubGrubHint::MissingVersionMetadata {
package: package.clone(),
version: version.clone(),
});
}
IncompletePackage::InvalidMetadata(reason) => {
hints.insert(PubGrubHint::InvalidVersionMetadata {
package: package.clone(),
Expand Down Expand Up @@ -601,6 +612,8 @@ pub(crate) enum PubGrubHint {
NoIndex,
/// A package was not found in the registry, but network access was disabled.
Offline,
/// Metadata for a package could not be found.
MissingPackageMetadata { package: PubGrubPackage },
/// Metadata for a package could not be parsed.
InvalidPackageMetadata {
package: PubGrubPackage,
Expand All @@ -613,6 +626,12 @@ pub(crate) enum PubGrubHint {
#[derivative(PartialEq = "ignore", Hash = "ignore")]
reason: String,
},
/// Metadata for a package version could not be found.
MissingVersionMetadata {
package: PubGrubPackage,
#[derivative(PartialEq = "ignore", Hash = "ignore")]
version: Version,
},
/// Metadata for a package version could not be parsed.
InvalidVersionMetadata {
package: PubGrubPackage,
Expand Down Expand Up @@ -689,6 +708,15 @@ impl std::fmt::Display for PubGrubHint {
":".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 } => {
write!(
f,
Expand All @@ -709,6 +737,16 @@ impl std::fmt::Display for PubGrubHint {
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.bold(),
version.bold(),
)
}
Self::InvalidVersionMetadata {
package,
version,
Expand Down
10 changes: 10 additions & 0 deletions crates/uv-resolver/src/resolver/availability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ impl Display for UnavailableReason {
pub(crate) enum UnavailableVersion {
/// Version is incompatible because it has no usable distributions
IncompatibleDist(IncompatibleDist),
/// The wheel metadata was not found.
MissingMetadata,
/// The wheel metadata was found, but could not be parsed.
InvalidMetadata,
/// The wheel metadata was found, but the metadata was inconsistent.
Expand All @@ -46,6 +48,9 @@ impl Display for UnavailableVersion {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
UnavailableVersion::IncompatibleDist(invalid_dist) => Display::fmt(invalid_dist, f),
UnavailableVersion::MissingMetadata => {
f.write_str("does not include a `METADATA` file")
}
UnavailableVersion::InvalidMetadata => f.write_str("has invalid metadata"),
UnavailableVersion::InconsistentMetadata => f.write_str("has inconsistent metadata"),
UnavailableVersion::InvalidStructure => f.write_str("has an invalid package format"),
Expand All @@ -66,6 +71,8 @@ pub(crate) enum UnavailablePackage {
Offline,
/// The package was not found in the registry.
NotFound,
/// The package metadata was not found.
MissingMetadata,
/// The package metadata was found, but could not be parsed.
InvalidMetadata(String),
/// The package has an invalid structure.
Expand All @@ -78,6 +85,7 @@ impl UnavailablePackage {
UnavailablePackage::NoIndex => "was not found in the provided package locations",
UnavailablePackage::Offline => "was not found in the cache",
UnavailablePackage::NotFound => "was not found in the package registry",
UnavailablePackage::MissingMetadata => "does not include a `METADATA` file",
UnavailablePackage::InvalidMetadata(_) => "has invalid metadata",
UnavailablePackage::InvalidStructure(_) => "has an invalid package format",
}
Expand All @@ -95,6 +103,8 @@ impl Display for UnavailablePackage {
pub(crate) enum IncompletePackage {
/// Network requests were disabled (i.e., `--offline`), and the wheel metadata was not found in the cache.
Offline,
/// The wheel metadata was not found.
MissingMetadata,
/// The wheel metadata was found, but could not be parsed.
InvalidMetadata(String),
/// The wheel metadata was found, but the metadata was inconsistent.
Expand Down
14 changes: 14 additions & 0 deletions crates/uv-resolver/src/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,11 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
.insert(name.clone(), UnavailablePackage::Offline);
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(),
Expand Down Expand Up @@ -1042,6 +1047,15 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
.insert(version.clone(), IncompletePackage::Offline);
return Ok(Dependencies::Unavailable(UnavailableVersion::Offline));
}
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
Expand Down
5 changes: 5 additions & 0 deletions crates/uv-resolver/src/resolver/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub enum VersionsResponse {
pub enum MetadataResponse {
/// The wheel metadata was found and parsed successfully.
Found(ArchiveMetadata),
/// The wheel metadata was not found.
MissingMetadata,
/// The wheel metadata was found, but could not be parsed.
InvalidMetadata(Box<pypi_types::MetadataError>),
/// The wheel metadata was found, but the metadata was inconsistent.
Expand Down Expand Up @@ -184,6 +186,9 @@ impl<'a, Context: BuildContext> ResolverProvider for DefaultResolverProvider<'a,
Err(err) => match err {
uv_distribution::Error::Client(client) => match client.into_kind() {
uv_client::ErrorKind::Offline(_) => Ok(MetadataResponse::Offline),
uv_client::ErrorKind::MetadataNotFound(_, _) => {
Ok(MetadataResponse::MissingMetadata)
}
uv_client::ErrorKind::MetadataParseError(_, _, err) => {
Ok(MetadataResponse::InvalidMetadata(err))
}
Expand Down

0 comments on commit 6958c28

Please sign in to comment.