diff --git a/crates/distribution-types/src/installed.rs b/crates/distribution-types/src/installed.rs index 2eb38253456..4cd4dd76e0c 100644 --- a/crates/distribution-types/src/installed.rs +++ b/crates/distribution-types/src/installed.rs @@ -168,7 +168,7 @@ impl InstalledDist { return Ok(None); } }; - let metadata = match pypi_types::Metadata23::parse_pkg_info(&content) { + let metadata = match pypi_types::Metadata10::parse_pkg_info(&content) { Ok(metadata) => metadata, Err(err) => { warn!("Failed to parse metadata for {path:?}: {err}"); @@ -178,7 +178,7 @@ impl InstalledDist { return Ok(Some(Self::LegacyEditable(InstalledLegacyEditable { name: metadata.name, - version: metadata.version, + version: Version::from_str(&metadata.version)?, egg_link: path.to_path_buf(), target, target_url: url, diff --git a/crates/pypi-types/src/metadata.rs b/crates/pypi-types/src/metadata.rs index 9696d5e82b3..a877bb3aa84 100644 --- a/crates/pypi-types/src/metadata.rs +++ b/crates/pypi-types/src/metadata.rs @@ -285,6 +285,7 @@ pub(crate) struct Project { #[serde(rename_all = "kebab-case")] pub struct Metadata10 { pub name: PackageName, + pub version: String, } impl Metadata10 { @@ -296,7 +297,10 @@ impl Metadata10 { .get_first_value("Name") .ok_or(MetadataError::FieldNotFound("Name"))?, )?; - Ok(Self { name }) + let version = headers + .get_first_value("Version") + .ok_or(MetadataError::FieldNotFound("Version"))?; + Ok(Self { name, version }) } } diff --git a/crates/uv/tests/pip_freeze.rs b/crates/uv/tests/pip_freeze.rs index d4640fed3bb..fa4cfd86a7a 100644 --- a/crates/uv/tests/pip_freeze.rs +++ b/crates/uv/tests/pip_freeze.rs @@ -279,7 +279,7 @@ fn freeze_with_legacy_editable() -> Result<()> { .child("zstandard.egg-info") .child("PKG-INFO") .write_str( - "Metadata-Version: 2.2 + "Metadata-Version: 2.1 Name: zstandard Version: 0.22.0 ", diff --git a/crates/uv/tests/pip_list.rs b/crates/uv/tests/pip_list.rs index 88e5e86054c..c1f82d56ef9 100644 --- a/crates/uv/tests/pip_list.rs +++ b/crates/uv/tests/pip_list.rs @@ -583,7 +583,7 @@ fn list_legacy_editable() -> Result<()> { .child("zstandard.egg-info") .child("PKG-INFO") .write_str( - "Metadata-Version: 2.2 + "Metadata-Version: 2.1 Name: zstandard Version: 0.22.0 ", @@ -626,3 +626,52 @@ Version: 0.22.0 Ok(()) } + +#[test] +fn list_legacy_editable_invalid_version() -> Result<()> { + let context = TestContext::new("3.12"); + + let site_packages = ChildPath::new(context.site_packages()); + + let target = context.temp_dir.child("paramiko_project"); + target.child("paramiko.egg-info").create_dir_all()?; + target + .child("paramiko.egg-info") + .child("PKG-INFO") + .write_str( + "Metadata-Version: 1.0 +Name: paramiko +Version: 0.1-bulbasaur +", + )?; + site_packages + .child("paramiko.egg-link") + .write_str(target.path().to_str().unwrap())?; + + let filters = context + .filters() + .into_iter() + .chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")]) + .collect::>(); + + uv_snapshot!(filters, Command::new(get_bin()) + .arg("pip") + .arg("list") + .arg("--editable") + .arg("--cache-dir") + .arg(context.cache_dir.path()) + .env("VIRTUAL_ENV", context.venv.as_os_str()) + .env("UV_NO_WRAP", "1") + .current_dir(&context.temp_dir), @r###" +success: false +exit_code: 2 +----- stdout ----- + +----- stderr ----- +error: Failed to read metadata: from [SITE_PACKAGES]/paramiko.egg-link + Caused by: after parsing '0.1b0', found 'ulbasaur', which is not part of a valid version + "### + ); + + Ok(()) +} diff --git a/crates/uv/tests/pip_uninstall.rs b/crates/uv/tests/pip_uninstall.rs index d3ceca9fe42..87013c99576 100644 --- a/crates/uv/tests/pip_uninstall.rs +++ b/crates/uv/tests/pip_uninstall.rs @@ -490,7 +490,7 @@ fn uninstall_legacy_editable() -> Result<()> { .child("zstandard.egg-info") .child("PKG-INFO") .write_str( - "Metadata-Version: 2.2 + "Metadata-Version: 2.1 Name: zstandard Version: 0.22.0 ",