diff --git a/CHANGELOG.md b/CHANGELOG.md index f248217..c7aef2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.14] + +### Fixed + +- The `Distribution` API now handles ZIP source distributions + (those ending with `.zip`) instead of rejecting them as invalid + ([#68](https://github.com/trailofbits/pypi-attestations/pull/68)) + ## [0.0.13] ### Changed @@ -155,7 +163,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial implementation -[Unreleased]: https://github.com/trailofbits/pypi-attestation-models/compare/v0.0.13...HEAD +[Unreleased]: https://github.com/trailofbits/pypi-attestation-models/compare/v0.0.14...HEAD +[0.0.14]: https://github.com/trailofbits/pypi-attestation-models/compare/v0.0.13...v0.0.14 [0.0.13]: https://github.com/trailofbits/pypi-attestation-models/compare/v0.0.12...v0.0.13 [0.0.12]: https://github.com/trailofbits/pypi-attestation-models/compare/v0.0.11...v0.0.12 [0.0.11]: https://github.com/trailofbits/pypi-attestation-models/compare/v0.0.10...v0.0.11 diff --git a/src/pypi_attestations/_impl.py b/src/pypi_attestations/_impl.py index ad93a46..0f6355c 100644 --- a/src/pypi_attestations/_impl.py +++ b/src/pypi_attestations/_impl.py @@ -374,12 +374,15 @@ def _ultranormalize_dist_filename(dist: str) -> str: parts = "-".join([name, str(ver), impl_tag, abi_tag, platform_tag]) return f"{parts}.whl" - - elif dist.endswith(".tar.gz"): + elif dist.endswith((".tar.gz", ".zip")): # `parse_sdist_filename` raises a supertype of ValueError on failure. name, ver = parse_sdist_filename(dist) name = name.replace("-", "_") - return f"{name}-{ver}.tar.gz" + + if dist.endswith(".tar.gz"): + return f"{name}-{ver}.tar.gz" + else: + return f"{name}-{ver}.zip" else: raise ValueError(f"unknown distribution format: {dist}") diff --git a/test/test_impl.py b/test/test_impl.py index 109d5bc..745f244 100644 --- a/test/test_impl.py +++ b/test/test_impl.py @@ -457,10 +457,14 @@ def test_exception_types(self) -> None: ("foo-1.0-py3-none.none.none-any.whl", "foo-1.0-py3-none-any.whl"), # sdist: fully normalized, no changes ("foo-1.0.tar.gz", "foo-1.0.tar.gz"), + ("foo-1.0.zip", "foo-1.0.zip"), # sdist: dist name is not case normalized ("Foo-1.0.tar.gz", "foo-1.0.tar.gz"), ("FOO-1.0.tar.gz", "foo-1.0.tar.gz"), ("FoO-1.0.tar.gz", "foo-1.0.tar.gz"), + ("Foo-1.0.zip", "foo-1.0.zip"), + ("FOO-1.0.zip", "foo-1.0.zip"), + ("FoO-1.0.zip", "foo-1.0.zip"), # sdist: dist name contains alternate separators, including # `-` despite being forbidden by PEP 625 ("foo-bar-1.0.tar.gz", "foo_bar-1.0.tar.gz"), @@ -469,9 +473,17 @@ def test_exception_types(self) -> None: ("foo.bar-1.0.tar.gz", "foo_bar-1.0.tar.gz"), ("foo..bar-1.0.tar.gz", "foo_bar-1.0.tar.gz"), ("foo.bar.baz-1.0.tar.gz", "foo_bar_baz-1.0.tar.gz"), + ("foo-bar-1.0.zip", "foo_bar-1.0.zip"), + ("foo-bar-baz-1.0.zip", "foo_bar_baz-1.0.zip"), + ("foo--bar-1.0.zip", "foo_bar-1.0.zip"), + ("foo.bar-1.0.zip", "foo_bar-1.0.zip"), + ("foo..bar-1.0.zip", "foo_bar-1.0.zip"), + ("foo.bar.baz-1.0.zip", "foo_bar_baz-1.0.zip"), # sdist: dist version is not normalized ("foo-1.0beta1.tar.gz", "foo-1.0b1.tar.gz"), ("foo-01.0beta1.tar.gz", "foo-1.0b1.tar.gz"), + ("foo-1.0beta1.zip", "foo-1.0b1.zip"), + ("foo-01.0beta1.zip", "foo-1.0b1.zip"), ], ) def test_ultranormalize_dist_filename(input: str, normalized: str) -> None: @@ -489,6 +501,7 @@ def test_ultranormalize_dist_filename(input: str, normalized: str) -> None: "foo", # suffixes must be lowercase "foo-1.0.TAR.GZ", + "foo-1.0.ZIP", "foo-1.0-py3-none-any.WHL", # wheel: invalid separator in dist name "foo-bar-1.0-py3-none-any.whl", @@ -499,6 +512,13 @@ def test_ultranormalize_dist_filename(input: str, normalized: str) -> None: # sdist: invalid version "foo-charmander.tar.gz", "foo-1charmander.tar.gz", + "foo-charmander.zip", + "foo-1charmander.zip", + # sdist: nonsense suffixes + "foo-1.2.3.junk.zip", + "foo-1.2.3.junk.tar.gz", + "foo-1.2.3.zip.tar.gz", + "foo-1.2.3.tar.gz.zip", ], ) def test_ultranormalize_dist_filename_invalid(input: str) -> None: