Deprecate some non-PEP 625 source distributions (#17467)

This commit is contained in:
William Woodruff
2026-03-17 08:18:09 +09:00
committed by GitHub
parent de2071881e
commit 4d4b968f25
7 changed files with 58 additions and 2 deletions
Generated
+1
View File
@@ -6323,6 +6323,7 @@ dependencies = [
"uv-pypi-types",
"uv-redacted",
"uv-types",
"uv-warnings",
"uv-workspace",
"walkdir",
"zip",
@@ -82,13 +82,16 @@ impl SourceDistExtension {
};
match extension {
"gz" if is_tar(path.as_ref()) => Ok(Self::TarGz),
// TODO: Remove these other extensions in the future.
// NOTE: These get parsed from network sources like PyPI, so we don't
// necessarily want to hard-fail, just skip in the future.
"zip" => Ok(Self::Zip),
"tar" => Ok(Self::Tar),
"tgz" => Ok(Self::Tgz),
"tbz" => Ok(Self::Tbz),
"txz" => Ok(Self::Txz),
"tlz" => Ok(Self::Tlz),
"gz" if is_tar(path.as_ref()) => Ok(Self::TarGz),
"bz2" if is_tar(path.as_ref()) => Ok(Self::TarBz2),
"xz" if is_tar(path.as_ref()) => Ok(Self::TarXz),
"lz" if is_tar(path.as_ref()) => Ok(Self::TarLz),
+10
View File
@@ -632,6 +632,16 @@ impl BuiltDist {
}
impl SourceDist {
/// Returns the [`SourceDistExtension`] of the distribution, if it has one.
pub fn extension(&self) -> Option<SourceDistExtension> {
match self {
Self::Registry(source_dist) => Some(source_dist.ext),
Self::DirectUrl(source_dist) => Some(source_dist.ext),
Self::Path(source_dist) => Some(source_dist.ext),
Self::Git(_) | Self::Directory(_) => None,
}
}
/// Returns the [`IndexUrl`], if the distribution is from a registry.
pub fn index(&self) -> Option<&IndexUrl> {
match self {
+1
View File
@@ -36,6 +36,7 @@ uv-platform-tags = { workspace = true }
uv-pypi-types = { workspace = true }
uv-redacted = { workspace = true }
uv-types = { workspace = true }
uv-warnings = { workspace = true }
uv-workspace = { workspace = true }
anyhow = { workspace = true }
@@ -18,7 +18,7 @@ use uv_cache_info::{CacheInfo, Timestamp};
use uv_client::{
CacheControl, CachedClientError, Connectivity, DataWithCachePolicy, RegistryClient,
};
use uv_distribution_filename::WheelFilename;
use uv_distribution_filename::{SourceDistExtension, WheelFilename};
use uv_distribution_types::{
BuildInfo, BuildableSource, BuiltDist, Dist, File, HashPolicy, Hashed, IndexUrl, InstalledDist,
Name, SourceDist, ToUrlError,
@@ -29,6 +29,7 @@ use uv_platform_tags::Tags;
use uv_pypi_types::{HashDigest, HashDigests, PyProjectToml};
use uv_redacted::DisplaySafeUrl;
use uv_types::{BuildContext, BuildStack};
use uv_warnings::warn_user_once;
use crate::archive::Archive;
use crate::metadata::{ArchiveMetadata, Metadata};
@@ -380,6 +381,34 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
tags: &Tags,
hashes: HashPolicy<'_>,
) -> Result<LocalWheel, Error> {
// Warn if the source distribution isn't PEP 625 compliant.
// We do this here instead of in `SourceDistExtension::from_path` to minimize log volume:
// a non-compliant distribution isn't a huge problem if it's not actually being
// materialized into a wheel. Observe that we also allow no extension, since we expect that
// for directory and Git installs.
// NOTE: Observe that we also allow `.zip` sdists here, which are not PEP 625 compliant.
// This is because they were allowed on PyPI until relatively recently (2020).
if let Some(extension) = dist.extension()
&& !matches!(
extension,
SourceDistExtension::TarGz | SourceDistExtension::Zip
)
{
if matches!(dist, SourceDist::Registry(_)) {
// Observe that we display a slightly different warning when the sdist comes
// from a registry, since that suggests that the user has inadvertently
// (rather than explicitly) depended on a non-compliant sdist.
warn_user_once!(
"{dist} uses a legacy source distribution format ('.{extension}') that is not compliant with PEP 625. A future version of uv will reject this source distribution. Consider upgrading to a newer version of {package}",
package = dist.name(),
);
} else {
warn_user_once!(
"{dist} is not a standards-compliant source distribution: expected '.tar.gz' but found '.{extension}'. A future version of uv will reject source distributions that do not meet the requirements specified in PEP 625",
);
}
}
let built_wheel = self
.builder
.download_and_build(&BuildableSource::Dist(dist), tags, hashes, &self.client)
+1
View File
@@ -881,6 +881,7 @@ fn install_sdist_archive_type_bz2() -> Result<()> {
----- stderr -----
Resolved 1 package in [TIME]
warning: bz2 @ file://[WORKSPACE]/test/links/bz2-1.0.0.tar.bz2 is not a standards-compliant source distribution: expected '.tar.gz' but found '.tar.bz2'. A future version of uv will reject source distributions that do not meet the requirements specified in PEP 625
Prepared 1 package in [TIME]
Installed 1 package in [TIME]
+ bz2==1.0.0 (from file://[WORKSPACE]/test/links/bz2-1.0.0.tar.bz2)
+11
View File
@@ -781,6 +781,17 @@ reading and extracting archives in the following formats:
- lzma tarball (`.tar.lzma`)
- zip (`.zip`)
!!! important
Using source distribution extensions other than `.tar.gz` is strongly
discouraged, as these extensions are not widely or consistently
supported across the Python packaging ecosystem.
!!! warning "Deprecated"
Support for source distribution extensions other than `.tar.gz` is
deprecated and will be removed in a future release of uv.
## Lockfile versioning
The `uv.lock` file uses a versioned schema. The schema version is included in the `version` field of