diff --git a/crates/uv-client/src/html.rs b/crates/uv-client/src/html.rs index 5c27df26f..2fe521658 100644 --- a/crates/uv-client/src/html.rs +++ b/crates/uv-client/src/html.rs @@ -109,9 +109,15 @@ impl SimpleHtml { debug!("{err}"); Hashes::default() } - Err(err @ HashError::UnsupportedHashAlgorithm(..)) => { - // If the URL references a hash, but it's unsupported, error. - return Err(err.into()); + Err(HashError::UnsupportedHashAlgorithm(fragment)) => { + if fragment == "egg" { + // If the URL references an egg hash, ignore it. + debug!("{}", HashError::UnsupportedHashAlgorithm(fragment)); + Hashes::default() + } else { + // If the URL references a hash, but it's unsupported, error. + return Err(HashError::UnsupportedHashAlgorithm(fragment).into()); + } } } }, @@ -247,7 +253,7 @@ pub enum Error { MissingHash(String), #[error(transparent)] - FragmentParse(#[from] uv_pypi_types::HashError), + FragmentParse(#[from] HashError), #[error("Invalid `requires-python` specifier: {0}")] Pep440(#[source] uv_pep440::VersionSpecifiersParseError), @@ -908,6 +914,64 @@ mod tests { "###); } + #[test] + fn parse_egg_fragment() { + let text = r#" + + + +

Links for jinja2

+Jinja2-3.1.2-py3-none-any.whl#egg=public-hello-0.1
+ + + + "#; + let base = Url::parse("https://download.pytorch.org/whl/jinja2/").unwrap(); + let result = SimpleHtml::parse(text, &base); + insta::assert_debug_snapshot!(result, @r###" + Ok( + SimpleHtml { + base: BaseUrl( + Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "download.pytorch.org", + ), + ), + port: None, + path: "/whl/jinja2/", + query: None, + fragment: None, + }, + ), + 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, + sha256: None, + sha384: None, + sha512: None, + }, + requires_python: None, + size: None, + upload_time: None, + url: "/whl/Jinja2-3.1.2-py3-none-any.whl#main", + yanked: None, + }, + ], + }, + ) + "###); + } + #[test] fn parse_unknown_hash() { let text = r#"