diff --git a/crates/uv-client/src/html.rs b/crates/uv-client/src/html.rs index 571c35e5b..5a17998ac 100644 --- a/crates/uv-client/src/html.rs +++ b/crates/uv-client/src/html.rs @@ -185,10 +185,14 @@ impl SimpleHtml { None }; - // Extract the `data-dist-info-metadata` field, which should be set on - // the `data-dist-info-metadata` attribute. - let dist_info_metadata = if let Some(dist_info_metadata) = - link.attributes().get("data-dist-info-metadata").flatten() + // Extract the `core-metadata` field, which is either set on: + // - `data-core-metadata`, per PEP 714. + // - `data-dist-info-metadata`, per PEP 658. + let core_metadata = if let Some(dist_info_metadata) = link + .attributes() + .get("data-core-metadata") + .flatten() + .or_else(|| link.attributes().get("data-dist-info-metadata").flatten()) { let dist_info_metadata = std::str::from_utf8(dist_info_metadata.as_bytes())?; let dist_info_metadata = html_escape::decode_html_entities(dist_info_metadata); @@ -212,7 +216,7 @@ impl SimpleHtml { }; Ok(File { - core_metadata: dist_info_metadata, + core_metadata, dist_info_metadata: None, data_dist_info_metadata: None, yanked, @@ -936,9 +940,9 @@ mod tests {

Links for flask

- Flask-0.1.tar.gz + Flask-0.1.tar.gz
- Flask-0.10.1.tar.gz + Flask-0.10.1.tar.gz
flask-3.0.1.tar.gz
@@ -1108,4 +1112,153 @@ mod tests { } "###); } + + /// Respect PEP 714 (see: ). + #[test] + fn parse_core_metadata() { + let text = r#" + + + +

Links for jinja2

+ Jinja2-3.1.2-py3-none-any.whl
+ Jinja2-3.1.3-py3-none-any.whl
+ Jinja2-3.1.4-py3-none-any.whl
+ Jinja2-3.1.5-py3-none-any.whl
+ Jinja2-3.1.6-py3-none-any.whl
+ + + "#; + let base = Url::parse("https://account.d.codeartifact.us-west-2.amazonaws.com/pypi/shared-packages-pypi/simple/flask/") + .unwrap(); + let result = SimpleHtml::parse(text, &base).unwrap(); + insta::assert_debug_snapshot!(result, @r###" + SimpleHtml { + base: BaseUrl( + Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "account.d.codeartifact.us-west-2.amazonaws.com", + ), + ), + port: None, + path: "/pypi/shared-packages-pypi/simple/flask/", + query: None, + fragment: None, + }, + ), + files: [ + File { + core_metadata: Some( + Bool( + true, + ), + ), + dist_info_metadata: None, + data_dist_info_metadata: None, + filename: "Jinja2-3.1.2-py3-none-any.whl", + hashes: Hashes { + md5: None, + sha256: None, + sha384: None, + sha512: None, + }, + requires_python: None, + size: None, + upload_time: None, + url: "/whl/Jinja2-3.1.2-py3-none-any.whl", + yanked: None, + }, + File { + core_metadata: Some( + Bool( + true, + ), + ), + dist_info_metadata: None, + data_dist_info_metadata: None, + filename: "Jinja2-3.1.3-py3-none-any.whl", + hashes: Hashes { + md5: None, + sha256: None, + sha384: None, + sha512: None, + }, + requires_python: None, + size: None, + upload_time: None, + url: "/whl/Jinja2-3.1.3-py3-none-any.whl", + yanked: None, + }, + File { + core_metadata: Some( + Bool( + false, + ), + ), + dist_info_metadata: None, + data_dist_info_metadata: None, + filename: "Jinja2-3.1.4-py3-none-any.whl", + hashes: Hashes { + md5: None, + sha256: None, + sha384: None, + sha512: None, + }, + requires_python: None, + size: None, + upload_time: None, + url: "/whl/Jinja2-3.1.4-py3-none-any.whl", + yanked: None, + }, + File { + core_metadata: Some( + Bool( + false, + ), + ), + dist_info_metadata: None, + data_dist_info_metadata: None, + filename: "Jinja2-3.1.5-py3-none-any.whl", + hashes: Hashes { + md5: None, + sha256: None, + sha384: None, + sha512: None, + }, + requires_python: None, + size: None, + upload_time: None, + url: "/whl/Jinja2-3.1.5-py3-none-any.whl", + yanked: None, + }, + File { + core_metadata: Some( + Bool( + true, + ), + ), + dist_info_metadata: None, + data_dist_info_metadata: None, + filename: "Jinja2-3.1.6-py3-none-any.whl", + hashes: Hashes { + md5: None, + sha256: None, + sha384: None, + sha512: None, + }, + requires_python: None, + size: None, + upload_time: None, + url: "/whl/Jinja2-3.1.6-py3-none-any.whl", + yanked: None, + }, + ], + } + "###); + } }