Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make missing METADATA file a recoverable error #4247

Merged
merged 1 commit into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading