From 9d0256b3bba40b574102020fdb8558cfdb2eb9cd Mon Sep 17 00:00:00 2001 From: Daniele Nicolodi Date: Wed, 27 Nov 2024 11:53:38 +0100 Subject: [PATCH] Accommodate for invalid metadata produced by setuptools See pypa/setuptools#4759. --- tests/test_package.py | 31 +++++++++++++++++++++++++++++++ twine/package.py | 11 +++++++++++ 2 files changed, 42 insertions(+) diff --git a/tests/test_package.py b/tests/test_package.py index 3e5e5310..5be92df5 100644 --- a/tests/test_package.py +++ b/tests/test_package.py @@ -424,3 +424,34 @@ def test_package_from_unrecognized_file_error(): with pytest.raises(exceptions.InvalidDistribution) as err: package_file.PackageFile.from_filename(filename, comment=None) assert "Unknown distribution format" in err.value.args[0] + + +@pytest.mark.parametrize( + "read_data, filtered", + [ + pytest.param( + "Metadata-Version: 2.1\n" + "Name: test-package\n" + "Version: 1.0.0\n" + "License-File: LICENSE\n", + True, + id="invalid License-File", + ), + pytest.param( + "Metadata-Version: 2.4\n" + "Name: test-package\n" + "Version: 1.0.0\n" + "License-File: LICENSE\n", + False, + id="valid License-File", + ), + ], +) +def test_setuptools_license_file(read_data, filtered, monkeypatch): + """Drop License-File metadata entries if Metadata-Version is less than 2.4.""" + monkeypatch.setattr(package_file.wheel.Wheel, "read", lambda _: read_data) + filename = "tests/fixtures/twine-1.5.0-py2.py3-none-any.whl" + + package = package_file.PackageFile.from_filename(filename, comment=None) + meta = package.metadata_dictionary() + assert filtered != ("license_file" in meta) diff --git a/twine/package.py b/twine/package.py index 7be0d56e..5abe22e5 100644 --- a/twine/package.py +++ b/twine/package.py @@ -21,6 +21,7 @@ from typing import Any, Dict, List, NamedTuple, Optional, Self, Tuple, TypedDict, Union from packaging import metadata +from packaging import version from rich import print from twine import exceptions @@ -231,6 +232,16 @@ def from_filename(cls, filename: str, comment: Optional[str]) -> "PackageFile": ) ) ) + # setuptools emits License-File metadata fields while declaring + # Metadata-Version 2.1. This is invalid because the metadata + # specification does not allow to add arbitrary fields, and because + # the semantic implemented by setuptools is different than the one + # described in PEP 639. However, rejecting these packages would be + # too disruptive. Drop License-File metadata entries from the data + # sent to the package index if the declared metadata version is less + # than 2.4. + if version.Version(meta.get("metadata_version", "0")) < version.Version("2.4"): + meta.pop("license_files", None) try: metadata.Metadata.from_raw(meta) except metadata.ExceptionGroup as group: