mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 02:48:17 +00:00
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:
parent
6f83a44fea
commit
b2439b24a1
15 changed files with 558 additions and 68 deletions
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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?;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue