From 5205165d42e8aafe217a802d58ee0b56990f81e0 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 21 May 2024 11:52:37 -0400 Subject: [PATCH] Add PEP 714 support for JSON API client (#3698) ## Summary Closes https://github.com/astral-sh/uv/issues/3689. ## Test Plan Manually verified we pick up `core-metadata` from PyPI if I remove the aliases. --- crates/distribution-types/src/file.rs | 4 +++- crates/pypi-types/src/simple_json.rs | 13 ++++++---- crates/uv-client/src/html.rs | 34 ++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/crates/distribution-types/src/file.rs b/crates/distribution-types/src/file.rs index 4021ad2f98e6..35b6653d3f38 100644 --- a/crates/distribution-types/src/file.rs +++ b/crates/distribution-types/src/file.rs @@ -44,8 +44,10 @@ impl File { pub fn try_from(file: pypi_types::File, base: &Url) -> Result { Ok(Self { dist_info_metadata: file - .dist_info_metadata + .core_metadata .as_ref() + .or(file.dist_info_metadata.as_ref()) + .or(file.data_dist_info_metadata.as_ref()) .is_some_and(DistInfoMetadata::is_available), filename: file.filename, hashes: file.hashes.into_digests(), diff --git a/crates/pypi-types/src/simple_json.rs b/crates/pypi-types/src/simple_json.rs index b82c6931e503..e98d1be75026 100644 --- a/crates/pypi-types/src/simple_json.rs +++ b/crates/pypi-types/src/simple_json.rs @@ -37,14 +37,17 @@ fn sorted_simple_json_files<'de, D: Deserializer<'de>>(d: D) -> Result #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "kebab-case")] pub struct File { - // Non-PEP 691-compliant alias used by PyPI. - #[serde(alias = "data-dist-info-metadata")] + // PEP 714-renamed field, followed by PEP 691-compliant field, followed by non-PEP 691-compliant + // alias used by PyPI. + pub core_metadata: Option, pub dist_info_metadata: Option, + pub data_dist_info_metadata: Option, pub filename: String, pub hashes: Hashes, - /// There are a number of invalid specifiers on pypi, so we first try to parse it into a [`VersionSpecifiers`] - /// according to spec (PEP 440), then a [`LenientVersionSpecifiers`] with fixup for some common problems and if this - /// still fails, we skip the file when creating a version map. + /// There are a number of invalid specifiers on PyPI, so we first try to parse it into a + /// [`VersionSpecifiers`] according to spec (PEP 440), then a [`LenientVersionSpecifiers`] with + /// fixup for some common problems and if this still fails, we skip the file when creating a + /// version map. #[serde(default, deserialize_with = "deserialize_version_specifiers_lenient")] pub requires_python: Option>, pub size: Option, diff --git a/crates/uv-client/src/html.rs b/crates/uv-client/src/html.rs index 8ad5cc420396..571c35e5bb7e 100644 --- a/crates/uv-client/src/html.rs +++ b/crates/uv-client/src/html.rs @@ -212,7 +212,9 @@ impl SimpleHtml { }; Ok(File { - dist_info_metadata, + core_metadata: dist_info_metadata, + dist_info_metadata: None, + data_dist_info_metadata: None, yanked, requires_python, hashes, @@ -298,7 +300,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Jinja2-3.1.2-py3-none-any.whl", hashes: Hashes { md5: None, @@ -354,7 +358,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Jinja2-3.1.2-py3-none-any.whl", hashes: Hashes { md5: Some( @@ -413,7 +419,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Jinja2-3.1.2-py3-none-any.whl", hashes: Hashes { md5: None, @@ -469,7 +477,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Jinja2-3.1.2+233fca715f49-py3-none-any.whl", hashes: Hashes { md5: None, @@ -525,7 +535,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Jinja2-3.1.2-py3-none-any.whl", hashes: Hashes { md5: None, @@ -581,7 +593,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "torchtext-0.17.0+cpu-cp39-cp39-win_amd64.whl", hashes: Hashes { md5: None, @@ -635,7 +649,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Jinja2-3.1.2-py3-none-any.whl", hashes: Hashes { md5: None, @@ -723,7 +739,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Jinja2-3.1.2-py3-none-any.whl", hashes: Hashes { md5: None, @@ -777,7 +795,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Jinja2-3.1.2-py3-none-any.whl", hashes: Hashes { md5: None, @@ -866,7 +886,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "jaxlib-0.1.52+cuda100-cp36-none-manylinux2010_x86_64.whl", hashes: Hashes { md5: None, @@ -881,7 +903,9 @@ mod tests { yanked: None, }, File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "jaxlib-0.1.52+cuda100-cp37-none-manylinux2010_x86_64.whl", hashes: Hashes { md5: None, @@ -945,7 +969,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Flask-0.1.tar.gz", hashes: Hashes { md5: None, @@ -962,7 +988,9 @@ mod tests { yanked: None, }, File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Flask-0.10.1.tar.gz", hashes: Hashes { md5: None, @@ -979,7 +1007,9 @@ mod tests { yanked: None, }, File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "flask-3.0.1.tar.gz", hashes: Hashes { md5: None, @@ -1045,7 +1075,9 @@ mod tests { ), files: [ File { + core_metadata: None, dist_info_metadata: None, + data_dist_info_metadata: None, filename: "Jinja2-3.1.2-py3-none-any.whl", hashes: Hashes { md5: None,