Skip to content

Commit

Permalink
Add logic capturing when the declared metadata version is not supported.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaraco committed Jun 25, 2024
1 parent ecaced0 commit e780b0f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@
# TODO: Try to add these to intersphinx_mapping
nitpick_ignore_regex = [
(r"py:.*", r"pkginfo.*"),
("py:class", r"warnings\.WarningMessage"),
]

# -- Options for apidoc output ------------------------------------------------
Expand Down
38 changes: 32 additions & 6 deletions twine/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,19 @@
import os
import re
import subprocess
from typing import Any, Dict, List, NamedTuple, Optional, Sequence, Tuple, Union, cast
import warnings
from typing import (
Any,
Dict,
Iterable,
List,
NamedTuple,
Optional,
Sequence,
Tuple,
Union,
cast,
)

import importlib_metadata
import pkginfo
Expand Down Expand Up @@ -95,7 +107,8 @@ def from_filename(cls, filename: str, comment: Optional[str]) -> "PackageFile":
for ext, dtype in DIST_EXTENSIONS.items():
if filename.endswith(ext):
try:
meta = DIST_TYPES[dtype](filename)
with warnings.catch_warnings(record=True) as captured:
meta = DIST_TYPES[dtype](filename)
except EOFError:
raise exceptions.InvalidDistribution(
"Invalid distribution file: '%s'" % os.path.basename(filename)
Expand All @@ -107,19 +120,25 @@ 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
supported_metadata = list(pkginfo.distribution.HEADER_ATTRS)
if cls._is_unknown_metadata_version(captured):
raise exceptions.InvalidDistribution(
"Make sure the distribution is using a supported Metadata-Version: "
f"{', '.join(supported_metadata)}."
)
# If pkginfo <1.11 encounters a metadata version it doesn't support, it may give
# 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(
"Metadata is missing required fields: "
f"{', '.join(missing_fields)}.\n"
"Make sure the distribution includes the files where those fields "
f"{', '.join(missing_fields)}."
# TODO: Remove this section after requiring pkginfo>=1.11
"\nMake sure the distribution includes the files where those fields "
"are specified, and is using a supported Metadata-Version: "
f"{', '.join(supported_metadata)}."
)
Expand All @@ -137,6 +156,13 @@ def from_filename(cls, filename: str, comment: Optional[str]) -> "PackageFile":

return cls(filename, comment, meta, py_version, dtype)

@staticmethod
def _is_unknown_metadata_version(
captured: Iterable[warnings.WarningMessage],
) -> bool:
NMV = getattr(pkginfo.distribution, "NewMetadataVersion", None)
return any(warning.category is NMV for warning in captured)

def metadata_dictionary(self) -> Dict[str, MetadataValue]:
"""Merge multiple sources of metadata into a single dictionary.
Expand Down

0 comments on commit e780b0f

Please sign in to comment.