Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display a more helpful error message for invalid metadata #861

Merged
merged 4 commits into from
Jan 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/861.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Show more helpful error message for invalid metadata.
39 changes: 31 additions & 8 deletions tests/test_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,23 +337,46 @@ def test_fips_metadata_excludes_md5_and_blake2(monkeypatch):
assert "blake2_256_digest" not in mddict


def test_pkginfo_returns_no_metadata(monkeypatch):
@pytest.mark.parametrize(
"read_data, missing_fields",
[
pytest.param(
b"Metadata-Version: 2.3\nName: test-package\nVersion: 1.0.0\n",
"Name, Version",
id="unsupported Metadata-Version",
),
pytest.param(
b"Metadata-Version: 2.2\nName: UNKNOWN\nVersion: UNKNOWN\n",
"Name, Version",
id="missing Name and Version",
),
pytest.param(
b"Metadata-Version: 2.2\nName: UNKNOWN\nVersion: 1.0.0\n",
"Name",
id="missing Name",
),
pytest.param(
b"Metadata-Version: 2.2\nName: test-package\nVersion: UNKNOWN\n",
"Version",
id="missing Version",
),
],
)
def test_pkginfo_returns_no_metadata(read_data, missing_fields, monkeypatch):
"""Raise an exception when pkginfo can't interpret the metadata.

This could be caused by a version number or format it doesn't support yet.
"""

def EmptyDist(filename):
return pretend.stub(name=None, version=None)

monkeypatch.setattr(package_file, "DIST_TYPES", {"bdist_wheel": EmptyDist})
monkeypatch.setattr(package_file.wheel.Wheel, "read", lambda _: read_data)
filename = "tests/fixtures/twine-1.5.0-py2.py3-none-any.whl"

with pytest.raises(exceptions.InvalidDistribution) as err:
package_file.PackageFile.from_filename(filename, comment=None)

assert "Invalid distribution metadata" in err.value.args[0]
assert "1.0, 1.1, 1.2, 2.0, 2.1, and 2.2" in err.value.args[0]
assert (
f"Metadata is missing required fields: {missing_fields}." in err.value.args[0]
)
assert "1.0, 1.1, 1.2, 2.0, 2.1, 2.2" in err.value.args[0]


def test_malformed_from_file(monkeypatch):
Expand Down
20 changes: 13 additions & 7 deletions twine/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,21 @@ def from_filename(cls, filename: str, comment: Optional[str]) -> "PackageFile":
"Unknown distribution format: '%s'" % os.path.basename(filename)
)

# If pkginfo encounters a metadata version it doesn't support, it may
# give us back empty metadata. At the very least, we should have a name
# and version
if not (meta.name and meta.version):
# If pkginfo encounters a metadata version it doesn't support, it may give us
# back empty metadata. At the very least, we should have a name and version,
# which could also be empty if, for example, a MANIFEST.in doesn't include
# setup.cfg.
missing_fields = [
f.capitalize() for f in ["name", "version"] if not getattr(meta, f)
]
if missing_fields:
supported_metadata = list(pkginfo.distribution.HEADER_ATTRS)
raise exceptions.InvalidDistribution(
"Invalid distribution metadata. "
"This version of twine supports Metadata-Version "
f"{', '.join(supported_metadata[:-1])}, and {supported_metadata[-1]}"
"Metadata is missing required fields: "
f"{', '.join(missing_fields)}.\n"
"Make sure the distribution includes the files where those fields "
"are specified, and is using a supported Metadata-Version: "
f"{', '.join(supported_metadata)}."
)

py_version: Optional[str]
Expand Down