Skip to content

Commit

Permalink
Publish: Warn about unnormalized filenames.
Browse files Browse the repository at this point in the history
The spec requires normalizing the name and the version in distribution filenames (https://packaging.python.org/en/latest/specifications/binary-distribution-format/#escaping-and-unicode). Missing normalization caused #8030, this PR adds a warning for it.
  • Loading branch information
konstin committed Oct 15, 2024
1 parent 494a1d7 commit 14dcee9
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
6 changes: 6 additions & 0 deletions crates/uv-publish/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ pub fn files_for_publishing(
}
let dist_filename = DistFilename::try_from_normalized_filename(&filename)
.ok_or_else(|| PublishError::InvalidFilename(dist.clone()))?;
if dist_filename.to_string() != filename {
warn_user!(
"Invalid filename: Expected `{dist_filename}`, found `{filename}`. \
This is a problem with the build backend."
);
}
files.push((dist, filename, dist_filename));
}
}
Expand Down
40 changes: 40 additions & 0 deletions crates/uv/tests/it/publish.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::common::{uv_snapshot, TestContext};
use assert_fs::fixture::{FileTouch, PathChild};

#[test]
fn username_password_no_longer_supported() {
Expand Down Expand Up @@ -51,3 +52,42 @@ fn invalid_token() {
"###
);
}

/// Check that we warn about unnormalized filenames.
#[test]
fn invalid_validation_error() {
let context = TestContext::new("3.12");

let dist = context.temp_dir.child("dist");
// Unescaped dot
dist.child("aviary.gsm8k-0.7.6-py3-none-any.whl")
.touch()
.unwrap();
// Unescaped dot
dist.child("aviary.gsm8k-0.7.6.tar.gz").touch().unwrap();
// Complex but valid
dist.child("maturin-1.7.4-py3.py2-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl").touch().unwrap();

uv_snapshot!(context.filters(), context.publish()
.arg("--token")
.arg("dummy")
.arg("--publish-url")
.arg("https://test.pypi.org/legacy/")
.current_dir(&context.temp_dir), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
warning: `uv publish` is experimental and may change without warning
warning: Invalid filename: Expected `aviary_gsm8k-0.7.6-py3-none-any.whl`, found `aviary.gsm8k-0.7.6-py3-none-any.whl`. This is a problem with the build backend.
warning: Invalid filename: Expected `aviary_gsm8k-0.7.6.tar.gz`, found `aviary.gsm8k-0.7.6.tar.gz`. This is a problem with the build backend.
Publishing 3 files https://test.pypi.org/legacy/
Uploading aviary_gsm8k-0.7.6-py3-none-any.whl ([SIZE])
error: Failed to publish: `dist/aviary.gsm8k-0.7.6-py3-none-any.whl`
Caused by: Failed to read metadata
Caused by: Failed to read from zip file
Caused by: unable to locate the end of central directory record
"###
);
}

0 comments on commit 14dcee9

Please sign in to comment.