Fetch wheel metadata by async range requests on the remote wheel (#301)

Use range requests and async zip to extract the METADATA file from a
remote wheel.

We currently only cache when the remote says the remote declares the
resource as immutable, see
https://github.com/06chaynes/http-cache/issues/57 and
https://github.com/baszalmstra/async_http_range_reader/pull/1 . The
cache is stored as json with the description omitted, this improve cache
deserialization performance.
This commit is contained in:
konsti 2023-11-06 15:06:49 +01:00 committed by GitHub
parent 6f83a44fea
commit b2439b24a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 558 additions and 68 deletions

View file

@ -1,13 +1,14 @@
use distribution_filename::{SourceDistributionFilename, WheelFilename};
use std::ops::Deref;
use puffin_package::pypi_types::File;
/// A distribution can either be a wheel or a source distribution.
#[derive(Debug, Clone)]
pub(crate) struct WheelFile(File);
pub(crate) struct WheelFile(pub(crate) File, pub(crate) WheelFilename);
#[derive(Debug, Clone)]
pub(crate) struct SdistFile(File);
pub(crate) struct SdistFile(pub(crate) File, pub(crate) SourceDistributionFilename);
#[derive(Debug, Clone)]
pub(crate) enum DistributionFile {
@ -31,18 +32,6 @@ impl Deref for SdistFile {
}
}
impl From<File> for WheelFile {
fn from(file: File) -> Self {
Self(file)
}
}
impl From<File> for SdistFile {
fn from(file: File) -> Self {
Self(file)
}
}
impl From<WheelFile> for File {
fn from(wheel: WheelFile) -> Self {
wheel.0
@ -67,19 +56,6 @@ impl From<SdistFile> for DistributionFile {
}
}
impl From<File> for DistributionFile {
fn from(file: File) -> Self {
if std::path::Path::new(file.filename.as_str())
.extension()
.map_or(false, |ext| ext.eq_ignore_ascii_case("whl"))
{
Self::Wheel(WheelFile::from(file))
} else {
Self::Sdist(SdistFile::from(file))
}
}
}
impl DistributionFile {
pub(crate) fn filename(&self) -> &str {
match self {

View file

@ -157,6 +157,7 @@ impl<'a> DistributionFinder<'a> {
}
#[derive(Debug)]
#[allow(clippy::large_enum_variant)]
enum Request {
/// A request to fetch the metadata for a package.
Package(Requirement),

View file

@ -548,31 +548,33 @@ impl<'a, Context: BuildContext + Sync> Resolver<'a, Context> {
// distributions.
let mut version_map: VersionMap = BTreeMap::new();
for file in metadata.files {
if let Ok(name) = WheelFilename::from_str(file.filename.as_str()) {
if name.is_compatible(self.tags) {
let version = PubGrubVersion::from(name.version);
if let Ok(filename) = WheelFilename::from_str(file.filename.as_str()) {
if filename.is_compatible(self.tags) {
let version = PubGrubVersion::from(filename.version.clone());
match version_map.entry(version) {
std::collections::btree_map::Entry::Occupied(mut entry) => {
if matches!(entry.get(), DistributionFile::Sdist(_)) {
// Wheels get precedence over source distributions.
entry.insert(DistributionFile::from(WheelFile::from(
file,
entry.insert(DistributionFile::from(WheelFile(
file, filename,
)));
}
}
std::collections::btree_map::Entry::Vacant(entry) => {
entry.insert(DistributionFile::from(WheelFile::from(file)));
entry.insert(DistributionFile::from(WheelFile(
file, filename,
)));
}
}
}
} else if let Ok(name) =
} else if let Ok(filename) =
SourceDistributionFilename::parse(file.filename.as_str(), &package_name)
{
let version = PubGrubVersion::from(name.version);
let version = PubGrubVersion::from(filename.version.clone());
if let std::collections::btree_map::Entry::Vacant(entry) =
version_map.entry(version)
{
entry.insert(DistributionFile::from(SdistFile::from(file)));
entry.insert(DistributionFile::from(SdistFile(file, filename)));
}
}
}
@ -627,7 +629,7 @@ impl<'a, Context: BuildContext + Sync> Resolver<'a, Context> {
Request::Wheel(package_name, file) => {
let metadata = self
.client
.file(file.clone().into())
.wheel_metadata(file.0.clone(), file.1.clone())
.map_err(ResolveError::Client)
.await?;