diff --git a/crates/uv-resolver/src/lock/mod.rs b/crates/uv-resolver/src/lock/mod.rs index fa0db8a16..04a29f98b 100644 --- a/crates/uv-resolver/src/lock/mod.rs +++ b/crates/uv-resolver/src/lock/mod.rs @@ -2905,11 +2905,16 @@ enum SourceDist { #[serde(flatten)] metadata: SourceDistMetadata, }, + Metadata { + #[serde(flatten)] + metadata: SourceDistMetadata, + }, } impl SourceDist { fn filename(&self) -> Option> { match self { + SourceDist::Metadata { .. } => None, SourceDist::Url { url, .. } => url.filename().ok(), SourceDist::Path { path, .. } => { path.file_name().map(|filename| filename.to_string_lossy()) @@ -2919,6 +2924,7 @@ impl SourceDist { fn url(&self) -> Option<&UrlString> { match &self { + SourceDist::Metadata { .. } => None, SourceDist::Url { url, .. } => Some(url), SourceDist::Path { .. } => None, } @@ -2926,6 +2932,7 @@ impl SourceDist { fn path(&self) -> Option<&Path> { match &self { + SourceDist::Metadata { .. } => None, SourceDist::Url { .. } => None, SourceDist::Path { path, .. } => Some(path), } @@ -2933,6 +2940,7 @@ impl SourceDist { fn hash(&self) -> Option<&Hash> { match &self { + SourceDist::Metadata { metadata } => metadata.hash.as_ref(), SourceDist::Url { metadata, .. } => metadata.hash.as_ref(), SourceDist::Path { metadata, .. } => metadata.hash.as_ref(), } @@ -2940,6 +2948,7 @@ impl SourceDist { fn size(&self) -> Option { match &self { + SourceDist::Metadata { metadata } => metadata.size, SourceDist::Url { metadata, .. } => metadata.size, SourceDist::Path { metadata, .. } => metadata.size, } @@ -2990,14 +2999,16 @@ impl SourceDist { uv_distribution_types::SourceDist::Registry(ref reg_dist) => { SourceDist::from_registry_dist(reg_dist, index) } - uv_distribution_types::SourceDist::DirectUrl(ref direct_dist) => { - SourceDist::from_direct_dist(id, direct_dist, hashes).map(Some) + uv_distribution_types::SourceDist::DirectUrl(_) => { + SourceDist::from_direct_dist(id, hashes).map(Some) + } + uv_distribution_types::SourceDist::Path(_) => { + SourceDist::from_path_dist(id, hashes).map(Some) } // An actual sdist entry in the lockfile is only required when // it's from a registry or a direct URL. Otherwise, it's strictly // redundant with the information in all other kinds of `source`. uv_distribution_types::SourceDist::Git(_) - | uv_distribution_types::SourceDist::Path(_) | uv_distribution_types::SourceDist::Directory(_) => Ok(None), } } @@ -3046,11 +3057,7 @@ impl SourceDist { } } - fn from_direct_dist( - id: &PackageId, - direct_dist: &DirectUrlSourceDist, - hashes: &[HashDigest], - ) -> Result { + fn from_direct_dist(id: &PackageId, hashes: &[HashDigest]) -> Result { let Some(hash) = hashes.iter().max().cloned().map(Hash::from) else { let kind = LockErrorKind::Hash { id: id.clone(), @@ -3059,8 +3066,24 @@ impl SourceDist { }; return Err(kind.into()); }; - Ok(SourceDist::Url { - url: normalize_url(direct_dist.url.to_url()), + Ok(SourceDist::Metadata { + metadata: SourceDistMetadata { + hash: Some(hash), + size: None, + }, + }) + } + + fn from_path_dist(id: &PackageId, hashes: &[HashDigest]) -> Result { + let Some(hash) = hashes.iter().max().cloned().map(Hash::from) else { + let kind = LockErrorKind::Hash { + id: id.clone(), + artifact_type: "path source distribution", + expected: true, + }; + return Err(kind.into()); + }; + Ok(SourceDist::Metadata { metadata: SourceDistMetadata { hash: Some(hash), size: None, @@ -3082,6 +3105,10 @@ enum SourceDistWire { #[serde(flatten)] metadata: SourceDistMetadata, }, + Metadata { + #[serde(flatten)] + metadata: SourceDistMetadata, + }, } impl SourceDist { @@ -3089,6 +3116,7 @@ impl SourceDist { fn to_toml(&self) -> anyhow::Result { let mut table = InlineTable::new(); match &self { + SourceDist::Metadata { .. } => {} SourceDist::Url { url, .. } => { table.insert("url", Value::from(url.as_ref())); } @@ -3116,6 +3144,7 @@ impl TryFrom for SourceDist { path: path.into(), metadata, }), + SourceDistWire::Metadata { metadata } => Ok(SourceDist::Metadata { metadata }), } } } diff --git a/crates/uv/tests/it/lock.rs b/crates/uv/tests/it/lock.rs index 5d0983b11..f8cf0bbc5 100644 --- a/crates/uv/tests/it/lock.rs +++ b/crates/uv/tests/it/lock.rs @@ -1138,7 +1138,7 @@ fn lock_sdist_url() -> Result<()> { { name = "idna" }, { name = "sniffio" }, ] - sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" } + sdist = { hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" } [package.metadata] requires-dist = [ @@ -1307,7 +1307,7 @@ fn lock_sdist_url_subdirectory() -> Result<()> { dependencies = [ { name = "anyio" }, ] - sdist = { url = "https://github.com/user-attachments/files/18216295/subdirectory-test.tar.gz", hash = "sha256:24b55efee28d08ad3cdc58903e359e820601baa6a4a4b3424311541ebcfb09d3" } + sdist = { hash = "sha256:24b55efee28d08ad3cdc58903e359e820601baa6a4a4b3424311541ebcfb09d3" } [package.metadata] requires-dist = [{ name = "anyio" }] @@ -9556,7 +9556,7 @@ fn lock_sources_url() -> Result<()> { dependencies = [ { name = "anyio" }, ] - sdist = { url = "https://github.com/user-attachments/files/16592193/workspace.zip", hash = "sha256:ba690a925dc3d1b53e0675201c9ec26ab59eeec72ab271562f53297bf1817263" } + sdist = { hash = "sha256:ba690a925dc3d1b53e0675201c9ec26ab59eeec72ab271562f53297bf1817263" } [package.metadata] requires-dist = [{ name = "anyio" }] @@ -9636,11 +9636,11 @@ fn lock_sources_archive() -> Result<()> { let lock = context.read("uv.lock"); - // insta::with_settings!({ - // filters => context.filters(), - // }, { - assert_snapshot!( - lock, @r###" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" version = 1 requires-python = ">=3.12" @@ -9696,12 +9696,13 @@ fn lock_sources_archive() -> Result<()> { dependencies = [ { name = "anyio" }, ] + sdist = { hash = "sha256:ba690a925dc3d1b53e0675201c9ec26ab59eeec72ab271562f53297bf1817263" } [package.metadata] requires-dist = [{ name = "anyio" }] "### - ); - // }); + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" @@ -17496,7 +17497,7 @@ fn lock_multiple_sources() -> Result<()> { resolution-markers = [ "sys_platform == 'win32'", ] - sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3" } + sdist = { hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3" } [[package]] name = "iniconfig"